-
Notifications
You must be signed in to change notification settings - Fork 101
/
criteria.go
148 lines (132 loc) · 2.81 KB
/
criteria.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
package qbs
type criteria struct {
model *model
condition *Condition
orderBys []order
limit int
offset int
omitFields []string
omitJoin bool
}
func (c *criteria) mergePkCondition(d Dialect) {
var con *Condition
if !c.model.pkZero() {
expr := d.quote(c.model.pk.name) + " = ?"
con = NewCondition(expr, c.model.pk.value)
con.AndCondition(c.condition)
} else {
con = c.condition
}
c.condition = con
}
type order struct {
path string
desc bool
}
// Conditions are structured in a way to define
// complex where clause easily.
type Condition struct {
expr string
args []interface{}
sub *Condition
isOr bool
}
func NewCondition(expr string, args ...interface{}) *Condition {
return &Condition{
expr: expr,
args: args,
}
}
//Snakecase column name
func NewEqualCondition(column string, value interface{}) *Condition {
expr := column + " = ?"
return NewCondition(expr, value)
}
func NewInCondition(column string, values []interface{}) *Condition {
expr := column + " IN ("
for _ = range values {
expr += "?, "
}
expr = expr[:len(expr)-2]
expr += ")"
return &Condition{
expr: expr,
args: values,
}
}
func (c *Condition) And(expr string, args ...interface{}) *Condition {
if c.sub != nil {
c.expr, c.args = c.Merge()
}
c.sub = NewCondition(expr, args...)
c.isOr = false
return c
}
//Snakecase column name
func (c *Condition) AndEqual(column string, value interface{}) *Condition {
expr := column + " = ?"
c.And(expr, value)
return c
}
func (c *Condition) AndCondition(subCondition *Condition) *Condition {
if c.sub != nil {
c.expr, c.args = c.Merge()
}
c.sub = subCondition
c.isOr = false
return c
}
func (c *Condition) Or(expr string, args ...interface{}) *Condition {
if c.sub != nil {
c.expr, c.args = c.Merge()
}
c.sub = NewCondition(expr, args...)
c.isOr = true
return c
}
//Snakecase column name
func (c *Condition) OrEqual(column string, value interface{}) *Condition {
expr := column + " = ?"
c.Or(expr, value)
return c
}
func (c *Condition) OrCondition(subCondition *Condition) *Condition {
if c.sub != nil {
c.expr, c.args = c.Merge()
}
c.sub = subCondition
c.isOr = true
return c
}
func (c *Condition) Merge() (expr string, args []interface{}) {
expr = c.expr
args = c.args
if c.sub == nil {
return
}
expr = "(" + expr + ")"
if c.isOr {
expr += " OR "
} else {
expr += " AND "
}
subExpr, subArgs := c.sub.Merge()
expr += "(" + subExpr + ")"
args = append(args, subArgs...)
return expr, args
}
//Used for in condition.
func StringsToInterfaces(strs ...string) []interface{} {
ret := make([]interface{}, len(strs))
for i := 0; i < len(strs); i++ {
ret[i] = strs[i]
}
return ret
}
func IntsToInterfaces(ints ...int64) []interface{} {
ret := make([]interface{}, len(ints))
for i := 0; i < len(ints); i++ {
ret[i] = ints[i]
}
return ret
}