Skip to content

Commit dabf32f

Browse files
committed
[add] between rules and start,end value
1 parent a067fd3 commit dabf32f

File tree

3 files changed

+88
-22
lines changed

3 files changed

+88
-22
lines changed

condition.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package querysql
2+
3+
type Condition struct {
4+
Rule string `json:"type"`
5+
Value interface{} `json:"filter"`
6+
}
7+
8+
func (c *Condition) getValues() []interface{} {
9+
valueMap, ok := c.Value.(map[string]interface{})
10+
if !ok {
11+
return []interface{}{c.Value}
12+
}
13+
14+
return []interface{}{valueMap["start"], valueMap["end"]}
15+
}

sql.go

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,7 @@ type Filter struct {
1414
Kids []Filter `json:"rules"`
1515
}
1616

17-
type Condition struct {
18-
Rule string `json:"type"`
19-
Value interface{} `json:"filter"`
20-
}
21-
22-
type CustomOperation func(string, Condition) (string, []interface{}, error)
17+
type CustomOperation func(string, string, []interface{}) (string, []interface{}, error)
2318

2419
type SQLConfig struct {
2520
Whitelist map[string]bool
@@ -54,43 +49,68 @@ func GetSQL(data Filter, config *SQLConfig) (string, []interface{}, error) {
5449
return inSQL(data.Field, data.Includes)
5550
}
5651

52+
values := data.Condition.getValues()
5753
switch data.Condition.Rule {
5854
case "":
5955
return "", NoValues, nil
6056
case "equal":
61-
return fmt.Sprintf("%s = ?", data.Field), []interface{}{data.Condition.Value}, nil
57+
return fmt.Sprintf("%s = ?", data.Field), values, nil
6258
case "notEqual":
63-
return fmt.Sprintf("%s <> ?", data.Field), []interface{}{data.Condition.Value}, nil
59+
return fmt.Sprintf("%s <> ?", data.Field), values, nil
6460
case "contains":
65-
return fmt.Sprintf("INSTR(%s, ?) > 0", data.Field), []interface{}{data.Condition.Value}, nil
61+
return fmt.Sprintf("INSTR(%s, ?) > 0", data.Field), values, nil
6662
case "notContains":
67-
return fmt.Sprintf("INSTR(%s, ?) < 0", data.Field), []interface{}{data.Condition.Value}, nil
63+
return fmt.Sprintf("INSTR(%s, ?) < 0", data.Field), values, nil
6864
case "lessOrEqual":
69-
return fmt.Sprintf("%s <= ?", data.Field), []interface{}{data.Condition.Value}, nil
65+
return fmt.Sprintf("%s <= ?", data.Field), values, nil
7066
case "greaterOrEqual":
71-
return fmt.Sprintf("%s >= ?", data.Field), []interface{}{data.Condition.Value}, nil
67+
return fmt.Sprintf("%s >= ?", data.Field), values, nil
7268
case "less":
73-
return fmt.Sprintf("%s < ?", data.Field), []interface{}{data.Condition.Value}, nil
69+
return fmt.Sprintf("%s < ?", data.Field), values, nil
70+
case "notBetween":
71+
if len(values) != 2 {
72+
return "", nil, fmt.Errorf("wrong number of parameters for notBetween operation: %d", len(values))
73+
}
74+
75+
if values[0] == nil {
76+
return fmt.Sprintf("%s > ?", data.Field), values[1:], nil
77+
} else if values[1] == nil {
78+
return fmt.Sprintf("%s < ?", data.Field), values[:1], nil
79+
} else {
80+
return fmt.Sprintf("( %s < ? OR %s > ? )", data.Field, data.Field), values, nil
81+
}
82+
case "between":
83+
if len(values) != 2 {
84+
return "", nil, fmt.Errorf("wrong number of parameters for notBetween operation: %d", len(values))
85+
}
86+
87+
if values[0] == nil {
88+
return fmt.Sprintf("%s < ?", data.Field), values[1:], nil
89+
} else if values[1] == nil {
90+
return fmt.Sprintf("%s > ?", data.Field), values[:1], nil
91+
} else {
92+
return fmt.Sprintf("( %s > ? AND %s < ? )", data.Field, data.Field), values, nil
93+
}
7494
case "greater":
75-
return fmt.Sprintf("%s > ?", data.Field), []interface{}{data.Condition.Value}, nil
95+
return fmt.Sprintf("%s > ?", data.Field), values, nil
7696
case "beginsWith":
7797
search := "CONCAT(?, '%')"
78-
return fmt.Sprintf("%s LIKE %s", data.Field, search), []interface{}{data.Condition.Value}, nil
98+
return fmt.Sprintf("%s LIKE %s", data.Field, search), values, nil
7999
case "notBeginsWith":
80100
search := "CONCAT(?, '%')"
81-
return fmt.Sprintf("%s NOT LIKE %s", data.Field, search), []interface{}{data.Condition.Value}, nil
101+
return fmt.Sprintf("%s NOT LIKE %s", data.Field, search), values, nil
82102
case "endsWith":
83103
search := "CONCAT('%', ?)"
84-
return fmt.Sprintf("%s LIKE %s", data.Field, search), []interface{}{data.Condition.Value}, nil
104+
return fmt.Sprintf("%s LIKE %s", data.Field, search), values, nil
85105
case "notEndsWith":
86106
search := "CONCAT('%', ?)"
87-
return fmt.Sprintf("%s NOT LIKE %s", data.Field, search), []interface{}{data.Condition.Value}, nil
107+
return fmt.Sprintf("%s NOT LIKE %s", data.Field, search), values, nil
88108
}
89109

90110
if config != nil && config.Operations != nil {
91111
op, opOk := config.Operations[data.Condition.Rule]
92112
if opOk {
93-
return op(data.Field, data.Condition)
113+
return op(data.Field, data.Condition.Rule, data.Condition.getValues())
94114
}
95115
}
96116

sql_test.go

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,36 @@ var cases = [][]string{
7373
"a NOT LIKE CONCAT('%', ?)",
7474
"1",
7575
},
76+
[]string{
77+
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"between", "filter":{ "start":1, "end":2 } }}]}`,
78+
"( a > ? AND a < ? )",
79+
"1,2",
80+
},
81+
[]string{
82+
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"between", "filter":{ "start":1 } }}]}`,
83+
"a > ?",
84+
"1",
85+
},
86+
[]string{
87+
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"between", "filter":{ "end":2 } }}]}`,
88+
"a < ?",
89+
"2",
90+
},
91+
[]string{
92+
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notBetween", "filter":{ "start":1, "end":2 } }}]}`,
93+
"( a < ? OR a > ? )",
94+
"1,2",
95+
},
96+
[]string{
97+
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notBetween", "filter":{ "start":1 } }}]}`,
98+
"a < ?",
99+
"1",
100+
},
101+
[]string{
102+
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notBetween", "filter":{ "end":2 } }}]}`,
103+
"a > ?",
104+
"2",
105+
},
76106
[]string{
77107
aAndB,
78108
"( a < ? AND b > ? )",
@@ -199,11 +229,12 @@ func TestCustomOperation(t *testing.T) {
199229

200230
sql, vals, err := GetSQL(format, &SQLConfig{
201231
Operations: map[string]CustomOperation{
202-
"is null" : func(n string, c Condition) (string, []interface{}, error) {
232+
"is null" : func(n string, r string, values []interface{}) (string, []interface{}, error) {
203233
return fmt.Sprintf("%s IS NULL", n), NoValues, nil
204234
},
205-
"range100" : func(n string, c Condition) (string, []interface{}, error) {
206-
return fmt.Sprintf("( %s > ? AND %s < ? + 100 )", n, n), []interface{}{c.Value, c.Value}, nil
235+
"range100" : func(n string, r string, values []interface{}) (string, []interface{}, error) {
236+
out := []interface{}{values[0], values[0]}
237+
return fmt.Sprintf("( %s > ? AND %s < ? + 100 )", n, n), out, nil
207238
},
208239
},
209240
})

0 commit comments

Comments
 (0)