-
Notifications
You must be signed in to change notification settings - Fork 12
/
filter_builder.go
113 lines (106 loc) · 3.13 KB
/
filter_builder.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
package service
import (
"errors"
"fmt"
"github.com/openline-ai/openline-customer-os/packages/server/customer-os-api/graph/model"
"github.com/openline-ai/openline-customer-os/packages/server/customer-os-common-module/utils"
"reflect"
)
func buildFilter(modelFilter *model.Filter, T reflect.Type) (*utils.CypherFilter, error) {
if modelFilter == nil {
return nil, nil
}
cypherFilter := new(utils.CypherFilter)
cypherFilter.Negate = false
foundAtCurrentLevel := false
if modelFilter.Not != nil {
foundAtCurrentLevel = true
cypherFilter.Negate = true
innerFilter, err := buildFilter(modelFilter.Not, T)
if err != nil {
return nil, err
}
cypherFilter.Filters = append(cypherFilter.Filters, innerFilter)
}
if modelFilter.And != nil {
if foundAtCurrentLevel {
return nil, newFilterError()
}
foundAtCurrentLevel = true
if len(modelFilter.And) < 2 {
return nil, newFilterErrorf("at least 2 filters expected in AND group")
}
cypherFilter.LogicalOperator = utils.AND
for _, v := range modelFilter.And {
innerFilter, err := buildFilter(v, T)
if err != nil {
return nil, err
}
cypherFilter.Filters = append(cypherFilter.Filters, innerFilter)
}
}
if modelFilter.Or != nil {
if foundAtCurrentLevel {
return nil, newFilterError()
}
foundAtCurrentLevel = true
if len(modelFilter.Or) < 2 {
return nil, newFilterErrorf("at least 2 filters expected in OR group")
}
cypherFilter.LogicalOperator = utils.OR
for _, v := range modelFilter.Or {
innerFilter, err := buildFilter(v, T)
if err != nil {
return nil, err
}
cypherFilter.Filters = append(cypherFilter.Filters, innerFilter)
}
}
if modelFilter.Filter != nil {
if foundAtCurrentLevel {
return nil, newFilterError()
}
props, err := utils.GetPropertyDetailsByLookupName(T, modelFilter.Filter.Property)
if err != nil {
return nil, err
}
cypherFilterItem := utils.CypherFilterItem{
NodeProperty: props[utils.TagProperty],
SupportCaseSensitive: props[utils.TagSupportCaseSensitive] == "true",
CaseSensitive: *modelFilter.Filter.CaseSensitive == true,
Value: modelFilter.Filter.Value.RealValue(),
ComparisonOperator: comparisonOperatorToEnum(modelFilter.Filter.Operation),
DbNodePropertyProps: props,
}
cypherFilter.Details = &cypherFilterItem
}
return cypherFilter, nil
}
func comparisonOperatorToEnum(co model.ComparisonOperator) utils.ComparisonOperator {
switch co {
case model.ComparisonOperatorContains:
return utils.CONTAINS
case model.ComparisonOperatorStartsWith:
return utils.STARTS_WITH
case model.ComparisonOperatorIn:
return utils.IN
case model.ComparisonOperatorLte:
return utils.LTE
case model.ComparisonOperatorGte:
return utils.GTE
case model.ComparisonOperatorBetween:
return utils.BETWEEN
case model.ComparisonOperatorIsNull:
return utils.IS_NULL
case model.ComparisonOperatorIsEmpty:
return utils.IS_EMPTY
default:
return utils.EQUALS
}
}
func newFilterError() error {
return errors.New("incorrect filter formatting")
}
func newFilterErrorf(msg string) error {
return errors.New(fmt.Sprintf("incorrect filter formatting: %s", msg))
}