-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmysql_filter.go
117 lines (101 loc) · 3.33 KB
/
mysql_filter.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
package mysql
import (
"github.com/spf13/cast"
"github.com/suvera/goScim2/scim2"
"log"
"strings"
)
type FilterConverter struct {
scim2.BaseDbFilterConverter
}
func NewMysqlFilterConverter() *FilterConverter {
return &FilterConverter{}
}
func (f *FilterConverter) Convert(filter string, columnMappings map[string]string) *scim2.ScimError {
f.ColumnMappings = columnMappings
f.Clause = scim2.DbFilterClause{
WhereClause: "",
Binds: make(map[string]any),
}
return scim2.ParseFilter(filter, f)
}
func (f *FilterConverter) OnAttributeExpression(expression *scim2.AttributeExpression) {
column := f.GetMappedColumn(expression)
if column == "" {
log.Printf("Filter column '%s' is not supported in this context\n", expression.Attribute)
return
}
bindVar := f.GetBindVariable()
value := expression.Value
valueType := expression.ValueType
op := expression.Operator
switch op {
case scim2.FilterConditionEqual, scim2.FilterConditionNotEqual:
compOp := " = :" + bindVar
if op == scim2.FilterConditionNotEqual {
compOp = " != :" + bindVar
}
if valueType == scim2.ValueTypeString && f.CaseInsensitive {
column = "LOWER(" + column + ")"
value = strings.ToLower(cast.ToString(value))
}
f.Clause.WhereClause += column + compOp
f.Clause.Binds[bindVar] = value
case scim2.FilterConditionContains, scim2.FilterConditionStartsWith, scim2.FilterConditionEndsWith:
if valueType != scim2.ValueTypeString {
log.Printf("Unsupported value type for operator %s", op)
return
}
if f.CaseInsensitive {
column = "LOWER(" + column + ")"
value = strings.ToLower(cast.ToString(value))
}
f.Clause.WhereClause += column + " LIKE :" + bindVar
strVal := cast.ToString(value)
if op == scim2.FilterConditionStartsWith {
strVal = strVal + "%"
} else if op == scim2.FilterConditionEndsWith {
strVal = "%" + strVal
} else {
strVal = "%" + strVal + "%"
}
f.Clause.Binds[bindVar] = strVal
case scim2.FilterConditionLesserThan, scim2.FilterConditionGreaterThan, scim2.FilterConditionLesserThanEquals, scim2.FilterConditionGreaterThanEquals:
if valueType != scim2.ValueTypeInteger && valueType != scim2.ValueTypeDecimal && valueType != scim2.ValueTypeDateTime {
log.Printf("Unsupported value type for operator %s", op)
return
}
dbOp := "<"
if op == scim2.FilterConditionGreaterThan {
dbOp = ">"
} else if op == scim2.FilterConditionLesserThanEquals {
dbOp = "<="
} else if op == scim2.FilterConditionGreaterThanEquals {
dbOp = ">="
}
f.Clause.WhereClause += column + " " + dbOp + " :" + bindVar
f.Clause.Binds[bindVar] = value
case scim2.FilterConditionPresent:
f.Clause.WhereClause += column + " IS NOT NULL"
if valueType == scim2.ValueTypeString {
f.Clause.WhereClause += " AND " + column + " != ''"
} else if valueType == scim2.ValueTypeInteger || valueType == scim2.ValueTypeDecimal {
f.Clause.WhereClause += " AND " + column + " != 0"
}
default:
log.Printf("Unsupported filter operator %s", op)
}
}
func (f *FilterConverter) OnOpenParenthesis(negated bool) {
if negated {
f.Clause.WhereClause += " NOT ( "
} else {
f.Clause.WhereClause += " ( "
}
}
func (f *FilterConverter) OnCloseParenthesis(negated bool) {
f.Clause.WhereClause += " ) "
}
func (f *FilterConverter) OnLogicalOperator(operation scim2.FilterOperation) {
f.Clause.WhereClause += " " + string(operation) + " "
}