-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.go
98 lines (86 loc) · 2.5 KB
/
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
package godruid
import (
"encoding/json"
"errors"
"time"
)
type OperationType string
var (
Selector OperationType = "selector"
AndExp OperationType = "and"
OrExp OperationType = "or"
NotExp OperationType = "not"
InExp OperationType = "in"
BoundFilter OperationType = "bound"
Regex OperationType = "regex"
ErrFilterCannotHaveChildren = errors.New("cannot append filter to selector type")
ErrFilterCannotHaveSibling = errors.New("non-selector filter type cannot have sibling")
)
type Filter struct {
FilterType OperationType `json:"type,omitempty"`
Dimension string `json:"dimension,omitempty"`
Value string `json:"value,omitempty"`
Values []string `json:"values,omitempty"` // Thanks Druid
Pattern string `json:"pattern,omitempty"`
Filters []*Filter `json:"fields,omitempty"`
Filter *Filter `json:"field,omitempty"`
Upper string `json:"upper,omitempty"`
Lower string `json:"lower,omitempty"`
ExtractionFn *ExtractionFn `json:"extractionFn,omitmpty"`
}
func NewBaseFilter(filterType OperationType) *Filter {
return &Filter{
FilterType: filterType,
Filters: []*Filter{},
}
}
func NewDimensionFilter(dimension, value string) *Filter {
return &Filter{
FilterType: Selector,
Dimension: dimension,
Value: value,
}
}
func NewRegexFilter(dimension, pattern string) *Filter {
return &Filter{
FilterType: Regex,
Pattern: pattern,
}
}
func NewInFilter(dimension string, values []string) *Filter {
return &Filter{
FilterType: InExp,
Dimension: dimension,
Values: values,
}
}
func NewTimeBoundFilter(dimension string, start, end time.Time, timezone, timeFormat string) *Filter {
return &Filter{
FilterType: BoundFilter,
Upper: end.Format(timeFormat),
Lower: start.Format(timeFormat),
Dimension: dimension,
ExtractionFn: &ExtractionFn{
Type: TimeFormatExtractionType,
Format: timeFormat,
TimeZone: timezone,
},
}
}
func (f *Filter) AddChildren(newFs ...*Filter) error {
if f.FilterType == Selector {
return ErrFilterCannotHaveChildren
}
f.Filters = append(f.Filters, newFs...)
return nil
}
// MarshalJSON will check the length of the child filters as Druid hates 1 item
// arrays and for Not filters they are illegal it needs to be an object.
func (f Filter) MarshalJSON() ([]byte, error) {
type Alias Filter
if len(f.Filters) == 1 {
f.Filter = f.Filters[0]
f.Filters = nil
}
return json.Marshal((Alias)(f))
}