...
1 package exp
2
3 import (
4 "sort"
5 "strings"
6
7 "github.com/doug-martin/goqu/v9/internal/errors"
8 )
9
10 type (
11
12
13
14
15 Ex map[string]interface{}
16
17
18
19
20 ExOr map[string]interface{}
21
22 Op map[string]interface{}
23 )
24
25 func (e Ex) Expression() Expression {
26 return e
27 }
28
29 func (e Ex) Clone() Expression {
30 ret := Ex{}
31 for key, val := range e {
32 ret[key] = val
33 }
34 return ret
35 }
36
37 func (e Ex) IsEmpty() bool {
38 return len(e) == 0
39 }
40
41 func (e Ex) ToExpressions() (ExpressionList, error) {
42 return mapToExpressionList(e, AndType)
43 }
44
45 func (eo ExOr) Expression() Expression {
46 return eo
47 }
48
49 func (eo ExOr) Clone() Expression {
50 ret := ExOr{}
51 for key, val := range eo {
52 ret[key] = val
53 }
54 return ret
55 }
56
57 func (eo ExOr) IsEmpty() bool {
58 return len(eo) == 0
59 }
60
61 func (eo ExOr) ToExpressions() (ExpressionList, error) {
62 return mapToExpressionList(eo, OrType)
63 }
64
65 func getExMapKeys(ex map[string]interface{}) []string {
66 keys := make([]string, 0, len(ex))
67 for key := range ex {
68 keys = append(keys, key)
69 }
70 sort.Strings(keys)
71 return keys
72 }
73
74 func mapToExpressionList(ex map[string]interface{}, eType ExpressionListType) (ExpressionList, error) {
75 keys := getExMapKeys(ex)
76 ret := make([]Expression, 0, len(keys))
77 for _, key := range keys {
78 lhs := ParseIdentifier(key)
79 rhs := ex[key]
80 var exp Expression
81 if op, ok := rhs.(Op); ok {
82 ors, err := createOredExpressionFromMap(lhs, op)
83 if err != nil {
84 return nil, err
85 }
86 exp = NewExpressionList(OrType, ors...)
87 } else {
88 exp = lhs.Eq(rhs)
89 }
90 ret = append(ret, exp)
91 }
92 if eType == OrType {
93 return NewExpressionList(OrType, ret...), nil
94 }
95 return NewExpressionList(AndType, ret...), nil
96 }
97
98 func createOredExpressionFromMap(lhs IdentifierExpression, op Op) ([]Expression, error) {
99 opKeys := getExMapKeys(op)
100 ors := make([]Expression, 0, len(opKeys))
101 for _, opKey := range opKeys {
102 if exp, err := createExpressionFromOp(lhs, opKey, op); err != nil {
103 return nil, err
104 } else if exp != nil {
105 ors = append(ors, exp)
106 }
107 }
108 return ors, nil
109 }
110
111
112 func createExpressionFromOp(lhs IdentifierExpression, opKey string, op Op) (exp Expression, err error) {
113 switch strings.ToLower(opKey) {
114 case EqOp.String():
115 exp = lhs.Eq(op[opKey])
116 case NeqOp.String():
117 exp = lhs.Neq(op[opKey])
118 case IsOp.String():
119 exp = lhs.Is(op[opKey])
120 case IsNotOp.String():
121 exp = lhs.IsNot(op[opKey])
122 case GtOp.String():
123 exp = lhs.Gt(op[opKey])
124 case GteOp.String():
125 exp = lhs.Gte(op[opKey])
126 case LtOp.String():
127 exp = lhs.Lt(op[opKey])
128 case LteOp.String():
129 exp = lhs.Lte(op[opKey])
130 case InOp.String():
131 exp = lhs.In(op[opKey])
132 case NotInOp.String():
133 exp = lhs.NotIn(op[opKey])
134 case LikeOp.String():
135 exp = lhs.Like(op[opKey])
136 case NotLikeOp.String():
137 exp = lhs.NotLike(op[opKey])
138 case ILikeOp.String():
139 exp = lhs.ILike(op[opKey])
140 case NotILikeOp.String():
141 exp = lhs.NotILike(op[opKey])
142 case RegexpLikeOp.String():
143 exp = lhs.RegexpLike(op[opKey])
144 case RegexpNotLikeOp.String():
145 exp = lhs.RegexpNotLike(op[opKey])
146 case RegexpILikeOp.String():
147 exp = lhs.RegexpILike(op[opKey])
148 case RegexpNotILikeOp.String():
149 exp = lhs.RegexpNotILike(op[opKey])
150 case betweenStr:
151 rangeVal, ok := op[opKey].(RangeVal)
152 if ok {
153 exp = lhs.Between(rangeVal)
154 }
155 case "notbetween":
156 rangeVal, ok := op[opKey].(RangeVal)
157 if ok {
158 exp = lhs.NotBetween(rangeVal)
159 }
160 default:
161 err = errors.New("unsupported expression type %s", opKey)
162 }
163 return exp, err
164 }
165
View as plain text