正在显示
5 个修改的文件
包含
207 行增加
和
51 行删除
| @@ -11,4 +11,5 @@ require ( | @@ -11,4 +11,5 @@ require ( | ||
| 11 | github.com/go-redis/redis v6.14.2+incompatible | 11 | github.com/go-redis/redis v6.14.2+incompatible |
| 12 | github.com/google/uuid v1.1.1 | 12 | github.com/google/uuid v1.1.1 |
| 13 | github.com/linmadan/egglib-go v0.0.0-20210827085852-177fa745932d | 13 | github.com/linmadan/egglib-go v0.0.0-20210827085852-177fa745932d |
| 14 | + github.com/stretchr/testify v1.7.0 | ||
| 14 | ) | 15 | ) |
| @@ -5,26 +5,26 @@ import ( | @@ -5,26 +5,26 @@ import ( | ||
| 5 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/util/advance" | 5 | "gitlab.fjmaimaimai.com/allied-creation/allied-creation-gateway/pkg/util/advance" |
| 6 | ) | 6 | ) |
| 7 | 7 | ||
| 8 | -type Model struct { | ||
| 9 | - Columns []advance.Column `json:"columns"` | ||
| 10 | - MapColumn advance.MapColumn `json:"-"` | ||
| 11 | - Name string `json:"name"` | ||
| 12 | -} | 8 | +type ( |
| 9 | + Model struct { | ||
| 10 | + Columns []advance.Column `json:"columns"` | ||
| 11 | + MapColumn advance.MapColumn `json:"-"` | ||
| 12 | + Name string `json:"name"` | ||
| 13 | + } | ||
| 14 | + ModelInterface interface { | ||
| 15 | + ModelName() string | ||
| 16 | + Columns() []advance.Column | ||
| 17 | + } | ||
| 18 | +) | ||
| 13 | 19 | ||
| 14 | var registerModels = make(map[string]Model) | 20 | var registerModels = make(map[string]Model) |
| 15 | 21 | ||
| 16 | -func RegisModel(m Model) { | ||
| 17 | - if _, ok := registerModels[m.Name]; ok { | ||
| 18 | - panic("register modes exists:" + m.Name) | ||
| 19 | - } | ||
| 20 | - registerModels[m.Name] = m | ||
| 21 | -} | ||
| 22 | - | 22 | +// AdvancedQuerySql 高级查询语句生成 |
| 23 | func AdvancedQuerySql(model string, quires advance.AdvancedQueries) string { | 23 | func AdvancedQuerySql(model string, quires advance.AdvancedQueries) string { |
| 24 | if len(quires) == 0 { | 24 | if len(quires) == 0 { |
| 25 | return "" | 25 | return "" |
| 26 | } | 26 | } |
| 27 | - fixQueries := fixAdvanceQueries(model, quires) | 27 | + fixQueries := mergeDuplicateQueries(model, quires) |
| 28 | sql, err := advance.AdvancedQuerySql(fixQueries) | 28 | sql, err := advance.AdvancedQuerySql(fixQueries) |
| 29 | if err != nil { | 29 | if err != nil { |
| 30 | log.Logger.Error(err.Error()) | 30 | log.Logger.Error(err.Error()) |
| @@ -32,7 +32,7 @@ func AdvancedQuerySql(model string, quires advance.AdvancedQueries) string { | @@ -32,7 +32,7 @@ func AdvancedQuerySql(model string, quires advance.AdvancedQueries) string { | ||
| 32 | return sql | 32 | return sql |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | -func fixAdvanceQueries(model string, quires advance.AdvancedQueries) []advance.AdvancedQuery { | 35 | +func mergeDuplicateQueries(model string, quires advance.AdvancedQueries) []advance.AdvancedQuery { |
| 36 | m, ok := GetModel(model) | 36 | m, ok := GetModel(model) |
| 37 | response := make([]advance.AdvancedQuery, 0) | 37 | response := make([]advance.AdvancedQuery, 0) |
| 38 | mapResponse := make(map[string]advance.AdvancedQuery) | 38 | mapResponse := make(map[string]advance.AdvancedQuery) |
| @@ -57,11 +57,6 @@ func fixAdvanceQueries(model string, quires advance.AdvancedQueries) []advance.A | @@ -57,11 +57,6 @@ func fixAdvanceQueries(model string, quires advance.AdvancedQueries) []advance.A | ||
| 57 | return response | 57 | return response |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | -func GetModel(name string) (Model, bool) { | ||
| 61 | - m, ok := registerModels[name] | ||
| 62 | - return m, ok | ||
| 63 | -} | ||
| 64 | - | ||
| 65 | func NewModel(m ModelInterface) Model { | 60 | func NewModel(m ModelInterface) Model { |
| 66 | return Model{ | 61 | return Model{ |
| 67 | Name: m.ModelName(), | 62 | Name: m.ModelName(), |
| @@ -70,14 +65,22 @@ func NewModel(m ModelInterface) Model { | @@ -70,14 +65,22 @@ func NewModel(m ModelInterface) Model { | ||
| 70 | } | 65 | } |
| 71 | } | 66 | } |
| 72 | 67 | ||
| 73 | -type ModelInterface interface { | ||
| 74 | - ModelName() string | ||
| 75 | - Columns() []advance.Column | 68 | +func RegisModel(m Model) { |
| 69 | + if _, ok := registerModels[m.Name]; ok { | ||
| 70 | + panic("register modes exists:" + m.Name) | ||
| 71 | + } | ||
| 72 | + registerModels[m.Name] = m | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +func GetModel(name string) (Model, bool) { | ||
| 76 | + m, ok := registerModels[name] | ||
| 77 | + return m, ok | ||
| 76 | } | 78 | } |
| 77 | 79 | ||
| 78 | /*User*/ | 80 | /*User*/ |
| 79 | type UserModel struct{} | 81 | type UserModel struct{} |
| 80 | 82 | ||
| 83 | +// 实现接口 ModelInterface | ||
| 81 | func (u UserModel) ModelName() string { return "user" } | 84 | func (u UserModel) ModelName() string { return "user" } |
| 82 | func (u UserModel) Columns() []advance.Column { | 85 | func (u UserModel) Columns() []advance.Column { |
| 83 | return []advance.Column{ | 86 | return []advance.Column{ |
| @@ -160,7 +160,7 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -160,7 +160,7 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
| 160 | exceptSql string | 160 | exceptSql string |
| 161 | ok bool | 161 | ok bool |
| 162 | }{ | 162 | }{ |
| 163 | - // in | 163 | + // in (equal) |
| 164 | { | 164 | { |
| 165 | col: columnChar, | 165 | col: columnChar, |
| 166 | name: "in zero item", | 166 | name: "in zero item", |
| @@ -212,6 +212,19 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -212,6 +212,19 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
| 212 | ok: true, | 212 | ok: true, |
| 213 | }, | 213 | }, |
| 214 | 214 | ||
| 215 | + // not in (not equal) | ||
| 216 | + { | ||
| 217 | + col: columnNumber, | ||
| 218 | + name: "not equal many item (number)", | ||
| 219 | + ins: []Expr{ | ||
| 220 | + {OpChar: NotEqual, Value: []interface{}{1, 2, 3, 4}}, | ||
| 221 | + {OpChar: NotEqual, Value: []interface{}{5, 6}}, | ||
| 222 | + }, | ||
| 223 | + except: nil, | ||
| 224 | + exceptSql: "(age not in (1,2,3,4,5,6))", | ||
| 225 | + ok: true, | ||
| 226 | + }, | ||
| 227 | + | ||
| 215 | // range | 228 | // range |
| 216 | { | 229 | { |
| 217 | col: columnChar, | 230 | col: columnChar, |
| @@ -241,7 +254,7 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -241,7 +254,7 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
| 241 | {OpChar: LessThanEqual, Value: []interface{}{Infinity, 80}}, | 254 | {OpChar: LessThanEqual, Value: []interface{}{Infinity, 80}}, |
| 242 | }, | 255 | }, |
| 243 | except: nil, | 256 | except: nil, |
| 244 | - exceptSql: "(( age <= 80 ))", | 257 | + exceptSql: "(( age <= 60 ))", |
| 245 | ok: true, | 258 | ok: true, |
| 246 | }, | 259 | }, |
| 247 | { | 260 | { |
| @@ -254,7 +267,19 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -254,7 +267,19 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
| 254 | {OpChar: LessThanEqual, Value: []interface{}{Infinity, 70}}, | 267 | {OpChar: LessThanEqual, Value: []interface{}{Infinity, 70}}, |
| 255 | }, | 268 | }, |
| 256 | except: nil, | 269 | except: nil, |
| 257 | - exceptSql: "(( age <= 70 ) or ( age >= 80 ))", | 270 | + exceptSql: "", // 或集 (( age <= 70 ) or ( age >= 80 )) 并集 "" |
| 271 | + ok: true, | ||
| 272 | + }, | ||
| 273 | + { | ||
| 274 | + col: columnNumber, | ||
| 275 | + name: "range many item (Between $<=n<=$)", | ||
| 276 | + ins: []Expr{ | ||
| 277 | + {OpChar: GreaterThanEqual, Value: []interface{}{80, Infinity}}, | ||
| 278 | + {OpChar: LessThanEqual, Value: []interface{}{Infinity, 200}}, | ||
| 279 | + {OpChar: LessThan, Value: []interface{}{Infinity, 150}}, | ||
| 280 | + }, | ||
| 281 | + except: nil, | ||
| 282 | + exceptSql: "(( age >= 80 and age < 150 ))", | ||
| 258 | ok: true, | 283 | ok: true, |
| 259 | }, | 284 | }, |
| 260 | { | 285 | { |
| @@ -275,9 +300,10 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -275,9 +300,10 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
| 275 | {OpChar: Range, Value: []interface{}{120, 220}, LeftOp: GreaterThanEqual, RightOp: LessThan}, | 300 | {OpChar: Range, Value: []interface{}{120, 220}, LeftOp: GreaterThanEqual, RightOp: LessThan}, |
| 276 | {OpChar: Range, Value: []interface{}{100, 200}, LeftOp: GreaterThanEqual, RightOp: LessThanEqual}, | 301 | {OpChar: Range, Value: []interface{}{100, 200}, LeftOp: GreaterThanEqual, RightOp: LessThanEqual}, |
| 277 | {OpChar: Range, Value: []interface{}{80, 100}, LeftOp: GreaterThan, RightOp: LessThanEqual}, | 302 | {OpChar: Range, Value: []interface{}{80, 100}, LeftOp: GreaterThan, RightOp: LessThanEqual}, |
| 303 | + {OpChar: Range, Value: []interface{}{300, 500}, LeftOp: GreaterThan, RightOp: LessThanEqual}, | ||
| 278 | }, | 304 | }, |
| 279 | except: nil, | 305 | except: nil, |
| 280 | - exceptSql: "(( age > 80 and age < 220 ))", | 306 | + exceptSql: "(( age > 80 and age < 220 ) or ( age > 300 and age <= 500 ))", |
| 281 | ok: true, | 307 | ok: true, |
| 282 | }, | 308 | }, |
| 283 | 309 | ||
| @@ -322,6 +348,18 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -322,6 +348,18 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
| 322 | exceptSql: "((age::text like '%10%' or age::text like '%20%'))", | 348 | exceptSql: "((age::text like '%10%' or age::text like '%20%'))", |
| 323 | ok: true, | 349 | ok: true, |
| 324 | }, | 350 | }, |
| 351 | + | ||
| 352 | + // error input | ||
| 353 | + { | ||
| 354 | + col: columnChar, | ||
| 355 | + name: "invalid input", | ||
| 356 | + ins: []Expr{ | ||
| 357 | + {OpChar: Like, Value: []interface{}{"dsger?*"}}, | ||
| 358 | + }, | ||
| 359 | + except: nil, | ||
| 360 | + exceptSql: "", | ||
| 361 | + ok: false, | ||
| 362 | + }, | ||
| 325 | } | 363 | } |
| 326 | 364 | ||
| 327 | for i := range tables { | 365 | for i := range tables { |
| @@ -333,7 +371,6 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | @@ -333,7 +371,6 @@ func TestAdvancedQuerySql_PG(t *testing.T) { | ||
| 333 | } | 371 | } |
| 334 | t.Run(tables[i].name, func(t *testing.T) { | 372 | t.Run(tables[i].name, func(t *testing.T) { |
| 335 | sql, err := AdvancedQuerySql(q) | 373 | sql, err := AdvancedQuerySql(q) |
| 336 | - assert.Equal(t, tables[i].except, err) | ||
| 337 | assert.Equal(t, tables[i].exceptSql, sql) | 374 | assert.Equal(t, tables[i].exceptSql, sql) |
| 338 | if tables[i].ok { | 375 | if tables[i].ok { |
| 339 | assert.Nil(t, err) | 376 | assert.Nil(t, err) |
| @@ -3,6 +3,8 @@ package advance | @@ -3,6 +3,8 @@ package advance | ||
| 3 | import ( | 3 | import ( |
| 4 | "bytes" | 4 | "bytes" |
| 5 | "fmt" | 5 | "fmt" |
| 6 | + "regexp" | ||
| 7 | + "strconv" | ||
| 6 | "strings" | 8 | "strings" |
| 7 | ) | 9 | ) |
| 8 | 10 | ||
| @@ -65,7 +67,7 @@ func ComputeColumnExpr(queries []AdvancedQuery) []ColumnExprResult { | @@ -65,7 +67,7 @@ func ComputeColumnExpr(queries []AdvancedQuery) []ColumnExprResult { | ||
| 65 | } | 67 | } |
| 66 | 68 | ||
| 67 | func JoinColumnExprNumber(expr []Expr) []ExprResult { | 69 | func JoinColumnExprNumber(expr []Expr) []ExprResult { |
| 68 | - var ec = []exprCompute{NewInExprCompute(expr, ValueNumber), NewRangeExprCompute(expr, ValueNumber), NewNotEqualExprCompute(expr, ValueNumber), NewLikeExprCompute(expr, ValueNumber)} | 70 | + var ec = []exprCompute{NewInExprCompute(expr, ValueNumber), NewRangeExprCompute(expr, ValueNumber), NewLessGreaterExprCompute(expr, ValueNumber), NewNotEqualExprCompute(expr, ValueNumber), NewLikeExprCompute(expr, ValueNumber)} |
| 69 | return joinExprResult(ec) | 71 | return joinExprResult(ec) |
| 70 | } | 72 | } |
| 71 | 73 | ||
| @@ -98,12 +100,15 @@ func (m MapColumn) FindItem(col string) Column { | @@ -98,12 +100,15 @@ func (m MapColumn) FindItem(col string) Column { | ||
| 98 | 100 | ||
| 99 | type PgSqlGenerator struct{} | 101 | type PgSqlGenerator struct{} |
| 100 | 102 | ||
| 101 | -func (p PgSqlGenerator) SqlGen(q ColumnExprResult) string { | 103 | +func (p PgSqlGenerator) SqlGen(q ColumnExprResult) (string, error) { |
| 102 | sql := bytes.NewBuffer(nil) | 104 | sql := bytes.NewBuffer(nil) |
| 103 | sql.WriteString("(") | 105 | sql.WriteString("(") |
| 104 | var wheres []string | 106 | var wheres []string |
| 105 | for i := range q.Result { | 107 | for i := range q.Result { |
| 106 | item := q.Result[i] | 108 | item := q.Result[i] |
| 109 | + if err := p.PreCheckAndFormat(&item); err != nil { | ||
| 110 | + return "", err | ||
| 111 | + } | ||
| 107 | var where string | 112 | var where string |
| 108 | switch item.OpChar { | 113 | switch item.OpChar { |
| 109 | case In: | 114 | case In: |
| @@ -124,9 +129,34 @@ func (p PgSqlGenerator) SqlGen(q ColumnExprResult) string { | @@ -124,9 +129,34 @@ func (p PgSqlGenerator) SqlGen(q ColumnExprResult) string { | ||
| 124 | } | 129 | } |
| 125 | sql.WriteString(strings.Join(wheres, sepOr)) | 130 | sql.WriteString(strings.Join(wheres, sepOr)) |
| 126 | sql.WriteString(")") | 131 | sql.WriteString(")") |
| 127 | - return sql.String() | 132 | + return sql.String(), nil |
| 133 | +} | ||
| 134 | +func (p PgSqlGenerator) PreCheckAndFormat(rs *ExprResult) error { | ||
| 135 | + if rs.ValueType == ValueNumber || rs.ValueType == ValueDate { | ||
| 136 | + for i := range rs.Value { | ||
| 137 | + v := rs.Value[i] | ||
| 138 | + if isInfinity(v) { | ||
| 139 | + continue | ||
| 140 | + } | ||
| 141 | + if _, err := strconv.ParseFloat(fmt.Sprintf("%v", v), 64); err != nil { | ||
| 142 | + return fmt.Errorf("不是有效的数值类型:%v", v) | ||
| 143 | + } | ||
| 144 | + } | ||
| 145 | + } | ||
| 146 | + if rs.ValueType == ValueChars { | ||
| 147 | + for i := range rs.Value { | ||
| 148 | + v, ok := rs.Value[i].(string) | ||
| 149 | + err := fmt.Errorf("不是有效的字符串类型:%v", v) | ||
| 150 | + if !ok { | ||
| 151 | + return err | ||
| 152 | + } | ||
| 153 | + if ok, e := regexp.MatchString("[!%&()*+,-/=?^`'{|}~]", v); ok || e != nil { | ||
| 154 | + return fmt.Errorf("非法字符:%v", v) | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + } | ||
| 158 | + return nil | ||
| 128 | } | 159 | } |
| 129 | - | ||
| 130 | func (p PgSqlGenerator) In(c Column, values []interface{}) string { | 160 | func (p PgSqlGenerator) In(c Column, values []interface{}) string { |
| 131 | if len(values) < 1 { | 161 | if len(values) < 1 { |
| 132 | return "" | 162 | return "" |
| @@ -207,11 +237,18 @@ func AdvancedQuerySql(queries []AdvancedQuery) (string, error) { | @@ -207,11 +237,18 @@ func AdvancedQuerySql(queries []AdvancedQuery) (string, error) { | ||
| 207 | sql := bytes.NewBuffer(nil) | 237 | sql := bytes.NewBuffer(nil) |
| 208 | var wheres []string | 238 | var wheres []string |
| 209 | for i := range results { | 239 | for i := range results { |
| 210 | - wheres = append(wheres, gen.SqlGen(results[i])) | 240 | + condition, err := gen.SqlGen(results[i]) |
| 241 | + if err != nil { | ||
| 242 | + return "", err | ||
| 243 | + } | ||
| 244 | + wheres = append(wheres, condition) | ||
| 211 | } | 245 | } |
| 212 | sql.WriteString(strings.Join(wheres, sepAnd)) | 246 | sql.WriteString(strings.Join(wheres, sepAnd)) |
| 213 | // 空条件 () | 247 | // 空条件 () |
| 214 | - if len(sql.String()) == 2 { | 248 | + if sql.String() == "()" { |
| 249 | + return "", nil | ||
| 250 | + } | ||
| 251 | + if sql.String() == "(())" { | ||
| 215 | return "", nil | 252 | return "", nil |
| 216 | } | 253 | } |
| 217 | return sql.String(), nil | 254 | return sql.String(), nil |
| @@ -53,10 +53,10 @@ type ( | @@ -53,10 +53,10 @@ type ( | ||
| 53 | } | 53 | } |
| 54 | Expr struct { | 54 | Expr struct { |
| 55 | // 操作符 | 55 | // 操作符 |
| 56 | - OpChar OpType `json:"oc"` | 56 | + OpChar OpType `json:"op"` |
| 57 | // 如果 OpChar=range ,LeftOp、RightOp需要有值 | 57 | // 如果 OpChar=range ,LeftOp、RightOp需要有值 |
| 58 | - LeftOp OpType `json:"loc"` // "<= <" | ||
| 59 | - RightOp OpType `json:"roc"` // ">= >" | 58 | + LeftOp OpType `json:"lop"` // "<= <" |
| 59 | + RightOp OpType `json:"rop"` // ">= >" | ||
| 60 | // 值 | 60 | // 值 |
| 61 | Value []interface{} `json:"values"` | 61 | Value []interface{} `json:"values"` |
| 62 | } | 62 | } |
| @@ -98,6 +98,10 @@ type ( | @@ -98,6 +98,10 @@ type ( | ||
| 98 | valueType ValueType | 98 | valueType ValueType |
| 99 | OpType OpType | 99 | OpType OpType |
| 100 | } | 100 | } |
| 101 | + LessGreaterExprCompute struct { | ||
| 102 | + expr []Expr | ||
| 103 | + valueType ValueType | ||
| 104 | + } | ||
| 101 | ) | 105 | ) |
| 102 | 106 | ||
| 103 | // in合并 | 107 | // in合并 |
| @@ -151,7 +155,7 @@ func combine(arr []interface{}) []interface{} { | @@ -151,7 +155,7 @@ func combine(arr []interface{}) []interface{} { | ||
| 151 | func NewRangeExprCompute(expr []Expr, valueType ValueType) exprCompute { | 155 | func NewRangeExprCompute(expr []Expr, valueType ValueType) exprCompute { |
| 152 | rec := RangeNumberExprCompute{valueType: valueType} | 156 | rec := RangeNumberExprCompute{valueType: valueType} |
| 153 | for i := range expr { | 157 | for i := range expr { |
| 154 | - if expr[i].OpChar == Range || expr[i].OpChar == LessThanEqual || expr[i].OpChar == GreaterThanEqual || expr[i].OpChar == LessThan || expr[i].OpChar == GreaterThan { | 158 | + if expr[i].OpChar == Range { // || expr[i].OpChar == LessThanEqual || expr[i].OpChar == GreaterThanEqual || expr[i].OpChar == LessThan || expr[i].OpChar == GreaterThan |
| 155 | rec.expr = append(rec.expr, expr[i]) | 159 | rec.expr = append(rec.expr, expr[i]) |
| 156 | } | 160 | } |
| 157 | } | 161 | } |
| @@ -178,14 +182,14 @@ func (ex RangeNumberExprCompute) Append(result []ExprResult) []ExprResult { | @@ -178,14 +182,14 @@ func (ex RangeNumberExprCompute) Append(result []ExprResult) []ExprResult { | ||
| 178 | arr.RightOp = ex.expr[0].RightOp | 182 | arr.RightOp = ex.expr[0].RightOp |
| 179 | } | 183 | } |
| 180 | for i := 1; i < len(ex.expr); i++ { | 184 | for i := 1; i < len(ex.expr); i++ { |
| 181 | - if !arr.NumberCompare(ex.expr[i]) { | 185 | + if !arr.Compare(ex.expr[i]) { |
| 182 | result = append(result, *arr) | 186 | result = append(result, *arr) |
| 183 | arr.Value = ex.expr[i].Value | 187 | arr.Value = ex.expr[i].Value |
| 184 | arr.LeftOp = ex.expr[i].OpChar | 188 | arr.LeftOp = ex.expr[i].OpChar |
| 185 | arr.RightOp = ex.expr[i].OpChar | 189 | arr.RightOp = ex.expr[i].OpChar |
| 186 | - //if len(ex.expr[0].LeftOp) != 0 { | ||
| 187 | - // arr.LeftOp = ex.expr[0].LeftOp | ||
| 188 | - //} | 190 | + if len(ex.expr[0].LeftOp) != 0 { |
| 191 | + arr.LeftOp = ex.expr[0].LeftOp | ||
| 192 | + } | ||
| 189 | if len(ex.expr[0].RightOp) != 0 { | 193 | if len(ex.expr[0].RightOp) != 0 { |
| 190 | arr.RightOp = ex.expr[0].RightOp | 194 | arr.RightOp = ex.expr[0].RightOp |
| 191 | } | 195 | } |
| @@ -196,6 +200,60 @@ func (ex RangeNumberExprCompute) Append(result []ExprResult) []ExprResult { | @@ -196,6 +200,60 @@ func (ex RangeNumberExprCompute) Append(result []ExprResult) []ExprResult { | ||
| 196 | return result | 200 | return result |
| 197 | } | 201 | } |
| 198 | 202 | ||
| 203 | +//范围合并 | ||
| 204 | +func NewLessGreaterExprCompute(expr []Expr, valueType ValueType) exprCompute { | ||
| 205 | + rec := LessGreaterExprCompute{valueType: valueType} | ||
| 206 | + for i := range expr { | ||
| 207 | + if expr[i].OpChar == LessThanEqual || expr[i].OpChar == LessThan || expr[i].OpChar == GreaterThanEqual || expr[i].OpChar == GreaterThan { | ||
| 208 | + rec.expr = append(rec.expr, expr[i]) | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | + if len(rec.expr) == 0 { | ||
| 212 | + return nil | ||
| 213 | + } | ||
| 214 | + var exprSort = exprSortable(rec.expr) | ||
| 215 | + sort.Sort(exprSort) | ||
| 216 | + rec.expr = exprSort | ||
| 217 | + return rec | ||
| 218 | +} | ||
| 219 | +func (ex LessGreaterExprCompute) Append(result []ExprResult) []ExprResult { | ||
| 220 | + arr := &ExprResult{ | ||
| 221 | + OpChar: Range, | ||
| 222 | + ValueType: ex.valueType, | ||
| 223 | + Value: ex.expr[0].Value, | ||
| 224 | + LeftOp: ex.expr[0].OpChar, | ||
| 225 | + RightOp: ex.expr[0].OpChar, | ||
| 226 | + } | ||
| 227 | + x0, x1 := toFloat64(arr.Value[0], arr.Value[1]) | ||
| 228 | + for i := 1; i < len(ex.expr); i++ { | ||
| 229 | + compare := ex.expr[i] | ||
| 230 | + y0, y1 := toFloat64(compare.Value[0], compare.Value[1]) | ||
| 231 | + if compare.OpChar == LessThanEqual || compare.OpChar == LessThan { | ||
| 232 | + if isInfinity(x1) { | ||
| 233 | + arr.Value[1] = y0 | ||
| 234 | + arr.RightOp = compare.OpChar | ||
| 235 | + } else if x1 > y1 { | ||
| 236 | + arr.Value[0] = y0 | ||
| 237 | + arr.LeftOp = compare.OpChar | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | + if compare.OpChar == GreaterThan || compare.OpChar == GreaterThanEqual { | ||
| 241 | + if isInfinity(x0) { | ||
| 242 | + arr.Value[0] = y0 | ||
| 243 | + arr.LeftOp = compare.OpChar | ||
| 244 | + } else if y0 > x0 { | ||
| 245 | + arr.Value[0] = y0 | ||
| 246 | + arr.LeftOp = compare.OpChar | ||
| 247 | + } | ||
| 248 | + } | ||
| 249 | + } | ||
| 250 | + if _, ok := less(arr.Value[0], arr.Value[1]); !ok { | ||
| 251 | + arr.Value[0], arr.Value[1] = Infinity, Infinity | ||
| 252 | + } | ||
| 253 | + result = append(result, *arr) | ||
| 254 | + return result | ||
| 255 | +} | ||
| 256 | + | ||
| 199 | // recent范围 | 257 | // recent范围 |
| 200 | func NewRecentDateExprCompute(expr []Expr, valueType ValueType) exprCompute { | 258 | func NewRecentDateExprCompute(expr []Expr, valueType ValueType) exprCompute { |
| 201 | inExpr := RecentDateExprCompute{valueType: valueType} | 259 | inExpr := RecentDateExprCompute{valueType: valueType} |
| @@ -268,18 +326,24 @@ func (ex NotEqualExprCompute) Append(result []ExprResult) []ExprResult { | @@ -268,18 +326,24 @@ func (ex NotEqualExprCompute) Append(result []ExprResult) []ExprResult { | ||
| 268 | return result | 326 | return result |
| 269 | } | 327 | } |
| 270 | 328 | ||
| 271 | -func (er *ExprResult) NumberCompare(expr Expr) bool { | ||
| 272 | - if len(expr.Value) != 2 { | 329 | +// Compare 比较两个范围的值 |
| 330 | +// eg: [80,&] [&,200] | ||
| 331 | +// 排序 [&,200] | ||
| 332 | +// [80,&] | ||
| 333 | +// false:开启新的范围 | ||
| 334 | +// true:继续这个范围 | ||
| 335 | +func (er *ExprResult) Compare(compare Expr) bool { | ||
| 336 | + if len(compare.Value) != 2 { | ||
| 273 | return false | 337 | return false |
| 274 | } | 338 | } |
| 275 | - _, x2 := toFloat64(er.Value[0], er.Value[1]) | ||
| 276 | - y1, _ := toFloat64(expr.Value[0], expr.Value[1]) | ||
| 277 | - if y1 <= x2 { | ||
| 278 | - er.Value[1] = max(er.Value[1], expr.Value[1]) | ||
| 279 | - if isEqual(er.Value[1], expr.Value[1]) { | ||
| 280 | - er.RightOp = expr.OpChar | ||
| 281 | - if len(expr.RightOp) != 0 { | ||
| 282 | - er.RightOp = expr.RightOp | 339 | + _, x1 := toFloat64(er.Value[0], er.Value[1]) |
| 340 | + y0, _ := toFloat64(compare.Value[0], compare.Value[1]) | ||
| 341 | + if y0 <= x1 { | ||
| 342 | + er.Value[1] = max(er.Value[1], compare.Value[1]) | ||
| 343 | + if isEqual(er.Value[1], compare.Value[1]) { | ||
| 344 | + er.RightOp = compare.OpChar | ||
| 345 | + if len(compare.RightOp) != 0 { | ||
| 346 | + er.RightOp = compare.RightOp | ||
| 283 | } | 347 | } |
| 284 | } | 348 | } |
| 285 | return true | 349 | return true |
| @@ -349,6 +413,20 @@ func max(x, y interface{}) interface{} { | @@ -349,6 +413,20 @@ func max(x, y interface{}) interface{} { | ||
| 349 | return math.Max(fx, fy) | 413 | return math.Max(fx, fy) |
| 350 | } | 414 | } |
| 351 | 415 | ||
| 416 | +func less(x, y interface{}) (interface{}, bool) { | ||
| 417 | + if isInfinity(x) { | ||
| 418 | + return x, true | ||
| 419 | + } | ||
| 420 | + if isInfinity(y) { | ||
| 421 | + return y, true | ||
| 422 | + } | ||
| 423 | + fx, fy := toFloat64(x, y) | ||
| 424 | + if fx < fy { | ||
| 425 | + return x, true | ||
| 426 | + } | ||
| 427 | + return fy, false | ||
| 428 | +} | ||
| 429 | + | ||
| 352 | func isInfinity(val interface{}) bool { | 430 | func isInfinity(val interface{}) bool { |
| 353 | v := fmt.Sprintf("%v", val) | 431 | v := fmt.Sprintf("%v", val) |
| 354 | inf := fmt.Sprintf("%v", Infinity) | 432 | inf := fmt.Sprintf("%v", Infinity) |
-
请 注册 或 登录 后发表评论