1 package exp
2
3 import (
4 "reflect"
5 "regexp"
6 )
7
8 type boolean struct {
9 lhs Expression
10 rhs interface{}
11 op BooleanOperation
12 }
13
14 func NewBooleanExpression(op BooleanOperation, lhs Expression, rhs interface{}) BooleanExpression {
15 return boolean{op: op, lhs: lhs, rhs: rhs}
16 }
17
18 func (b boolean) Clone() Expression {
19 return NewBooleanExpression(b.op, b.lhs.Clone(), b.rhs)
20 }
21
22 func (b boolean) Expression() Expression {
23 return b
24 }
25
26 func (b boolean) RHS() interface{} {
27 return b.rhs
28 }
29
30 func (b boolean) LHS() Expression {
31 return b.lhs
32 }
33
34 func (b boolean) Op() BooleanOperation {
35 return b.op
36 }
37
38 func (b boolean) As(val interface{}) AliasedExpression {
39 return NewAliasExpression(b, val)
40 }
41
42
43 func eq(lhs Expression, rhs interface{}) BooleanExpression {
44 return checkBoolExpType(EqOp, lhs, rhs, false)
45 }
46
47
48 func neq(lhs Expression, rhs interface{}) BooleanExpression {
49 return checkBoolExpType(EqOp, lhs, rhs, true)
50 }
51
52
53 func gt(lhs Expression, rhs interface{}) BooleanExpression {
54 return NewBooleanExpression(GtOp, lhs, rhs)
55 }
56
57
58 func gte(lhs Expression, rhs interface{}) BooleanExpression {
59 return NewBooleanExpression(GteOp, lhs, rhs)
60 }
61
62
63 func lt(lhs Expression, rhs interface{}) BooleanExpression {
64 return NewBooleanExpression(LtOp, lhs, rhs)
65 }
66
67
68 func lte(lhs Expression, rhs interface{}) BooleanExpression {
69 return NewBooleanExpression(LteOp, lhs, rhs)
70 }
71
72
73 func in(lhs Expression, vals ...interface{}) BooleanExpression {
74 if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
75 return NewBooleanExpression(InOp, lhs, vals[0])
76 }
77 return NewBooleanExpression(InOp, lhs, vals)
78 }
79
80
81 func notIn(lhs Expression, vals ...interface{}) BooleanExpression {
82 if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
83 return NewBooleanExpression(NotInOp, lhs, vals[0])
84 }
85 return NewBooleanExpression(NotInOp, lhs, vals)
86 }
87
88
89 func is(lhs Expression, val interface{}) BooleanExpression {
90 return checkBoolExpType(IsOp, lhs, val, false)
91 }
92
93
94 func isNot(lhs Expression, val interface{}) BooleanExpression {
95 return checkBoolExpType(IsOp, lhs, val, true)
96 }
97
98
99 func like(lhs Expression, val interface{}) BooleanExpression {
100 return checkLikeExp(LikeOp, lhs, val, false)
101 }
102
103
104 func iLike(lhs Expression, val interface{}) BooleanExpression {
105 return checkLikeExp(ILikeOp, lhs, val, false)
106 }
107
108
109 func notLike(lhs Expression, val interface{}) BooleanExpression {
110 return checkLikeExp(LikeOp, lhs, val, true)
111 }
112
113
114 func notILike(lhs Expression, val interface{}) BooleanExpression {
115 return checkLikeExp(ILikeOp, lhs, val, true)
116 }
117
118
119 func regexpLike(lhs Expression, val interface{}) BooleanExpression {
120 return checkLikeExp(RegexpLikeOp, lhs, val, false)
121 }
122
123
124 func regexpILike(lhs Expression, val interface{}) BooleanExpression {
125 return checkLikeExp(RegexpILikeOp, lhs, val, false)
126 }
127
128
129 func regexpNotLike(lhs Expression, val interface{}) BooleanExpression {
130 return checkLikeExp(RegexpLikeOp, lhs, val, true)
131 }
132
133
134 func regexpNotILike(lhs Expression, val interface{}) BooleanExpression {
135 return checkLikeExp(RegexpILikeOp, lhs, val, true)
136 }
137
138
139 func checkLikeExp(op BooleanOperation, lhs Expression, val interface{}, invert bool) BooleanExpression {
140 rhs := val
141
142 if t, ok := val.(*regexp.Regexp); ok {
143 if op == LikeOp {
144 op = RegexpLikeOp
145 } else if op == ILikeOp {
146 op = RegexpILikeOp
147 }
148 rhs = t.String()
149 }
150 if invert {
151 op = operatorInversions[op]
152 }
153 return NewBooleanExpression(op, lhs, rhs)
154 }
155
156
157 func checkBoolExpType(op BooleanOperation, lhs Expression, rhs interface{}, invert bool) BooleanExpression {
158 if rhs == nil {
159 op = IsOp
160 } else {
161 switch reflect.Indirect(reflect.ValueOf(rhs)).Kind() {
162 case reflect.Bool:
163 op = IsOp
164 case reflect.Slice:
165
166 if _, ok := rhs.([]byte); !ok {
167 op = InOp
168 }
169 case reflect.Struct:
170 switch rhs.(type) {
171 case SQLExpression:
172 op = InOp
173 case AppendableExpression:
174 op = InOp
175 case *regexp.Regexp:
176 return checkLikeExp(LikeOp, lhs, rhs, invert)
177 }
178 default:
179 }
180 }
181 if invert {
182 op = operatorInversions[op]
183 }
184 return NewBooleanExpression(op, lhs, rhs)
185 }
186
View as plain text