/
condition.go
121 lines (105 loc) · 2.93 KB
/
condition.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package types
import (
"github.com/rancher/norman/types/convert"
)
var (
CondEQ = QueryConditionType{ModifierEQ, 1}
CondNE = QueryConditionType{ModifierNE, 1}
CondNull = QueryConditionType{ModifierNull, 0}
CondNotNull = QueryConditionType{ModifierNotNull, 0}
CondIn = QueryConditionType{ModifierIn, -1}
CondNotIn = QueryConditionType{ModifierNotIn, -1}
CondOr = QueryConditionType{ModifierType("or"), 1}
CondAnd = QueryConditionType{ModifierType("and"), 1}
mods = map[ModifierType]QueryConditionType{
CondEQ.Name: CondEQ,
CondNE.Name: CondNE,
CondNull.Name: CondNull,
CondNotNull.Name: CondNotNull,
CondIn.Name: CondIn,
CondNotIn.Name: CondNotIn,
CondOr.Name: CondOr,
CondAnd.Name: CondAnd,
}
)
type QueryConditionType struct {
Name ModifierType
Args int
}
type QueryCondition struct {
Field string
Value string
Values map[string]bool
conditionType QueryConditionType
left, right *QueryCondition
}
func (q *QueryCondition) Valid(schema *Schema, data map[string]interface{}) bool {
switch q.conditionType {
case CondAnd:
if q.left == nil || q.right == nil {
return false
}
return q.left.Valid(schema, data) && q.right.Valid(schema, data)
case CondOr:
if q.left == nil || q.right == nil {
return false
}
return q.left.Valid(schema, data) || q.right.Valid(schema, data)
case CondEQ:
return q.Value == convert.ToString(valueOrDefault(schema, data, q))
case CondNE:
return q.Value != convert.ToString(valueOrDefault(schema, data, q))
case CondIn:
return q.Values[convert.ToString(valueOrDefault(schema, data, q))]
case CondNotIn:
return !q.Values[convert.ToString(valueOrDefault(schema, data, q))]
case CondNotNull:
return convert.ToString(valueOrDefault(schema, data, q)) != ""
case CondNull:
return convert.ToString(valueOrDefault(schema, data, q)) == ""
}
return false
}
func valueOrDefault(schema *Schema, data map[string]interface{}, q *QueryCondition) interface{} {
value := data[q.Field]
if value == nil {
value = schema.ResourceFields[q.Field].Default
}
return value
}
func (q *QueryCondition) ToCondition() Condition {
cond := Condition{
Modifier: q.conditionType.Name,
}
if q.conditionType.Args == 1 {
cond.Value = q.Value
} else if q.conditionType.Args == -1 {
stringValues := []string{}
for val := range q.Values {
stringValues = append(stringValues, val)
}
cond.Value = stringValues
}
return cond
}
func ValidMod(mod ModifierType) bool {
_, ok := mods[mod]
return ok
}
func EQ(key, value string) *QueryCondition {
return NewConditionFromString(key, ModifierEQ, value)
}
func NewConditionFromString(field string, mod ModifierType, values ...string) *QueryCondition {
q := &QueryCondition{
Field: field,
conditionType: mods[mod],
Values: map[string]bool{},
}
for i, value := range values {
if i == 0 {
q.Value = value
}
q.Values[value] = true
}
return q
}