-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommonqueryrepresentation.go
143 lines (125 loc) · 3.53 KB
/
commonqueryrepresentation.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Package cqr provides a common query representation for keyword and Boolean queries in go.
package cqr
import (
"fmt"
"sort"
"strings"
"sync"
)
var (
ExplodedString = "exploded"
TruncatedString = "truncated"
AND = "and"
OR = "or"
NOT = "not"
mu sync.Mutex
)
// CommonQueryRepresentation is the parent type for all subtypes.
type CommonQueryRepresentation interface {
String() string
StringPretty() string
GetOption(string) interface{}
SetOption(string, interface{}) CommonQueryRepresentation
}
// Keyword is a single query expression.
type Keyword struct {
QueryString string `json:"query"`
Fields []string `json:"fields"`
Options map[string]interface{} `json:"options"`
}
// BooleanQuery is a nested set of queries, containing either more Boolean queries, or keywords.
type BooleanQuery struct {
Operator string `json:"operator"`
Children []CommonQueryRepresentation `json:"children"`
Options map[string]interface{} `json:"options"`
}
// String computes the string representation of a keyword.
func (k Keyword) String() string {
s := make([]string, len(k.Options))
i := 0
for k, v := range k.Options {
s[i] = fmt.Sprintf("%v:%v", k, v)
i++
}
sort.Strings(s)
return fmt.Sprintf("%v %v {%v}", k.QueryString, k.Fields, strings.Join(s, " "))
}
func (k Keyword) StringPretty() string {
return k.QueryString
}
// String computes the string representation of a Boolean query.
func (b BooleanQuery) String() (s string) {
x := make([]string, len(b.Options))
i := 0
for k, v := range b.Options {
x[i] = fmt.Sprintf("%v:%v", k, v)
i++
}
sort.Strings(x)
y := make([]string, len(b.Children))
for i, child := range b.Children {
y[i] = child.String()
}
sort.Strings(y)
s += fmt.Sprintf(" ( %v[%v]", b.Operator, x)
for _, child := range y {
s += fmt.Sprintf(" %v", child)
}
s += ") "
return strings.TrimSpace(s)
}
// String computes the string representation of a Boolean query.
func (b BooleanQuery) StringPretty() (s string) {
return b.Operator
}
// SetOption sets an optional parameter on the keyword.
func (k Keyword) SetOption(key string, value interface{}) CommonQueryRepresentation {
k.Options[key] = value
return k
}
// SetOption sets an optional parameter on the Boolean query.
func (b BooleanQuery) SetOption(key string, value interface{}) CommonQueryRepresentation {
b.Options[key] = value
return b
}
// GetOption gets an optional parameter of the keyword.
func (k Keyword) GetOption(key string) interface{} {
return k.Options[key]
}
// GetOption gets an optional parameter of the Boolean Query.
func (b BooleanQuery) GetOption(key string) interface{} {
return b.Options[key]
}
// NewKeyword constructs a new keyword.
func NewKeyword(queryString string, fields ...string) Keyword {
return Keyword{
QueryString: queryString,
Fields: fields,
Options: map[string]interface{}{},
}
}
// NewBooleanQuery constructs a new Boolean query.
func NewBooleanQuery(operator string, children []CommonQueryRepresentation) BooleanQuery {
return BooleanQuery{
Operator: operator,
Children: children,
Options: map[string]interface{}{},
}
}
func IsBoolean(query CommonQueryRepresentation) bool {
if _, ok := query.(BooleanQuery); ok {
return true
}
return false
}
func CopyKeyword(query Keyword) Keyword {
fields := make([]string, len(query.Fields))
copy(fields, query.Fields)
nq := NewKeyword(query.QueryString, fields...)
mu.Lock()
for k, v := range query.Options {
nq.Options[k] = v
}
mu.Unlock()
return nq
}