This repository has been archived by the owner on Dec 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathgeofence_query_builder.go
209 lines (184 loc) · 7.1 KB
/
geofence_query_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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package t38c
import (
"context"
"strconv"
"strings"
)
// GeofenceQueryBuilder optional params
type GeofenceQueryBuilder struct {
client tile38Client
isRoamQuery bool
cmd string
key string
area cmd
target string
pattern string
meters int
outputFormat *OutputFormat
detectActions []DetectAction
notifyCommands []NotifyCommand
searchOpts searchOpts
isNodwell bool
}
func newGeofenceQueryBuilder(client tile38Client, cmd, key string, area cmd) GeofenceQueryBuilder {
return GeofenceQueryBuilder{
client: client,
cmd: cmd,
key: key,
area: area,
}
}
func newGeofenceRoamQueryBuilder(client tile38Client, key, target, pattern string, meters int, nodwell bool) GeofenceQueryBuilder {
return GeofenceQueryBuilder{
client: client,
cmd: "NEARBY",
isRoamQuery: true,
key: key,
target: target,
pattern: pattern,
meters: meters,
isNodwell: nodwell,
}
}
func (query GeofenceQueryBuilder) toCmd() cmd {
args := []string{query.key}
args = append(args, query.searchOpts.Args()...)
args = append(args, "FENCE")
if query.isNodwell {
args = append(args, "NODWELL")
}
if len(query.detectActions) > 0 {
actions := make([]string, len(query.detectActions))
for i := range query.detectActions {
actions[i] = string(query.detectActions[i])
}
args = append(args, "DETECT", strings.Join(actions, ","))
}
if len(query.notifyCommands) > 0 {
commands := make([]string, len(query.notifyCommands))
for i := range query.notifyCommands {
commands[i] = string(query.notifyCommands[i])
}
args = append(args, "COMMANDS", strings.Join(commands, ","))
}
if query.outputFormat != nil {
args = append(args, query.outputFormat.Name)
args = append(args, query.outputFormat.Args...)
}
if query.isRoamQuery {
args = append(args, "ROAM", query.target, query.pattern, strconv.Itoa(query.meters))
} else {
args = append(args, query.area.Name)
args = append(args, query.area.Args...)
}
return newCmd(query.cmd, args...)
}
// Do cmd
func (query GeofenceQueryBuilder) Do(ctx context.Context, handler EventHandler) error {
cmd := query.toCmd()
return query.client.ExecuteStream(ctx, rawEventHandler(handler), cmd.Name, cmd.Args...)
}
// Actions sets the geofence actions.
// All actions used by default.
func (query GeofenceQueryBuilder) Actions(actions ...DetectAction) GeofenceQueryBuilder {
query.detectActions = append(query.detectActions, actions...)
return query
}
// Commands sets the geofence commands.
func (query GeofenceQueryBuilder) Commands(notifyCommands ...NotifyCommand) GeofenceQueryBuilder {
query.notifyCommands = append(query.notifyCommands, notifyCommands...)
return query
}
// NoFields tells the server that you do not want field values returned with the search results.
func (query GeofenceQueryBuilder) NoFields() GeofenceQueryBuilder {
query.searchOpts.NoFields = true
return query
}
// Clip tells the server to clip intersecting objects by the bounding box area of the search.
// It can only be used with these area formats: BOUNDS, TILE, QUADKEY, HASH.
func (query GeofenceQueryBuilder) Clip() GeofenceQueryBuilder {
query.searchOpts.Clip = true
return query
}
// Distance allows to return between objects. Only for NEARBY tileCmd.
func (query GeofenceQueryBuilder) Distance() GeofenceQueryBuilder {
query.searchOpts.Distance = true
return query
}
// Cursor is used to iterate though many objects from the search results.
// An iteration begins when the CURSOR is set to Zero or not included with the request,
// and completes when the cursor returned by the server is Zero.
func (query GeofenceQueryBuilder) Cursor(cursor int) GeofenceQueryBuilder {
query.searchOpts.Cursor = &cursor
return query
}
// Limit can be used to limit the number of objects returned for a single search request.
func (query GeofenceQueryBuilder) Limit(limit int) GeofenceQueryBuilder {
query.searchOpts.Limit = &limit
return query
}
// Sparse will distribute the results of a search evenly across the requested area.
func (query GeofenceQueryBuilder) Sparse(sparse int) GeofenceQueryBuilder {
query.searchOpts.Sparse = &sparse
return query
}
// Where allows for filtering out results based on field values.
func (query GeofenceQueryBuilder) Where(field string, min, max float64) GeofenceQueryBuilder {
query.searchOpts.Where = append(query.searchOpts.Where, whereOpt{
Field: field,
Min: min,
Max: max,
})
return query
}
// Wherein is similar to Where except that it checks whether the object’s field value is in a given list.
func (query GeofenceQueryBuilder) Wherein(field string, values ...float64) GeofenceQueryBuilder {
query.searchOpts.Wherein = append(query.searchOpts.Wherein, whereinOpt{
Field: field,
Values: values,
})
return query
}
// WhereEval similar to WHERE except that matching decision is made by Lua script
// For example:
// 'nearby fleet whereeval "return FIELDS.wheels > ARGV[1] or (FIELDS.length * FIELDS.width) > ARGV[2]" 2 8 120 point 33.462 -112.268 6000'
// will return only the objects in the fleet collection that are within the 6km radius
// and have a field named wheels that is above 8, or have length and width whose product is greater than 120.
// Multiple WHEREEVALs are concatenated as and clauses. See EVAL command for more details.
// Note that, unlike the EVAL command, WHEREVAL Lua environment (1) does not have KEYS global,
// and (2) has the FIELDS global with the Lua table of the iterated object’s fields.
func (query GeofenceQueryBuilder) WhereEval(script string, args ...string) GeofenceQueryBuilder {
query.searchOpts.WhereEval = append(query.searchOpts.WhereEval, whereEvalOpt{
Name: script,
Args: args,
})
return query
}
// WhereEvalSHA similar to WHERE except that matching decision is made by Lua script
// For example:
// 'nearby fleet whereeval "return FIELDS.wheels > ARGV[1] or (FIELDS.length * FIELDS.width) > ARGV[2]" 2 8 120 point 33.462 -112.268 6000'
// will return only the objects in the fleet collection that are within the 6km radius
// and have a field named wheels that is above 8, or have length and width whose product is greater than 120.
// Multiple WHEREEVALs are concatenated as and clauses. See EVAL command for more details.
// Note that, unlike the EVAL command, WHEREVAL Lua environment (1) does not have KEYS global,
// and (2) has the FIELDS global with the Lua table of the iterated object’s fields.
func (query GeofenceQueryBuilder) WhereEvalSHA(sha string, args ...string) GeofenceQueryBuilder {
query.searchOpts.WhereEval = append(query.searchOpts.WhereEval, whereEvalOpt{
Name: sha,
IsSHA: true,
Args: args,
})
return query
}
// Match is similar to WHERE except that it works on the object id instead of fields.
// There can be multiple MATCH options in a single search.
// The MATCH value is a simple glob pattern.
func (query GeofenceQueryBuilder) Match(pattern string) GeofenceQueryBuilder {
query.searchOpts.Match = append(query.searchOpts.Match, pattern)
return query
}
// Format set response format.
func (query GeofenceQueryBuilder) Format(fmt OutputFormat) GeofenceQueryBuilder {
query.outputFormat = &fmt
return query
}