正在显示
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) |
-
请 注册 或 登录 后发表评论