norikra 1.1.2-java → 1.2.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Changes.md +4 -0
- data/Gemfile +4 -0
- data/README.md +3 -6
- data/lib/norikra/cli.rb +54 -54
- data/lib/norikra/engine.rb +91 -44
- data/lib/norikra/field.rb +12 -7
- data/lib/norikra/fieldset.rb +26 -13
- data/lib/norikra/listener.rb +192 -61
- data/lib/norikra/logger.rb +34 -10
- data/lib/norikra/output_pool.rb +1 -1
- data/lib/norikra/query/ast.rb +240 -20
- data/lib/norikra/query.rb +103 -46
- data/lib/norikra/rpc/handler.rb +3 -3
- data/lib/norikra/rpc/http.rb +1 -1
- data/lib/norikra/server.rb +34 -28
- data/lib/norikra/stats.rb +3 -3
- data/lib/norikra/target.rb +1 -1
- data/lib/norikra/typedef.rb +22 -17
- data/lib/norikra/typedef_manager.rb +9 -6
- data/lib/norikra/udf.rb +6 -2
- data/lib/norikra/version.rb +1 -1
- data/lib/norikra/webui/api.rb +3 -3
- data/lib/norikra/webui/handler.rb +6 -6
- data/norikra.gemspec +0 -1
- data/script/{spec_server_pry → pry} +0 -24
- data/spec/field_spec.rb +14 -0
- data/spec/fieldset_spec.rb +111 -0
- data/spec/listener_spec.rb +64 -26
- data/spec/query_spec.rb +171 -25
- data/spec/spec_helper.rb +0 -46
- data/spec/typedef_manager_spec.rb +15 -9
- data/spec/typedef_spec.rb +11 -11
- metadata +3 -19
- data/lib/norikra/rpc/error.rb +0 -0
- data/lib/norikra/rubyudf.rb +0 -49
data/spec/listener_spec.rb
CHANGED
@@ -4,6 +4,19 @@ require_relative './spec_helper'
|
|
4
4
|
require 'json'
|
5
5
|
require 'norikra/listener'
|
6
6
|
|
7
|
+
class DummyEngine
|
8
|
+
attr_reader :events
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@events = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def send(target, events)
|
15
|
+
@events[target] ||= []
|
16
|
+
@events[target].push(*events)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
class DummyOutputPool
|
8
21
|
attr_reader :pool
|
9
22
|
|
@@ -18,17 +31,15 @@ class DummyOutputPool
|
|
18
31
|
end
|
19
32
|
end
|
20
33
|
|
21
|
-
describe Norikra::Listener do
|
34
|
+
describe Norikra::Listener::Base do
|
22
35
|
it 'should be initialized' do
|
23
|
-
dummy_pool = DummyOutputPool.new
|
24
36
|
statistics = {output: 0}
|
25
|
-
expect { Norikra::Listener.new('name', 'group',
|
37
|
+
expect { Norikra::Listener::Base.new('name', 'group', statistics) }.not_to raise_error
|
26
38
|
end
|
27
39
|
|
28
40
|
describe '#type_convert' do
|
29
|
-
dummy_pool = DummyOutputPool.new
|
30
41
|
statistics = {output: 0}
|
31
|
-
listener = Norikra::Listener.new('name', 'group',
|
42
|
+
listener = Norikra::Listener::Base.new('name', 'group', statistics)
|
32
43
|
|
33
44
|
it 'returns value itself for number, boolean and nil' do
|
34
45
|
val = 10001
|
@@ -104,10 +115,24 @@ describe Norikra::Listener do
|
|
104
115
|
end
|
105
116
|
end
|
106
117
|
|
118
|
+
### TODO: add specs of #start, #process_async, #push and default #update
|
119
|
+
### TODO: add norikra/listener_spec_helper.rb
|
120
|
+
end
|
121
|
+
|
122
|
+
describe Norikra::Listener::MemoryPool do
|
123
|
+
describe '.check' do
|
124
|
+
it 'always returns true' do
|
125
|
+
expect(Norikra::Listener::MemoryPool.check(nil)).to be_truthy
|
126
|
+
expect(Norikra::Listener::MemoryPool.check('')).to be_truthy
|
127
|
+
expect(Norikra::Listener::MemoryPool.check('FOO')).to be_truthy
|
128
|
+
expect(Norikra::Listener::MemoryPool.check('FOO()')).to be_truthy
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
107
132
|
describe '#update' do
|
108
|
-
dummy_pool = DummyOutputPool.new
|
109
133
|
statistics = {output: 0}
|
110
|
-
listener = Norikra::Listener.new('name', 'group',
|
134
|
+
listener = Norikra::Listener::MemoryPool.new('name', 'group', statistics)
|
135
|
+
listener.output_pool = dummy_pool = DummyOutputPool.new
|
111
136
|
|
112
137
|
it 'pushs events into pool, with current time' do
|
113
138
|
listener.update([{"n1" => 100, "s" => "string one"}, {"n1" => 101, "s" => "string two"}], [])
|
@@ -124,30 +149,35 @@ describe Norikra::Listener do
|
|
124
149
|
end
|
125
150
|
end
|
126
151
|
|
127
|
-
|
128
|
-
|
152
|
+
describe Norikra::Listener::Loopback do
|
153
|
+
describe '.check' do
|
154
|
+
it 'returns nil for nil group' do
|
155
|
+
expect(Norikra::Listener::Loopback.check(nil)).to be_nil
|
156
|
+
end
|
129
157
|
|
130
|
-
|
131
|
-
|
132
|
-
|
158
|
+
it 'returns nil for string group name without prefix' do
|
159
|
+
expect(Norikra::Listener::Loopback.check('a')).to be_nil
|
160
|
+
expect(Norikra::Listener::Loopback.check('group1')).to be_nil
|
161
|
+
expect(Norikra::Listener::Loopback.check('LOOPBACK')).to be_nil
|
162
|
+
end
|
133
163
|
|
134
|
-
|
135
|
-
|
136
|
-
|
164
|
+
it 'returns specified string as loopback target by parentheses' do
|
165
|
+
expect(Norikra::Listener::Loopback.check('LOOPBACK()')).to be_nil
|
166
|
+
expect(Norikra::Listener::Loopback.check('LOOPBACK(a)')).to eql('a')
|
167
|
+
expect(Norikra::Listener::Loopback.check('LOOPBACK(loopback_target)')).to eql('loopback_target')
|
168
|
+
expect(Norikra::Listener::Loopback.check('LOOPBACK(target name)')).to eql('target name') # should be invalid on 'open'
|
169
|
+
end
|
137
170
|
end
|
138
|
-
end
|
139
171
|
|
140
|
-
describe Norikra::LoopbackListener do
|
141
172
|
it 'should be initialized' do
|
142
|
-
dummy_engine = DummyEngine.new
|
143
173
|
statistics = {output: 0}
|
144
|
-
expect { Norikra::
|
174
|
+
expect { Norikra::Listener::Loopback.new('name', 'LOOPBACK(target1)', statistics) }.not_to raise_error
|
145
175
|
end
|
146
176
|
|
147
177
|
describe '#update' do
|
148
|
-
dummy_engine = DummyEngine.new
|
149
178
|
statistics = {output: 0}
|
150
|
-
listener = Norikra::
|
179
|
+
listener = Norikra::Listener::Loopback.new('name', 'LOOPBACK(target1)', statistics)
|
180
|
+
listener.engine = dummy_engine = DummyEngine.new
|
151
181
|
|
152
182
|
it 'sends events into engine with target name' do
|
153
183
|
listener.update([{"n1" => 100, "s" => "string one"}, {"n1" => 101, "s" => "string two"}], [])
|
@@ -163,17 +193,25 @@ describe Norikra::LoopbackListener do
|
|
163
193
|
end
|
164
194
|
end
|
165
195
|
|
166
|
-
describe Norikra::
|
196
|
+
describe Norikra::Listener::Stdout do
|
197
|
+
describe '.check' do
|
198
|
+
it 'returns true if group name is "STDOUT()"' do
|
199
|
+
expect(Norikra::Listener::Stdout.check(nil)).to be_falsy
|
200
|
+
expect(Norikra::Listener::Stdout.check("")).to be_falsy
|
201
|
+
expect(Norikra::Listener::Stdout.check("foo")).to be_falsy
|
202
|
+
expect(Norikra::Listener::Stdout.check("STDOUT")).to be_falsy
|
203
|
+
expect(Norikra::Listener::Stdout.check("STDOUT()")).to be_truthy
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
167
207
|
it 'should be initialized' do
|
168
|
-
dummy_engine = DummyEngine.new
|
169
208
|
statistics = {output: 0}
|
170
|
-
expect { Norikra::
|
209
|
+
expect { Norikra::Listener::Stdout.new('name', 'STDOUT()', statistics) }.not_to raise_error
|
171
210
|
end
|
172
211
|
|
173
212
|
describe '#update' do
|
174
|
-
dummy_engine = DummyEngine.new
|
175
213
|
statistics = {output: 0}
|
176
|
-
listener = Norikra::
|
214
|
+
listener = Norikra::Listener::Stdout.new('name', 'STDOUT()', statistics)
|
177
215
|
dummyio = StringIO.new
|
178
216
|
listener.instance_eval{ @stdout = dummyio }
|
179
217
|
|
data/spec/query_spec.rb
CHANGED
@@ -89,6 +89,73 @@ describe Norikra::Query do
|
|
89
89
|
expect(q.fields('TestTable')).to eql([])
|
90
90
|
expect(q.fields(nil)).to eql([])
|
91
91
|
|
92
|
+
expect(q.nullable_fields).to eql([])
|
93
|
+
expect(q.nullable_fields('TestTable')).to eql([])
|
94
|
+
expect(q.nullable_fields(nil)).to eql([])
|
95
|
+
|
96
|
+
expect(q.invalid?).to be_falsy
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'returns query instances collectly parsed, even if it has property' do
|
100
|
+
expression = 'SELECT rate(a.b) FROM TestTable output snapshot every 2 sec'
|
101
|
+
q = Norikra::Query.new(
|
102
|
+
:name => 'TestTable query1', :expression => expression
|
103
|
+
)
|
104
|
+
expect(q.name).to eql('TestTable query1')
|
105
|
+
expect(q.group).to be_nil
|
106
|
+
expect(q.expression).to eql(expression)
|
107
|
+
expect(q.targets).to eql(['TestTable'])
|
108
|
+
|
109
|
+
expect(q.fields).to eql(['a.b'])
|
110
|
+
expect(q.fields('TestTable')).to eql(['a.b'])
|
111
|
+
expect(q.fields(nil)).to eql([])
|
112
|
+
|
113
|
+
expect(q.nullable_fields).to eql([])
|
114
|
+
expect(q.nullable_fields('TestTable')).to eql([])
|
115
|
+
expect(q.nullable_fields(nil)).to eql([])
|
116
|
+
|
117
|
+
expect(q.invalid?).to be_falsy
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'returns query instances collectly parsed, with built-in NULLABLE()' do
|
121
|
+
expression = 'SELECT a, b, NULLABLE(c) FROM TestTable output snapshot every 2 sec'
|
122
|
+
q = Norikra::Query.new(
|
123
|
+
:name => 'TestTable query1', :expression => expression
|
124
|
+
)
|
125
|
+
expect(q.name).to eql('TestTable query1')
|
126
|
+
expect(q.group).to be_nil
|
127
|
+
expect(q.expression).to eql(expression)
|
128
|
+
expect(q.targets).to eql(['TestTable'])
|
129
|
+
|
130
|
+
expect(q.fields).to eql(['a', 'b', 'c'])
|
131
|
+
expect(q.fields('TestTable')).to eql(['a', 'b', 'c'])
|
132
|
+
expect(q.fields(nil)).to eql([])
|
133
|
+
|
134
|
+
expect(q.nullable_fields).to eql(['c'])
|
135
|
+
expect(q.nullable_fields('TestTable')).to eql(['c'])
|
136
|
+
expect(q.nullable_fields(nil)).to eql([])
|
137
|
+
|
138
|
+
expect(q.invalid?).to be_falsy
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'returns query instances collectly parsed, with built-in NULLABLE(), case-insensitive' do
|
142
|
+
expression = 'SELECT a, b, nullable(c) FROM TestTable output snapshot every 2 sec'
|
143
|
+
q = Norikra::Query.new(
|
144
|
+
:name => 'TestTable query1', :expression => expression
|
145
|
+
)
|
146
|
+
expect(q.name).to eql('TestTable query1')
|
147
|
+
expect(q.group).to be_nil
|
148
|
+
expect(q.expression).to eql(expression)
|
149
|
+
expect(q.targets).to eql(['TestTable'])
|
150
|
+
|
151
|
+
expect(q.fields).to eql(['a', 'b', 'c'])
|
152
|
+
expect(q.fields('TestTable')).to eql(['a', 'b', 'c'])
|
153
|
+
expect(q.fields(nil)).to eql([])
|
154
|
+
|
155
|
+
expect(q.nullable_fields).to eql(['c'])
|
156
|
+
expect(q.nullable_fields('TestTable')).to eql(['c'])
|
157
|
+
expect(q.nullable_fields(nil)).to eql([])
|
158
|
+
|
92
159
|
expect(q.invalid?).to be_falsy
|
93
160
|
end
|
94
161
|
end
|
@@ -178,9 +245,9 @@ describe Norikra::Query do
|
|
178
245
|
expect(q.targets).to eql(['RfidEvent', 'Zones'])
|
179
246
|
|
180
247
|
expect(q.fields).to eql(['name','zoneName','zoneId'].sort)
|
248
|
+
expect(q.fields(nil)).to eql([])
|
181
249
|
expect(q.fields('RfidEvent')).to eql(['zoneId'])
|
182
250
|
expect(q.fields('Zones')).to eql(['name','zoneName','zoneId'].sort)
|
183
|
-
expect(q.fields(nil)).to eql([])
|
184
251
|
|
185
252
|
expect(q.invalid?).to be_falsy
|
186
253
|
end
|
@@ -203,6 +270,28 @@ describe Norikra::Query do
|
|
203
270
|
|
204
271
|
expect(q.invalid?).to be_falsy
|
205
272
|
end
|
273
|
+
|
274
|
+
it 'returns query instances collectly parsed, even if it has nullable field' do
|
275
|
+
expression = 'select zoneId, (select NULLABLE(name) from Zones.std:unique(zoneName) where zoneId = RfidEvent.zoneId) as name from RfidEvent'
|
276
|
+
q = Norikra::Query.new(
|
277
|
+
:name => 'TestTable query5', :expression => expression
|
278
|
+
)
|
279
|
+
expect(q.name).to eql('TestTable query5')
|
280
|
+
expect(q.expression).to eql(expression)
|
281
|
+
expect(q.targets).to eql(['RfidEvent', 'Zones'].sort)
|
282
|
+
|
283
|
+
expect(q.fields).to eql(['name','zoneName','zoneId'].sort)
|
284
|
+
expect(q.fields('RfidEvent')).to eql(['zoneId'])
|
285
|
+
expect(q.fields('Zones')).to eql(['name','zoneName','zoneId'].sort)
|
286
|
+
expect(q.fields(nil)).to eql([])
|
287
|
+
|
288
|
+
expect(q.nullable_fields).to eql(['name'])
|
289
|
+
expect(q.nullable_fields(nil)).to eql([])
|
290
|
+
expect(q.nullable_fields('RfidEvent')).to eql([])
|
291
|
+
expect(q.nullable_fields('Zones')).to eql(['name'])
|
292
|
+
|
293
|
+
expect(q.invalid?).to be_falsy
|
294
|
+
end
|
206
295
|
end
|
207
296
|
|
208
297
|
context 'with query with subquery (from clause)' do
|
@@ -308,6 +397,25 @@ describe Norikra::Query do
|
|
308
397
|
end
|
309
398
|
end
|
310
399
|
|
400
|
+
context 'with non-builtin functions (ex: udf) with property arguments' do
|
401
|
+
it 'returns property fields correctly' do
|
402
|
+
expression = "select name, FOO(value) from EventA"
|
403
|
+
q = Norikra::Query.new(
|
404
|
+
:name => 'TestTable query10', :expression => expression
|
405
|
+
)
|
406
|
+
expect(q.name).to eql('TestTable query10')
|
407
|
+
expect(q.group).to be_nil
|
408
|
+
expect(q.expression).to eql(expression)
|
409
|
+
expect(q.targets).to eql(['EventA'])
|
410
|
+
expect(q.aliases).to eql([])
|
411
|
+
expect(q.fields).to eql(['name', 'value'].sort)
|
412
|
+
expect(q.fields('EventA')).to eql(['name', 'value'].sort)
|
413
|
+
expect(q.fields(nil)).to eql([])
|
414
|
+
|
415
|
+
expect(q.invalid?).to be_falsy
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
311
419
|
context 'with "*" selection list' do
|
312
420
|
it 'returns query instance which is singed as invalid for norikra query' do
|
313
421
|
expression = "select * from target1 where key1=1"
|
@@ -317,34 +425,30 @@ describe Norikra::Query do
|
|
317
425
|
expect(q.invalid?).to be_truthy
|
318
426
|
end
|
319
427
|
end
|
320
|
-
end
|
321
428
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
429
|
+
context 'with valid/invalid NULLABLE(...)' do
|
430
|
+
it 'returns query instance to show valid/invalid' do
|
431
|
+
exp0 = "SELECT a, NULLABLE( ) FROM t1 where a > 1"
|
432
|
+
expect(Norikra::Query.new(name:'q0', expression: exp0).invalid?).to be_truthy
|
326
433
|
|
327
|
-
|
328
|
-
|
329
|
-
expect(Norikra::Query.loopback('group1')).to be_nil
|
330
|
-
expect(Norikra::Query.loopback('LOOPBACK')).to be_nil
|
331
|
-
end
|
434
|
+
exp1 = "SELECT a, NULLABLE( b ) FROM t1 where a > 1"
|
435
|
+
expect(Norikra::Query.new(name:'q1', expression: exp1).invalid?).to be_falsy
|
332
436
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
end
|
339
|
-
end
|
437
|
+
exp2 = "SELECT a, NULLABLE( b ) FROM t1 where a || b"
|
438
|
+
expect(Norikra::Query.new(name:'q2', expression: exp2).invalid?).to be_falsy
|
439
|
+
|
440
|
+
exp3 = "SELECT a, NULLABLE( a, b ) FROM t1 where a"
|
441
|
+
expect(Norikra::Query.new(name:'q3', expression: exp3).invalid?).to be_truthy
|
340
442
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
443
|
+
exp4 = "SELECT a, NULLABLE( a + b ) FROM t1 where c"
|
444
|
+
expect(Norikra::Query.new(name:'q4', expression: exp4).invalid?).to be_truthy
|
445
|
+
|
446
|
+
exp5 = "SELECT a, NULLABLE( foo(b) ) FROM t1 where c"
|
447
|
+
expect(Norikra::Query.new(name:'q5', expression: exp5).invalid?).to be_truthy
|
448
|
+
|
449
|
+
exp6 = "SELECT a, NULLABLE( NULLABLE(b) ) FROM t1 where c"
|
450
|
+
expect(Norikra::Query.new(name:'q6', expression: exp6).invalid?).to be_truthy
|
451
|
+
end
|
348
452
|
end
|
349
453
|
end
|
350
454
|
|
@@ -380,6 +484,41 @@ describe Norikra::Query do
|
|
380
484
|
end
|
381
485
|
end
|
382
486
|
|
487
|
+
describe '.rewrite_nullable_fields' do
|
488
|
+
context 'with NULLABLE()' do
|
489
|
+
expression = 'select a, nullable(b) from TestTable.win:time_batch(10 seconds) where c>0'
|
490
|
+
expected = 'select a, b from TestTable.win:time_batch(10 seconds) where c>0'
|
491
|
+
it 'returns query without NULLABLE()' do
|
492
|
+
with_engine do
|
493
|
+
model = administrator.compileEPL(expression)
|
494
|
+
expect(Norikra::Query.rewrite_event_field_name(model, {'TestTable' => 'T1'}).toEPL).to eql(expression)
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
context 'with NULLABLE() in count(distinct)' do
|
500
|
+
expression = 'select a, count(distinct nullable(b)) from TestTable.win:time_batch(10 seconds) where c>0 group by a'
|
501
|
+
expected = 'select a, count(distinct b) from TestTable.win:time_batch(10 seconds) where c>0 group by a'
|
502
|
+
it 'returns query without NULLABLE()' do
|
503
|
+
with_engine do
|
504
|
+
model = administrator.compileEPL(expression)
|
505
|
+
expect(Norikra::Query.rewrite_event_field_name(model, {'TestTable' => 'T1'}).toEPL).to eql(expression)
|
506
|
+
end
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
context 'with some NULLABLE()' do
|
511
|
+
expression = 'select a, NULLABLE(b), NULLABLE(c), count(*) as cnt from TestTable.win:time_batch(10 seconds) where c>0 group by a, b, c'
|
512
|
+
expected = 'select a, b, c, count(*) AS cnt from TestTable.win:time_batch(10 seconds) where c>0 group by a, b, c'
|
513
|
+
it 'returns query without NULLABLE()' do
|
514
|
+
with_engine do
|
515
|
+
model = administrator.compileEPL(expression)
|
516
|
+
expect(Norikra::Query.rewrite_event_field_name(model, {'TestTable' => 'T1'}).toEPL).to eql(expression)
|
517
|
+
end
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
383
522
|
describe '.rewrite_event_field_name' do
|
384
523
|
context 'without any container field access' do
|
385
524
|
expression = 'select count(*) as cnt from TestTable.win:time_batch(10 seconds) where path="/" and size>100 and (param.length())>0'
|
@@ -566,6 +705,13 @@ describe Norikra::Query do
|
|
566
705
|
model = administrator.compileEPL(e5)
|
567
706
|
mapping = {'RfidEvent' => 'R1', 'Zones' => 'Z1'}
|
568
707
|
expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x5)
|
708
|
+
|
709
|
+
# Fully-qualified field access w/ container field access and NULLABLE()
|
710
|
+
e6 = 'select NULLABLE(RfidEvent.zoneId.$0), (select NULLABLE(name.x) from Zones.std:unique(zoneName) where zoneId=RfidEvent.zoneId.$0) as name from RfidEvent'
|
711
|
+
x6 = 'select R1.zoneId$$0, (select name$x from Z1.std:unique(zoneName) where zoneId=R1.zoneId$$0) as name from R1'
|
712
|
+
model = administrator.compileEPL(e6)
|
713
|
+
mapping = {'RfidEvent' => 'R1', 'Zones' => 'Z1'}
|
714
|
+
expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x6)
|
569
715
|
end
|
570
716
|
end
|
571
717
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,50 +1,4 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'spork'
|
3
|
-
#uncomment the following line to use spork with the debugger
|
4
|
-
#require 'spork/ext/ruby-debug'
|
5
|
-
|
6
|
-
Spork.prefork do
|
7
|
-
# Loading more in this block will cause your tests to run faster. However,
|
8
|
-
# if you change any configuration or code from libraries loaded here, you'll
|
9
|
-
# need to restart spork for it take effect.
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
Spork.each_run do
|
14
|
-
# This code will be run each time you run your specs.
|
15
|
-
Dir.glob('./lib/norikra/**/*.rb').each do |file|
|
16
|
-
load file
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# --- Instructions ---
|
21
|
-
# Sort the contents of this file into a Spork.prefork and a Spork.each_run
|
22
|
-
# block.
|
23
|
-
#
|
24
|
-
# The Spork.prefork block is run only once when the spork server is started.
|
25
|
-
# You typically want to place most of your (slow) initializer code in here, in
|
26
|
-
# particular, require'ing any 3rd-party gems that you don't normally modify
|
27
|
-
# during development.
|
28
|
-
#
|
29
|
-
# The Spork.each_run block is run each time you run your specs. In case you
|
30
|
-
# need to load files that tend to change during development, require them here.
|
31
|
-
# With Rails, your application modules are loaded automatically, so sometimes
|
32
|
-
# this block can remain empty.
|
33
|
-
#
|
34
|
-
# Note: You can modify files loaded *from* the Spork.each_run block without
|
35
|
-
# restarting the spork server. However, this file itself will not be reloaded,
|
36
|
-
# so if you change any of the code inside the each_run block, you still need to
|
37
|
-
# restart the server. In general, if you have non-trivial code in this file,
|
38
|
-
# it's advisable to move it into a separate file so you can easily edit it
|
39
|
-
# without restarting spork. (For example, with RSpec, you could move
|
40
|
-
# non-trivial code into a file spec/support/my_helper.rb, making sure that the
|
41
|
-
# spec/support/* files are require'd from inside the each_run block.)
|
42
|
-
#
|
43
|
-
# Any code that is left outside the two blocks will be run during preforking
|
44
|
-
# *and* during each_run -- that's probably not what you want.
|
45
|
-
#
|
46
|
-
# These instructions should self-destruct in 10 seconds. If they don't, feel
|
47
|
-
# free to delete them.
|
48
2
|
|
49
3
|
require 'rubygems'
|
50
4
|
require 'rspec'
|
@@ -218,10 +218,16 @@ describe Norikra::TypedefManager do
|
|
218
218
|
|
219
219
|
describe '#generate_query_fieldset' do
|
220
220
|
it 'returns fieldset instance with all required(non-optional) fields of target, and fields of query requires' do
|
221
|
-
r = manager.generate_query_fieldset('sample', ['a', 'b','f'], 'qname1', nil)
|
221
|
+
r = manager.generate_query_fieldset('sample', ['a', 'b', 'f'], [], 'qname1', nil)
|
222
222
|
expect(r.fields.size).to eql(4) # a,b,c,f
|
223
223
|
expect(r.summary).to eql('a:string,b:string,c:float,f:boolean')
|
224
224
|
end
|
225
|
+
|
226
|
+
it 'returns fieldset instance with nullable information if specified' do
|
227
|
+
r = manager.generate_query_fieldset('sample', ['a', 'b', 'f'], ['b', 'f'], 'qname1', nil)
|
228
|
+
expect(r.fields.size).to eql(4) # a,b,c,f
|
229
|
+
expect(r.summary).to eql('a:string,b:string:nullable,c:float,f:boolean:nullable')
|
230
|
+
end
|
225
231
|
end
|
226
232
|
|
227
233
|
describe '#dump_target' do
|
@@ -233,18 +239,18 @@ describe Norikra::TypedefManager do
|
|
233
239
|
|
234
240
|
r = m.dump_target('sample')
|
235
241
|
expect(r).to eql({
|
236
|
-
a: {name: 'a', type: 'string', optional: false},
|
237
|
-
b: {name: 'b', type: 'string', optional: false},
|
238
|
-
c: {name: 'c', type: 'float', optional: false},
|
239
|
-
z: {name: 'z', type: 'boolean', optional: true},
|
242
|
+
a: {name: 'a', type: 'string', optional: false, nullable: false},
|
243
|
+
b: {name: 'b', type: 'string', optional: false, nullable: false},
|
244
|
+
c: {name: 'c', type: 'float', optional: false, nullable: false},
|
245
|
+
z: {name: 'z', type: 'boolean', optional: true, nullable: false},
|
240
246
|
})
|
241
247
|
|
242
248
|
r = m.dump_target('sample_next')
|
243
249
|
expect(r).to eql({
|
244
|
-
a: {name: 'a', type: 'string', optional: false},
|
245
|
-
b: {name: 'b', type: 'string', optional: false},
|
246
|
-
c: {name: 'c', type: 'float', optional: false},
|
247
|
-
d: {name: 'd', type: 'float', optional: false},
|
250
|
+
a: {name: 'a', type: 'string', optional: false, nullable: false},
|
251
|
+
b: {name: 'b', type: 'string', optional: false, nullable: false},
|
252
|
+
c: {name: 'c', type: 'float', optional: false, nullable: false},
|
253
|
+
d: {name: 'd', type: 'float', optional: false, nullable: false},
|
248
254
|
})
|
249
255
|
end
|
250
256
|
end
|
data/spec/typedef_spec.rb
CHANGED
@@ -290,7 +290,7 @@ describe Norikra::Typedef do
|
|
290
290
|
set1 = Norikra::FieldSet.new({'a'=>'string','b'=>'int'})
|
291
291
|
set2 = Norikra::FieldSet.new({'a'=>'string','c'=>'int'})
|
292
292
|
t.push(:data, set1)
|
293
|
-
expect { t.replace(:data, set1, set2) }.to raise_error(
|
293
|
+
expect { t.replace(:data, set1, set2) }.to raise_error(::ArgumentError)
|
294
294
|
end
|
295
295
|
|
296
296
|
it 'replaces typedef internal fieldset object for specified field_names_key' do
|
@@ -540,10 +540,10 @@ describe Norikra::Typedef do
|
|
540
540
|
|
541
541
|
r = t.dump
|
542
542
|
expect(r.keys.sort).to eql([:a, :b, :c, :d])
|
543
|
-
expect(r[:a]).to eql({name: 'a', type: 'string', optional: false})
|
544
|
-
expect(r[:b]).to eql({name: 'b', type: 'integer', optional: false})
|
545
|
-
expect(r[:c]).to eql({name: 'c', type: 'float', optional: true})
|
546
|
-
expect(r[:d]).to eql({name: 'd', type: 'string', optional: true})
|
543
|
+
expect(r[:a]).to eql({name: 'a', type: 'string', optional: false, nullable: false})
|
544
|
+
expect(r[:b]).to eql({name: 'b', type: 'integer', optional: false, nullable: false})
|
545
|
+
expect(r[:c]).to eql({name: 'c', type: 'float', optional: true, nullable: false})
|
546
|
+
expect(r[:d]).to eql({name: 'd', type: 'string', optional: true, nullable: false})
|
547
547
|
|
548
548
|
t2 = Norikra::Typedef.new(r)
|
549
549
|
expect(t2.fields.keys.sort).to eql(fields.keys.sort)
|
@@ -560,12 +560,12 @@ describe Norikra::Typedef do
|
|
560
560
|
|
561
561
|
r = t.dump
|
562
562
|
expect(r.keys.sort).to eql([:a, :b, :c, :d, :e, :f])
|
563
|
-
expect(r[:a]).to eql({name: 'a', type: 'string', optional: false})
|
564
|
-
expect(r[:b]).to eql({name: 'b', type: 'integer', optional: false})
|
565
|
-
expect(r[:c]).to eql({name: 'c', type: 'float', optional: true})
|
566
|
-
expect(r[:d]).to eql({name: 'd', type: 'string', optional: true})
|
567
|
-
expect(r[:e]).to eql({name: 'e', type: 'array', optional: true})
|
568
|
-
expect(r[:f]).to eql({name: 'f', type: 'hash', optional: true})
|
563
|
+
expect(r[:a]).to eql({name: 'a', type: 'string', optional: false, nullable: false})
|
564
|
+
expect(r[:b]).to eql({name: 'b', type: 'integer', optional: false, nullable: false})
|
565
|
+
expect(r[:c]).to eql({name: 'c', type: 'float', optional: true, nullable: false})
|
566
|
+
expect(r[:d]).to eql({name: 'd', type: 'string', optional: true, nullable: false})
|
567
|
+
expect(r[:e]).to eql({name: 'e', type: 'array', optional: true, nullable: false})
|
568
|
+
expect(r[:f]).to eql({name: 'f', type: 'hash', optional: true, nullable: false})
|
569
569
|
end
|
570
570
|
end
|
571
571
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: norikra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- TAGOMORI Satoshi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mizuno
|
@@ -164,20 +164,6 @@ dependencies:
|
|
164
164
|
version: '0'
|
165
165
|
prerelease: false
|
166
166
|
type: :development
|
167
|
-
- !ruby/object:Gem::Dependency
|
168
|
-
name: spork
|
169
|
-
version_requirements: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - '>='
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
174
|
-
requirement: !ruby/object:Gem::Requirement
|
175
|
-
requirements:
|
176
|
-
- - '>='
|
177
|
-
- !ruby/object:Gem::Version
|
178
|
-
version: '0'
|
179
|
-
prerelease: false
|
180
|
-
type: :development
|
181
167
|
- !ruby/object:Gem::Dependency
|
182
168
|
name: pry
|
183
169
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -238,11 +224,9 @@ files:
|
|
238
224
|
- lib/norikra/query.rb
|
239
225
|
- lib/norikra/query/ast.rb
|
240
226
|
- lib/norikra/rpc.rb
|
241
|
-
- lib/norikra/rpc/error.rb
|
242
227
|
- lib/norikra/rpc/gatekeeper.rb
|
243
228
|
- lib/norikra/rpc/handler.rb
|
244
229
|
- lib/norikra/rpc/http.rb
|
245
|
-
- lib/norikra/rubyudf.rb
|
246
230
|
- lib/norikra/server.rb
|
247
231
|
- lib/norikra/stats.rb
|
248
232
|
- lib/norikra/suspended_query.rb
|
@@ -272,7 +256,7 @@ files:
|
|
272
256
|
- public/js/bootstrap.min.js
|
273
257
|
- public/js/jquery.min.js
|
274
258
|
- public/js/norikra.webui.js
|
275
|
-
- script/
|
259
|
+
- script/pry
|
276
260
|
- spec/engine_spec.rb
|
277
261
|
- spec/field_spec.rb
|
278
262
|
- spec/fieldset_spec.rb
|
data/lib/norikra/rpc/error.rb
DELETED
File without changes
|
data/lib/norikra/rubyudf.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# this is note for future update
|
2
|
-
|
3
|
-
# module Norikra
|
4
|
-
# module UDF
|
5
|
-
# class FailedUDFImplementationPureRuby
|
6
|
-
# # require 'jruby/core_ext'
|
7
|
-
# class WootheeIsCrawler < Norikra::UDF::Base # Norikra::UDF::WootheeIsCrawler < Norikra::UDF::Base
|
8
|
-
# def self.init
|
9
|
-
# require 'woothee'
|
10
|
-
# end
|
11
|
-
|
12
|
-
# def self.function_name
|
13
|
-
# "isCrawler"
|
14
|
-
# end
|
15
|
-
|
16
|
-
# def self.isCrawler(agent)
|
17
|
-
# Woothee.is_crawler(agent)
|
18
|
-
# end
|
19
|
-
# class << self
|
20
|
-
# add_method_signature( "isCrawler", [java.lang.Boolean, java.lang.String] )
|
21
|
-
# end
|
22
|
-
# end
|
23
|
-
|
24
|
-
# # for engine.rb
|
25
|
-
# def load_udf_actually(udf_klass)
|
26
|
-
# require 'jruby/core_ext'
|
27
|
-
# udf_klass.init
|
28
|
-
|
29
|
-
# jclass = udf_klass.become_java!(".")
|
30
|
-
# className = jclass.get_name.to_java(:string)
|
31
|
-
|
32
|
-
# #### try for NullPointerException, but doesn't work well
|
33
|
-
# # field = jclass.getDeclaredField("ruby");
|
34
|
-
# # field.setAccessible(java.lang.Boolean::TRUE)
|
35
|
-
# # field.set(nil, org.jruby.Ruby.getGlobalRuntime)
|
36
|
-
|
37
|
-
# functionName = udf_klass.function_name.to_java(:string)
|
38
|
-
# methodName = udf_klass.method_name.to_java(:string)
|
39
|
-
|
40
|
-
# valueCache = udf_klass.value_cache ? VALUE_CACHE_ENUM::ENABLED : VALUE_CACHE_ENUM::DISABLED
|
41
|
-
# filterOptimizable = udf_klass.filter_optimizable ? FILTER_OPTIMIZABLE_ENUM::ENABLED : FILTER_OPTIMIZABLE_ENUM::DISABLED
|
42
|
-
# rethrowExceptions = udf_klass.rethrow_exceptions
|
43
|
-
|
44
|
-
# debug "adding SingleRowFunction", :class => udf_klass.to_s, :javaClass => jclass.get_name
|
45
|
-
# @config.addPlugInSingleRowFunction(functionName, className, methodName, valueCache, filterOptimizable, rethrowExceptions)
|
46
|
-
# end
|
47
|
-
# end
|
48
|
-
# end
|
49
|
-
# end
|