ustate-client 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +44 -5
- data/lib/ustate/query/and.rb +5 -1
- data/lib/ustate/query/approximately.rb +5 -1
- data/lib/ustate/query/ast.rb +8 -1
- data/lib/ustate/query/equals.rb +5 -1
- data/lib/ustate/query/false.rb +10 -0
- data/lib/ustate/query/greater.rb +16 -0
- data/lib/ustate/query/greater_equal.rb +16 -0
- data/lib/ustate/query/less.rb +16 -0
- data/lib/ustate/query/less_equal.rb +16 -0
- data/lib/ustate/query/node.rb +15 -0
- data/lib/ustate/query/not.rb +5 -1
- data/lib/ustate/query/not_equals.rb +5 -1
- data/lib/ustate/query/or.rb +5 -1
- data/lib/ustate/query/true.rb +10 -0
- data/lib/ustate/query_string.rb +588 -40
- data/lib/ustate/query_string.treetop +99 -7
- data/lib/ustate/reaper.rb +126 -0
- data/lib/ustate/server.rb +4 -0
- data/lib/ustate/server/index.rb +9 -36
- data/lib/ustate/version.rb +1 -1
- metadata +43 -33
data/README.markdown
CHANGED
@@ -56,6 +56,8 @@ For the dashboard:
|
|
56
56
|
|
57
57
|
gem install sinatra thin erubis sass
|
58
58
|
|
59
|
+
We run UState from Upstart. An example job is in docs/upstart.conf.
|
60
|
+
|
59
61
|
Demo
|
60
62
|
====
|
61
63
|
|
@@ -79,6 +81,29 @@ The server loads a file in the working directory named config.rb. Override with
|
|
79
81
|
--config-file. Its contents are instance-evaled in the context of the current
|
80
82
|
server. You can use this to extend ustate with additional behavior.
|
81
83
|
|
84
|
+
Expiring States
|
85
|
+
---------------
|
86
|
+
|
87
|
+
The reaper periodically kills states matching queries which are too old. It
|
88
|
+
will ensure that any state matching a query will be present for *at least* that
|
89
|
+
many seconds. For instance:
|
90
|
+
|
91
|
+
# States expire after 10 seconds
|
92
|
+
reaper.default = 10
|
93
|
+
|
94
|
+
# Except for daily stats, which last 2 days
|
95
|
+
reaper.reap 'service =~ "%daily%"', 2 * 24 * 3600
|
96
|
+
|
97
|
+
# We need to know RIGHT AWAY if the fridge fails to check in.
|
98
|
+
reaper.reap 'host = "fridge"', 1
|
99
|
+
|
100
|
+
In this configuration, daily updates from host fridge will stay around for 2
|
101
|
+
days, everything not on the fridge expires after 10 seconds, and other fridge
|
102
|
+
updates are kept for only one second.
|
103
|
+
|
104
|
+
Note that the reaper does some query recomposition which can lead to
|
105
|
+
inefficient patterns. Writing an optimizer is on my list.
|
106
|
+
|
82
107
|
Email
|
83
108
|
-----
|
84
109
|
|
@@ -138,7 +163,7 @@ config.rb:
|
|
138
163
|
|
139
164
|
# And also include the disk use on all nodes
|
140
165
|
graphite.graph 'service = "disk"'
|
141
|
-
|
166
|
+
|
142
167
|
Custom hooks
|
143
168
|
------------
|
144
169
|
|
@@ -215,6 +240,9 @@ out states corresponding to any query: see lib/ustate/dash/helper/renderer.rb.
|
|
215
240
|
The way I figure, you're almost certainly going to want to write your own, so
|
216
241
|
I'm going to give you the tools you need, and get out of your way.
|
217
242
|
|
243
|
+
An example config.rb, additional controllers, views, and public directory are
|
244
|
+
all in doc/dash. Should give you ideas for extending the dashboard for your own needs.
|
245
|
+
|
218
246
|
Protocol
|
219
247
|
========
|
220
248
|
|
@@ -229,8 +257,17 @@ success boolean in the Message.
|
|
229
257
|
You can also query states using a very basic expression language. The grammar is specified as a Parsable Expression Grammar in query_string.treetop. Examples include:
|
230
258
|
|
231
259
|
state = "ok"
|
260
|
+
|
232
261
|
(service =~ "disk%") or (state == "critical" and host =~ "%.trioptimum.com")
|
233
262
|
|
263
|
+
metric_f > 2.0 and not host = "tau ceti 5"
|
264
|
+
|
265
|
+
# All states
|
266
|
+
true
|
267
|
+
|
268
|
+
# No states
|
269
|
+
false
|
270
|
+
|
234
271
|
Search queries will return a message with repeated States matching that expression. An null expression will return no states.
|
235
272
|
|
236
273
|
Performance
|
@@ -240,11 +277,13 @@ On a macbook pro 8,3, I see >1300 queries/sec or >1200 inserts/sec. The client i
|
|
240
277
|
|
241
278
|
For large installations, I plan to implement a selective forwarder. Local ustate servers can accept high volumes of states from a small set of nodes, and forward updates at a larger granularity to supervisors, and so forth, in a tree. The query language should be able to support proxying requests to the most recent source of a state, so very large sets of services can be maintained at high granularity.
|
242
279
|
|
243
|
-
|
280
|
+
Future directions
|
244
281
|
=====
|
245
282
|
|
246
|
-
|
247
|
-
|
248
|
-
|
283
|
+
Several people have mentioned wanting to query historical states; to replay the events in ustate over time. There are some difficulties here; notably that compressing hundreds of millions of states can make it a little tricky to query states over the entire dataset. If we restrict ourselves to specific time ranges, storing sequential states as protocol buffers compressed with snappy could work, especially if only *state* changes are written. Storing only state deltas might work as well.
|
284
|
+
|
285
|
+
It'd be interesting to subscribe to states matching a query and receive states pushed to you as soon as they change.
|
286
|
+
|
287
|
+
Should be easy to add a UDP acceptor for states as well. Have to figure out eventmachine with multiple backends.
|
249
288
|
|
250
289
|
When the protocol and architecture are finalized, I plan to reimplement the server in a faster language.
|
data/lib/ustate/query/and.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class UState::Query
|
2
|
-
class Approximately
|
2
|
+
class Approximately < Node
|
3
3
|
def initialize(field, value)
|
4
4
|
@field = field
|
5
5
|
@value = case value
|
@@ -20,5 +20,9 @@ class UState::Query
|
|
20
20
|
def ===(state)
|
21
21
|
@value === state.send(@field)
|
22
22
|
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
inspect_helper @field, @value
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
data/lib/ustate/query/ast.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
+
require 'ustate/query/node'
|
1
2
|
require 'ustate/query/and'
|
2
3
|
require 'ustate/query/approximately'
|
3
4
|
require 'ustate/query/equals'
|
4
|
-
require 'ustate/query/
|
5
|
+
require 'ustate/query/false'
|
6
|
+
require 'ustate/query/greater'
|
7
|
+
require 'ustate/query/greater_equal'
|
8
|
+
require 'ustate/query/less'
|
9
|
+
require 'ustate/query/less_equal'
|
5
10
|
require 'ustate/query/not'
|
11
|
+
require 'ustate/query/not_equals'
|
6
12
|
require 'ustate/query/or'
|
13
|
+
require 'ustate/query/true'
|
data/lib/ustate/query/equals.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class UState::Query
|
2
|
-
class Equals
|
2
|
+
class Equals < Node
|
3
3
|
def initialize(field, value)
|
4
4
|
@field = field
|
5
5
|
@value = value
|
@@ -8,5 +8,9 @@ class UState::Query
|
|
8
8
|
def ===(state)
|
9
9
|
state.send(@field) == @value
|
10
10
|
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
inspect_helper @field, @value
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class UState::Query
|
2
|
+
class Greater < Node
|
3
|
+
def initialize(field, value)
|
4
|
+
@field = field
|
5
|
+
@value = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def ===(state)
|
9
|
+
x = state.send(@field) and x > @value
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
inspect_helper @field, @value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class UState::Query
|
2
|
+
class GreaterEqual < Node
|
3
|
+
def initialize(field, value)
|
4
|
+
@field = field
|
5
|
+
@value = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def ===(state)
|
9
|
+
x = state.send(@field) and x >= @value
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
inspect_helper @field, @value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class UState::Query
|
2
|
+
class LessEqual < Node
|
3
|
+
def initialize(field, value)
|
4
|
+
@field = field
|
5
|
+
@value = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def ===(state)
|
9
|
+
x = state.send(@field) and x <= @value
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
inspect_helper @field, @value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class UState::Query
|
2
|
+
class Node
|
3
|
+
def indent(s, d = 1)
|
4
|
+
(" " * d) + s.gsub("\n", "\n" + (" " * d))
|
5
|
+
end
|
6
|
+
|
7
|
+
def inspect_helper(*kids)
|
8
|
+
"#{self.class}\n#{indent kids.map { |k| k.inspect }.join("\n")}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def inspect
|
12
|
+
inspect_helper
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/ustate/query/not.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class UState::Query
|
2
|
-
class NotEquals
|
2
|
+
class NotEquals < Node
|
3
3
|
def initialize(field, value)
|
4
4
|
@field = field
|
5
5
|
@value = value
|
@@ -8,5 +8,9 @@ class UState::Query
|
|
8
8
|
def ===(state)
|
9
9
|
state.send(@field) != @value
|
10
10
|
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
inspect_helper @field, @value
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
data/lib/ustate/query/or.rb
CHANGED
data/lib/ustate/query_string.rb
CHANGED
@@ -125,7 +125,7 @@ module UState
|
|
125
125
|
elements[2]
|
126
126
|
end
|
127
127
|
|
128
|
-
def
|
128
|
+
def p
|
129
129
|
elements[3]
|
130
130
|
end
|
131
131
|
end
|
@@ -142,13 +142,13 @@ module UState
|
|
142
142
|
|
143
143
|
module And2
|
144
144
|
def query
|
145
|
-
rest.elements.map { |x| x.
|
145
|
+
rest.elements.map { |x| x.p }.inject(first.query) do |a, sub|
|
146
146
|
Query::And.new a, sub.query
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
150
|
def sql
|
151
|
-
rest.elements.map { |x| x.
|
151
|
+
rest.elements.map { |x| x.p }.
|
152
152
|
inject(first.sql) do |a, sub|
|
153
153
|
a & sub.sql
|
154
154
|
end
|
@@ -167,47 +167,71 @@ module UState
|
|
167
167
|
end
|
168
168
|
|
169
169
|
i0, s0 = index, []
|
170
|
-
|
170
|
+
i1 = index
|
171
|
+
r2 = _nt_not
|
172
|
+
if r2
|
173
|
+
r1 = r2
|
174
|
+
else
|
175
|
+
r3 = _nt_primary
|
176
|
+
if r3
|
177
|
+
r1 = r3
|
178
|
+
else
|
179
|
+
@index = i1
|
180
|
+
r1 = nil
|
181
|
+
end
|
182
|
+
end
|
171
183
|
s0 << r1
|
172
184
|
if r1
|
173
|
-
|
185
|
+
s4, i4 = [], index
|
174
186
|
loop do
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
if
|
187
|
+
i5, s5 = index, []
|
188
|
+
r6 = _nt_space
|
189
|
+
s5 << r6
|
190
|
+
if r6
|
179
191
|
if has_terminal?('and', false, index)
|
180
|
-
|
192
|
+
r7 = instantiate_node(SyntaxNode,input, index...(index + 3))
|
181
193
|
@index += 3
|
182
194
|
else
|
183
195
|
terminal_parse_failure('and')
|
184
|
-
|
196
|
+
r7 = nil
|
185
197
|
end
|
186
|
-
|
187
|
-
if
|
188
|
-
|
189
|
-
|
190
|
-
if
|
191
|
-
|
192
|
-
|
198
|
+
s5 << r7
|
199
|
+
if r7
|
200
|
+
r8 = _nt_space
|
201
|
+
s5 << r8
|
202
|
+
if r8
|
203
|
+
i9 = index
|
204
|
+
r10 = _nt_not
|
205
|
+
if r10
|
206
|
+
r9 = r10
|
207
|
+
else
|
208
|
+
r11 = _nt_primary
|
209
|
+
if r11
|
210
|
+
r9 = r11
|
211
|
+
else
|
212
|
+
@index = i9
|
213
|
+
r9 = nil
|
214
|
+
end
|
215
|
+
end
|
216
|
+
s5 << r9
|
193
217
|
end
|
194
218
|
end
|
195
219
|
end
|
196
|
-
if
|
197
|
-
|
198
|
-
|
220
|
+
if s5.last
|
221
|
+
r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
|
222
|
+
r5.extend(And0)
|
199
223
|
else
|
200
|
-
@index =
|
201
|
-
|
224
|
+
@index = i5
|
225
|
+
r5 = nil
|
202
226
|
end
|
203
|
-
if
|
204
|
-
|
227
|
+
if r5
|
228
|
+
s4 << r5
|
205
229
|
else
|
206
230
|
break
|
207
231
|
end
|
208
232
|
end
|
209
|
-
|
210
|
-
s0 <<
|
233
|
+
r4 = instantiate_node(SyntaxNode,input, i4...index, s4)
|
234
|
+
s0 << r4
|
211
235
|
end
|
212
236
|
if s0.last
|
213
237
|
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
@@ -223,6 +247,80 @@ module UState
|
|
223
247
|
r0
|
224
248
|
end
|
225
249
|
|
250
|
+
module Not0
|
251
|
+
def space
|
252
|
+
elements[1]
|
253
|
+
end
|
254
|
+
|
255
|
+
def p
|
256
|
+
elements[2]
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
module Not1
|
261
|
+
def query
|
262
|
+
Query::Not.new p.query
|
263
|
+
end
|
264
|
+
|
265
|
+
def sql
|
266
|
+
~ p.sql
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def _nt_not
|
271
|
+
start_index = index
|
272
|
+
if node_cache[:not].has_key?(index)
|
273
|
+
cached = node_cache[:not][index]
|
274
|
+
if cached
|
275
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
276
|
+
@index = cached.interval.end
|
277
|
+
end
|
278
|
+
return cached
|
279
|
+
end
|
280
|
+
|
281
|
+
i0, s0 = index, []
|
282
|
+
if has_terminal?('not', false, index)
|
283
|
+
r1 = instantiate_node(SyntaxNode,input, index...(index + 3))
|
284
|
+
@index += 3
|
285
|
+
else
|
286
|
+
terminal_parse_failure('not')
|
287
|
+
r1 = nil
|
288
|
+
end
|
289
|
+
s0 << r1
|
290
|
+
if r1
|
291
|
+
r2 = _nt_space
|
292
|
+
s0 << r2
|
293
|
+
if r2
|
294
|
+
i3 = index
|
295
|
+
r4 = _nt_not
|
296
|
+
if r4
|
297
|
+
r3 = r4
|
298
|
+
else
|
299
|
+
r5 = _nt_primary
|
300
|
+
if r5
|
301
|
+
r3 = r5
|
302
|
+
else
|
303
|
+
@index = i3
|
304
|
+
r3 = nil
|
305
|
+
end
|
306
|
+
end
|
307
|
+
s0 << r3
|
308
|
+
end
|
309
|
+
end
|
310
|
+
if s0.last
|
311
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
312
|
+
r0.extend(Not0)
|
313
|
+
r0.extend(Not1)
|
314
|
+
else
|
315
|
+
@index = i0
|
316
|
+
r0 = nil
|
317
|
+
end
|
318
|
+
|
319
|
+
node_cache[:not][start_index] = r0
|
320
|
+
|
321
|
+
r0
|
322
|
+
end
|
323
|
+
|
226
324
|
module Primary0
|
227
325
|
def x
|
228
326
|
elements[2]
|
@@ -330,20 +428,50 @@ module UState
|
|
330
428
|
end
|
331
429
|
|
332
430
|
i0 = index
|
333
|
-
r1 =
|
431
|
+
r1 = _nt_true
|
334
432
|
if r1
|
335
433
|
r0 = r1
|
336
434
|
else
|
337
|
-
r2 =
|
435
|
+
r2 = _nt_false
|
338
436
|
if r2
|
339
437
|
r0 = r2
|
340
438
|
else
|
341
|
-
r3 =
|
439
|
+
r3 = _nt_less_equal
|
342
440
|
if r3
|
343
441
|
r0 = r3
|
344
442
|
else
|
345
|
-
|
346
|
-
|
443
|
+
r4 = _nt_less
|
444
|
+
if r4
|
445
|
+
r0 = r4
|
446
|
+
else
|
447
|
+
r5 = _nt_greater_equal
|
448
|
+
if r5
|
449
|
+
r0 = r5
|
450
|
+
else
|
451
|
+
r6 = _nt_greater
|
452
|
+
if r6
|
453
|
+
r0 = r6
|
454
|
+
else
|
455
|
+
r7 = _nt_equals
|
456
|
+
if r7
|
457
|
+
r0 = r7
|
458
|
+
else
|
459
|
+
r8 = _nt_not_equals
|
460
|
+
if r8
|
461
|
+
r0 = r8
|
462
|
+
else
|
463
|
+
r9 = _nt_approximately
|
464
|
+
if r9
|
465
|
+
r0 = r9
|
466
|
+
else
|
467
|
+
@index = i0
|
468
|
+
r0 = nil
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
end
|
347
475
|
end
|
348
476
|
end
|
349
477
|
end
|
@@ -433,6 +561,326 @@ module UState
|
|
433
561
|
r0
|
434
562
|
end
|
435
563
|
|
564
|
+
module LessEqual0
|
565
|
+
def field
|
566
|
+
elements[0]
|
567
|
+
end
|
568
|
+
|
569
|
+
def value
|
570
|
+
elements[4]
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
module LessEqual1
|
575
|
+
def query
|
576
|
+
Query::LessEqual.new field.sql, value.sql
|
577
|
+
end
|
578
|
+
|
579
|
+
def sql
|
580
|
+
Sequel::SQL::BooleanExpression.new(:<=, field.sql, value.sql)
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
def _nt_less_equal
|
585
|
+
start_index = index
|
586
|
+
if node_cache[:less_equal].has_key?(index)
|
587
|
+
cached = node_cache[:less_equal][index]
|
588
|
+
if cached
|
589
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
590
|
+
@index = cached.interval.end
|
591
|
+
end
|
592
|
+
return cached
|
593
|
+
end
|
594
|
+
|
595
|
+
i0, s0 = index, []
|
596
|
+
r1 = _nt_field
|
597
|
+
s0 << r1
|
598
|
+
if r1
|
599
|
+
r3 = _nt_space
|
600
|
+
if r3
|
601
|
+
r2 = r3
|
602
|
+
else
|
603
|
+
r2 = instantiate_node(SyntaxNode,input, index...index)
|
604
|
+
end
|
605
|
+
s0 << r2
|
606
|
+
if r2
|
607
|
+
if has_terminal?('<=', false, index)
|
608
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 2))
|
609
|
+
@index += 2
|
610
|
+
else
|
611
|
+
terminal_parse_failure('<=')
|
612
|
+
r4 = nil
|
613
|
+
end
|
614
|
+
s0 << r4
|
615
|
+
if r4
|
616
|
+
r6 = _nt_space
|
617
|
+
if r6
|
618
|
+
r5 = r6
|
619
|
+
else
|
620
|
+
r5 = instantiate_node(SyntaxNode,input, index...index)
|
621
|
+
end
|
622
|
+
s0 << r5
|
623
|
+
if r5
|
624
|
+
r7 = _nt_value
|
625
|
+
s0 << r7
|
626
|
+
end
|
627
|
+
end
|
628
|
+
end
|
629
|
+
end
|
630
|
+
if s0.last
|
631
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
632
|
+
r0.extend(LessEqual0)
|
633
|
+
r0.extend(LessEqual1)
|
634
|
+
else
|
635
|
+
@index = i0
|
636
|
+
r0 = nil
|
637
|
+
end
|
638
|
+
|
639
|
+
node_cache[:less_equal][start_index] = r0
|
640
|
+
|
641
|
+
r0
|
642
|
+
end
|
643
|
+
|
644
|
+
module Less0
|
645
|
+
def field
|
646
|
+
elements[0]
|
647
|
+
end
|
648
|
+
|
649
|
+
def value
|
650
|
+
elements[4]
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
module Less1
|
655
|
+
def query
|
656
|
+
Query::Less.new field.sql, value.sql
|
657
|
+
end
|
658
|
+
|
659
|
+
def sql
|
660
|
+
Sequel::SQL::BooleanExpression.new(:<, field.sql, value.sql)
|
661
|
+
end
|
662
|
+
end
|
663
|
+
|
664
|
+
def _nt_less
|
665
|
+
start_index = index
|
666
|
+
if node_cache[:less].has_key?(index)
|
667
|
+
cached = node_cache[:less][index]
|
668
|
+
if cached
|
669
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
670
|
+
@index = cached.interval.end
|
671
|
+
end
|
672
|
+
return cached
|
673
|
+
end
|
674
|
+
|
675
|
+
i0, s0 = index, []
|
676
|
+
r1 = _nt_field
|
677
|
+
s0 << r1
|
678
|
+
if r1
|
679
|
+
r3 = _nt_space
|
680
|
+
if r3
|
681
|
+
r2 = r3
|
682
|
+
else
|
683
|
+
r2 = instantiate_node(SyntaxNode,input, index...index)
|
684
|
+
end
|
685
|
+
s0 << r2
|
686
|
+
if r2
|
687
|
+
if has_terminal?('<', false, index)
|
688
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
689
|
+
@index += 1
|
690
|
+
else
|
691
|
+
terminal_parse_failure('<')
|
692
|
+
r4 = nil
|
693
|
+
end
|
694
|
+
s0 << r4
|
695
|
+
if r4
|
696
|
+
r6 = _nt_space
|
697
|
+
if r6
|
698
|
+
r5 = r6
|
699
|
+
else
|
700
|
+
r5 = instantiate_node(SyntaxNode,input, index...index)
|
701
|
+
end
|
702
|
+
s0 << r5
|
703
|
+
if r5
|
704
|
+
r7 = _nt_value
|
705
|
+
s0 << r7
|
706
|
+
end
|
707
|
+
end
|
708
|
+
end
|
709
|
+
end
|
710
|
+
if s0.last
|
711
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
712
|
+
r0.extend(Less0)
|
713
|
+
r0.extend(Less1)
|
714
|
+
else
|
715
|
+
@index = i0
|
716
|
+
r0 = nil
|
717
|
+
end
|
718
|
+
|
719
|
+
node_cache[:less][start_index] = r0
|
720
|
+
|
721
|
+
r0
|
722
|
+
end
|
723
|
+
|
724
|
+
module GreaterEqual0
|
725
|
+
def field
|
726
|
+
elements[0]
|
727
|
+
end
|
728
|
+
|
729
|
+
def value
|
730
|
+
elements[4]
|
731
|
+
end
|
732
|
+
end
|
733
|
+
|
734
|
+
module GreaterEqual1
|
735
|
+
def query
|
736
|
+
Query::GreaterEqual.new field.sql, value.sql
|
737
|
+
end
|
738
|
+
|
739
|
+
def sql
|
740
|
+
Sequel::SQL::BooleanExpression.new(:>=, field.sql, value.sql)
|
741
|
+
end
|
742
|
+
end
|
743
|
+
|
744
|
+
def _nt_greater_equal
|
745
|
+
start_index = index
|
746
|
+
if node_cache[:greater_equal].has_key?(index)
|
747
|
+
cached = node_cache[:greater_equal][index]
|
748
|
+
if cached
|
749
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
750
|
+
@index = cached.interval.end
|
751
|
+
end
|
752
|
+
return cached
|
753
|
+
end
|
754
|
+
|
755
|
+
i0, s0 = index, []
|
756
|
+
r1 = _nt_field
|
757
|
+
s0 << r1
|
758
|
+
if r1
|
759
|
+
r3 = _nt_space
|
760
|
+
if r3
|
761
|
+
r2 = r3
|
762
|
+
else
|
763
|
+
r2 = instantiate_node(SyntaxNode,input, index...index)
|
764
|
+
end
|
765
|
+
s0 << r2
|
766
|
+
if r2
|
767
|
+
if has_terminal?('>=', false, index)
|
768
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 2))
|
769
|
+
@index += 2
|
770
|
+
else
|
771
|
+
terminal_parse_failure('>=')
|
772
|
+
r4 = nil
|
773
|
+
end
|
774
|
+
s0 << r4
|
775
|
+
if r4
|
776
|
+
r6 = _nt_space
|
777
|
+
if r6
|
778
|
+
r5 = r6
|
779
|
+
else
|
780
|
+
r5 = instantiate_node(SyntaxNode,input, index...index)
|
781
|
+
end
|
782
|
+
s0 << r5
|
783
|
+
if r5
|
784
|
+
r7 = _nt_value
|
785
|
+
s0 << r7
|
786
|
+
end
|
787
|
+
end
|
788
|
+
end
|
789
|
+
end
|
790
|
+
if s0.last
|
791
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
792
|
+
r0.extend(GreaterEqual0)
|
793
|
+
r0.extend(GreaterEqual1)
|
794
|
+
else
|
795
|
+
@index = i0
|
796
|
+
r0 = nil
|
797
|
+
end
|
798
|
+
|
799
|
+
node_cache[:greater_equal][start_index] = r0
|
800
|
+
|
801
|
+
r0
|
802
|
+
end
|
803
|
+
|
804
|
+
module Greater0
|
805
|
+
def field
|
806
|
+
elements[0]
|
807
|
+
end
|
808
|
+
|
809
|
+
def value
|
810
|
+
elements[4]
|
811
|
+
end
|
812
|
+
end
|
813
|
+
|
814
|
+
module Greater1
|
815
|
+
def query
|
816
|
+
Query::Greater.new field.sql, value.sql
|
817
|
+
end
|
818
|
+
|
819
|
+
def sql
|
820
|
+
Sequel::SQL::BooleanExpression.new(:>, field.sql, value.sql)
|
821
|
+
end
|
822
|
+
end
|
823
|
+
|
824
|
+
def _nt_greater
|
825
|
+
start_index = index
|
826
|
+
if node_cache[:greater].has_key?(index)
|
827
|
+
cached = node_cache[:greater][index]
|
828
|
+
if cached
|
829
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
830
|
+
@index = cached.interval.end
|
831
|
+
end
|
832
|
+
return cached
|
833
|
+
end
|
834
|
+
|
835
|
+
i0, s0 = index, []
|
836
|
+
r1 = _nt_field
|
837
|
+
s0 << r1
|
838
|
+
if r1
|
839
|
+
r3 = _nt_space
|
840
|
+
if r3
|
841
|
+
r2 = r3
|
842
|
+
else
|
843
|
+
r2 = instantiate_node(SyntaxNode,input, index...index)
|
844
|
+
end
|
845
|
+
s0 << r2
|
846
|
+
if r2
|
847
|
+
if has_terminal?('>', false, index)
|
848
|
+
r4 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
849
|
+
@index += 1
|
850
|
+
else
|
851
|
+
terminal_parse_failure('>')
|
852
|
+
r4 = nil
|
853
|
+
end
|
854
|
+
s0 << r4
|
855
|
+
if r4
|
856
|
+
r6 = _nt_space
|
857
|
+
if r6
|
858
|
+
r5 = r6
|
859
|
+
else
|
860
|
+
r5 = instantiate_node(SyntaxNode,input, index...index)
|
861
|
+
end
|
862
|
+
s0 << r5
|
863
|
+
if r5
|
864
|
+
r7 = _nt_value
|
865
|
+
s0 << r7
|
866
|
+
end
|
867
|
+
end
|
868
|
+
end
|
869
|
+
end
|
870
|
+
if s0.last
|
871
|
+
r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
|
872
|
+
r0.extend(Greater0)
|
873
|
+
r0.extend(Greater1)
|
874
|
+
else
|
875
|
+
@index = i0
|
876
|
+
r0 = nil
|
877
|
+
end
|
878
|
+
|
879
|
+
node_cache[:greater][start_index] = r0
|
880
|
+
|
881
|
+
r0
|
882
|
+
end
|
883
|
+
|
436
884
|
module NotEquals0
|
437
885
|
def field
|
438
886
|
elements[0]
|
@@ -623,24 +1071,34 @@ module UState
|
|
623
1071
|
end
|
624
1072
|
|
625
1073
|
i0 = index
|
626
|
-
r1 =
|
1074
|
+
r1 = _nt_true
|
627
1075
|
if r1
|
628
1076
|
r0 = r1
|
629
1077
|
else
|
630
|
-
r2 =
|
1078
|
+
r2 = _nt_false
|
631
1079
|
if r2
|
632
1080
|
r0 = r2
|
633
1081
|
else
|
634
|
-
r3 =
|
1082
|
+
r3 = _nt_double_quoted_string
|
635
1083
|
if r3
|
636
1084
|
r0 = r3
|
637
1085
|
else
|
638
|
-
r4 =
|
1086
|
+
r4 = _nt_float
|
639
1087
|
if r4
|
640
1088
|
r0 = r4
|
641
1089
|
else
|
642
|
-
|
643
|
-
|
1090
|
+
r5 = _nt_integer
|
1091
|
+
if r5
|
1092
|
+
r0 = r5
|
1093
|
+
else
|
1094
|
+
r6 = _nt_null
|
1095
|
+
if r6
|
1096
|
+
r0 = r6
|
1097
|
+
else
|
1098
|
+
@index = i0
|
1099
|
+
r0 = nil
|
1100
|
+
end
|
1101
|
+
end
|
644
1102
|
end
|
645
1103
|
end
|
646
1104
|
end
|
@@ -651,6 +1109,84 @@ module UState
|
|
651
1109
|
r0
|
652
1110
|
end
|
653
1111
|
|
1112
|
+
module True0
|
1113
|
+
def query
|
1114
|
+
Query::True.new
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
def ruby_value
|
1118
|
+
true
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
def sql
|
1122
|
+
Sequel::TRUE
|
1123
|
+
end
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
def _nt_true
|
1127
|
+
start_index = index
|
1128
|
+
if node_cache[:true].has_key?(index)
|
1129
|
+
cached = node_cache[:true][index]
|
1130
|
+
if cached
|
1131
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1132
|
+
@index = cached.interval.end
|
1133
|
+
end
|
1134
|
+
return cached
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
if has_terminal?('true', false, index)
|
1138
|
+
r0 = instantiate_node(SyntaxNode,input, index...(index + 4))
|
1139
|
+
r0.extend(True0)
|
1140
|
+
@index += 4
|
1141
|
+
else
|
1142
|
+
terminal_parse_failure('true')
|
1143
|
+
r0 = nil
|
1144
|
+
end
|
1145
|
+
|
1146
|
+
node_cache[:true][start_index] = r0
|
1147
|
+
|
1148
|
+
r0
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
module False0
|
1152
|
+
def query
|
1153
|
+
Query::False.new
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
def ruby_value
|
1157
|
+
false
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
def sql
|
1161
|
+
Sequel::FALSE
|
1162
|
+
end
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
def _nt_false
|
1166
|
+
start_index = index
|
1167
|
+
if node_cache[:false].has_key?(index)
|
1168
|
+
cached = node_cache[:false][index]
|
1169
|
+
if cached
|
1170
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
1171
|
+
@index = cached.interval.end
|
1172
|
+
end
|
1173
|
+
return cached
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
if has_terminal?('false', false, index)
|
1177
|
+
r0 = instantiate_node(SyntaxNode,input, index...(index + 5))
|
1178
|
+
r0.extend(False0)
|
1179
|
+
@index += 5
|
1180
|
+
else
|
1181
|
+
terminal_parse_failure('false')
|
1182
|
+
r0 = nil
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
node_cache[:false][start_index] = r0
|
1186
|
+
|
1187
|
+
r0
|
1188
|
+
end
|
1189
|
+
|
654
1190
|
module Integer0
|
655
1191
|
end
|
656
1192
|
|
@@ -902,8 +1438,20 @@ module UState
|
|
902
1438
|
r0 = r5
|
903
1439
|
r0.extend(Field0)
|
904
1440
|
else
|
905
|
-
|
906
|
-
|
1441
|
+
if has_terminal?("time", false, index)
|
1442
|
+
r6 = instantiate_node(SyntaxNode,input, index...(index + 4))
|
1443
|
+
@index += 4
|
1444
|
+
else
|
1445
|
+
terminal_parse_failure("time")
|
1446
|
+
r6 = nil
|
1447
|
+
end
|
1448
|
+
if r6
|
1449
|
+
r0 = r6
|
1450
|
+
r0.extend(Field0)
|
1451
|
+
else
|
1452
|
+
@index = i0
|
1453
|
+
r0 = nil
|
1454
|
+
end
|
907
1455
|
end
|
908
1456
|
end
|
909
1457
|
end
|