-
Notifications
You must be signed in to change notification settings - Fork 0
/
predicate.go
168 lines (157 loc) · 3.86 KB
/
predicate.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package surf
import (
"strconv"
)
type PredicateType int
const (
WHERE_IS_NOT_NULL PredicateType = iota // Default
WHERE_IS_NULL
WHERE_IN
WHERE_NOT_IN
WHERE_LIKE
WHERE_EQUAL
WHERE_NOT_EQUAL
WHERE_GREATER_THAN
WHERE_GREATER_THAN_OR_EQUAL_TO
WHERE_LESS_THAN
WHERE_LESS_THAN_OR_EQUAL_TO
)
// getPredicateTypeString returns the predicate type string from it's value
func getPredicateTypeString(predicateType PredicateType) string {
switch predicateType {
case WHERE_IS_NULL:
return "WHERE_IS_NULL"
case WHERE_IN:
return "WHERE_IN"
case WHERE_NOT_IN:
return "WHERE_NOT_IN"
case WHERE_LIKE:
return "WHERE_LIKE"
case WHERE_EQUAL:
return "WHERE_EQUAL"
case WHERE_NOT_EQUAL:
return "WHERE_NOT_EQUAL"
case WHERE_GREATER_THAN:
return "WHERE_GREATER_THAN"
case WHERE_GREATER_THAN_OR_EQUAL_TO:
return "WHERE_GREATER_THAN_OR_EQUAL_TO"
case WHERE_LESS_THAN:
return "WHERE_LESS_THAN"
case WHERE_LESS_THAN_OR_EQUAL_TO:
return "WHERE_LESS_THAN_OR_EQUAL_TO"
}
return "WHERE_IS_NOT_NULL"
}
// Predicate is the definition of a single where SQL predicate
type Predicate struct {
Field string
PredicateType PredicateType
Values []interface{}
}
// toString will convert a predicate to it's query string, along with its values
// to be passed along with the query
//
// This function will panic in the event that this is called on a malformed predicate
func (p *Predicate) toString(valueIndex int) (string, []interface{}) {
// Field
predicate := p.Field
// Type
switch p.PredicateType {
case WHERE_IS_NULL:
predicate += " IS NULL"
break
case WHERE_IN:
predicate += " IN "
break
case WHERE_NOT_IN:
predicate += " NOT IN "
break
case WHERE_LIKE:
predicate += " LIKE "
break
case WHERE_EQUAL:
predicate += " = "
break
case WHERE_NOT_EQUAL:
predicate += " != "
break
case WHERE_GREATER_THAN:
predicate += " > "
break
case WHERE_GREATER_THAN_OR_EQUAL_TO:
predicate += " >= "
break
case WHERE_LESS_THAN:
predicate += " < "
break
case WHERE_LESS_THAN_OR_EQUAL_TO:
predicate += " <= "
break
default:
predicate += " IS NOT NULL"
break
}
// Values
values := make([]interface{}, 0)
switch p.PredicateType {
case WHERE_IN,
WHERE_NOT_IN:
if len(p.Values) == 0 {
panic("`" + getPredicateTypeString(p.PredicateType) + "` predicates require at least one value.")
}
predicate += "("
for i, value := range p.Values {
values = append(values, value)
predicate += "$" + strconv.Itoa(valueIndex)
valueIndex++
if i < len(p.Values)-1 {
predicate += ", "
}
}
predicate += ")"
break
case WHERE_LIKE,
WHERE_EQUAL,
WHERE_NOT_EQUAL,
WHERE_GREATER_THAN,
WHERE_GREATER_THAN_OR_EQUAL_TO,
WHERE_LESS_THAN,
WHERE_LESS_THAN_OR_EQUAL_TO:
if len(p.Values) != 1 {
panic("`" + getPredicateTypeString(p.PredicateType) + "` predicates require exactly one value.")
}
values = append(values, p.Values[0])
predicate += "$" + strconv.Itoa(valueIndex)
break
case WHERE_IS_NOT_NULL,
WHERE_IS_NULL:
if len(p.Values) != 0 {
panic("`" + getPredicateTypeString(p.PredicateType) + "` predicates cannot have any values.")
}
break
default:
panic("Unknown predicate type.")
}
return predicate, values
}
// predicatesToString converts an array of predicates to a query string, along with its values
// to be passed along with the query
//
// This function will panic in the event that it encounters a malformed predicate
func predicatesToString(valueIndex int, predicates []Predicate) (string, []interface{}) {
values := make([]interface{}, 0)
predicateStr := ""
if len(predicates) > 0 {
predicateStr += "WHERE "
}
for i, predicate := range predicates {
iPredicateStr, iValues := predicate.toString(valueIndex)
valueIndex += len(iValues)
values = append(values, iValues...)
predicateStr += iPredicateStr
if i < (len(predicates) - 1) {
predicateStr += " AND "
}
}
return predicateStr, values
}