norikra 0.1.5-java → 0.1.6-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30a26c93805e62b832b47ade931907e800c35c01
4
- data.tar.gz: f8fe030eacb414c84aeebd01b40351965391a53b
3
+ metadata.gz: 0250e9866cf7d804dee32f348e8aa7832fbf5ef2
4
+ data.tar.gz: a91fb11a6ed74fd8bc2bc56108c62e4a4d3e8b0e
5
5
  SHA512:
6
- metadata.gz: 243a44cf8003f1843df7137c4c78c9e72765e3da51f7f33e961531cd9017c612389d44051fdf2a1cf98c57149b97a9978c250dacc98a4cd324206e9866d4cdbd
7
- data.tar.gz: 7351f6ee5139a5323adfb9708abe8291f253e47a783d2efcc4fdf682c35f706ea48ae7c179dcfa8bb6bea73137eb95bdd2b578c164ec4af4de24e237cb2efe9b
6
+ metadata.gz: 506b88f4cb736f441566f9ee02d34fbe7d2c990cddcf8bf8c30c2ebe907010a8dc44fc5586db57985d86fcf8f6aa784f09b80e12d8211147315621d230fbd8b6
7
+ data.tar.gz: 5913062545c129fcdd227260c1c0081ed8f7ff3682103f833f03e41740571be637ca35968e6264d94690900e62b499b0460270a14a1fcb2a5e5c6c9a0ab80f87
data/README.md CHANGED
@@ -69,37 +69,39 @@ See: http://norikra.github.io/
69
69
 
70
70
  ## Changes
71
71
 
72
+ * v0.1.6:
73
+ * Fix bug: Wrong escape for java instance method calls
72
74
  * v0.1.5:
73
- * Add RPC port monitoring handler (GET /)
74
- * Add `Pattern` support
75
- * Changes for GC/JVM
76
- * Server starts with default(recommended) JVM options for GC configurations
77
- * Add option not to use default JVM options
78
- * Add option to configure JVM to print GC logs
79
- * Stats file changes
80
- * Changed to use SIGUSR2 (SIGUSR1 is used by JVM on linux platform)
81
- * Changed no to contain server process configurations (ports, threads, logs ...)
82
- * WebUI improvements
83
- * Add button to close target on WebUI
84
- * Add link to download stats file
85
- * Fix bugs
86
- * Fieldname handlings about names with non-alphabetic chars
87
- * Query parser bug for some built-in functions (ex: `rate(10)`)
88
- * Write stats file in more safe way
89
- * WebUI: Incorrect memory bar
75
+ * Add RPC port monitoring handler (GET /)
76
+ * Add `Pattern` support
77
+ * Changes for GC/JVM
78
+ * Server starts with default(recommended) JVM options for GC configurations
79
+ * Add option not to use default JVM options
80
+ * Add option to configure JVM to print GC logs
81
+ * Stats file changes
82
+ * Changed to use SIGUSR2 (SIGUSR1 is used by JVM on linux platform)
83
+ * Changed no to contain server process configurations (ports, threads, logs ...)
84
+ * WebUI improvements
85
+ * Add button to close target on WebUI
86
+ * Add link to download stats file
87
+ * Fix bugs
88
+ * Fieldname handlings about names with non-alphabetic chars
89
+ * Query parser bug for some built-in functions (ex: `rate(10)`)
90
+ * Write stats file in more safe way
91
+ * WebUI: Incorrect memory bar
90
92
  * v0.1.4:
91
- * Stat dump option on runtime per specified intervals (`--dump-stat-interval`)
92
- * Stat dump on demand by SIGUSR1
93
- * `norikra-client event see` command (and API call) to get query results, but not remove it
94
- * Last modified time for each target on WebUI
93
+ * Stat dump option on runtime per specified intervals (`--dump-stat-interval`)
94
+ * Stat dump on demand by SIGUSR1
95
+ * `norikra-client event see` command (and API call) to get query results, but not remove it
96
+ * Last modified time for each target on WebUI
95
97
  * v0.1.3:
96
- * Fix critical bug about query de-registration
98
+ * Fix critical bug about query de-registration
97
99
  * v0.1.2:
98
- * Fix CLI start command to detect jruby path collectly (behind rbenv/rvm and others)
100
+ * Fix CLI start command to detect jruby path collectly (behind rbenv/rvm and others)
99
101
  * v0.1.1:
100
- * Fix types more explicitly for users ('int/long' -> 'integer', 'float/double' -> 'float')
102
+ * Fix types more explicitly for users ('int/long' -> 'integer', 'float/double' -> 'float')
101
103
  * v0.1.0:
102
- * First release for production
104
+ * First release for production
103
105
 
104
106
  ## Copyright
105
107
 
data/lib/norikra/query.rb CHANGED
@@ -215,7 +215,24 @@ module Norikra
215
215
  else
216
216
  raise Norikra::QueryError, "target cannot be determined for field '#{name}'"
217
217
  end
218
- encoded = (prefix ? "#{prefix}." : "") + Norikra::Field.escape_name(body)
218
+ #### 'field.javaMethod("args")' MUST NOT be escaped....
219
+ # 'getPropertyName' returns a String "path.index(\".\")" for java method calling,
220
+ # and other optional informations are not provided.
221
+ # We seems that '.camelCase(ANYTHING)' should be a method calling, not nested field accesses.
222
+ # This is ugly, but works.
223
+ #
224
+ # 'path.substring(0, path.indexOf(path.substring(1,1)))' is parsed as 3-times-nested LIB_FUNCTION_CHAIN,
225
+ # so does not make errors.
226
+ #
227
+ method_chains = []
228
+ body_chains = body.split('.')
229
+ while body_chains.size > 0
230
+ break unless body_chains.last =~ /^[a-z][a-zA-Z]*\(.*\)$/
231
+ method_chains.unshift body_chains.pop
232
+ end
233
+
234
+ escaped_body = Norikra::Field.escape_name(body_chains.join('.'))
235
+ encoded = (prefix ? "#{prefix}." : "") + escaped_body + (method_chains.size > 0 ? '.' + method_chains.join('.') : '' )
219
236
  node.send(setter, encoded)
220
237
  end
221
238
  }
@@ -207,6 +207,8 @@ module Norikra
207
207
  # "bbb" => ["EVENT_PROP_EXPR", ["EVENT_PROP_SIMPLE", "bbb"]]
208
208
  # "fraud.aaa" => ["EVENT_PROP_EXPR", ["EVENT_PROP_SIMPLE", "fraud"], ["EVENT_PROP_SIMPLE", "aaa"]]
209
209
  # "size.$0.bytes" => ["EVENT_PROP_EXPR", ["EVENT_PROP_SIMPLE", "size"], ["EVENT_PROP_SIMPLE", "$0"], ["EVENT_PROP_SIMPLE", "bytes"]]
210
+ # "field.index("?")" => ["EVENT_PROP_EXPR", ["EVENT_PROP_SIMPLE", "path"], ["EVENT_PROP_MAPPED", "index", "\"?\""]]
211
+ # "field.f1.index(".")" => ["EVENT_PROP_EXPR", ["EVENT_PROP_SIMPLE", "path"], ["EVENT_PROP_SIMPLE", "q1"], ["EVENT_PROP_MAPPED", "index", "\".\""]]
210
212
 
211
213
  def nodetype?(*sym)
212
214
  sym.include?(:prop) || sym.include?(:property)
@@ -214,7 +216,7 @@ module Norikra
214
216
 
215
217
  def fields(default_target=nil, known_targets_aliases=[])
216
218
  props = self.listup('EVENT_PROP_SIMPLE')
217
- if props.size > 1 # alias.fieldname or container_fieldname.key.$1
219
+ if props.size > 1 # alias.fieldname or container_fieldname.key.$1 or fieldname.method(...)
218
220
  if known_targets_aliases.include?(props[0].child.name)
219
221
  [ {:f => props[1..-1].map{|n| n.child.name}.join("."), :t => props[0].child.name} ]
220
222
  else
@@ -1,3 +1,3 @@
1
1
  module Norikra
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
data/spec/query_spec.rb CHANGED
@@ -175,6 +175,18 @@ describe Norikra::Query do
175
175
  expect(q.fields('TestTable')).to eql(['params.$$path.$1', 'size.$0.bytes', 'opts.num.$0'].sort)
176
176
  expect(q.fields(nil)).to eql([])
177
177
  end
178
+
179
+ it 'can parse with nested function calls correctly' do
180
+ expression = 'SELECT path.substring(0, path.index("?")) AS urlpath, COUNT(*) AS count FROM TestTable.win:time_batch(60 seconds) GROUP BY path.substring(0, path.index("?"))'
181
+ q = Norikra::Query.new(:name => 'TestTable query8.1', :expression => expression)
182
+ expect(q.fields).to eql(['path'])
183
+ end
184
+
185
+ it 'can parse with nested function calls w/ nested fields correctly' do
186
+ expression = 'SELECT path.f1.substring(0, path.f1.index("?")) AS urlpath, COUNT(*) AS count FROM TestTable.win:time_batch(60 seconds) GROUP BY path.f1.substring(0, path.f1.index("?"))'
187
+ q = Norikra::Query.new(:name => 'TestTable query8.2', :expression => expression)
188
+ expect(q.fields).to eql(['path.f1'])
189
+ end
178
190
  end
179
191
 
180
192
  context 'with query with patterns' do
@@ -333,60 +345,85 @@ describe Norikra::Query do
333
345
  describe '.rewrite_query' do
334
346
  it 'rewrites all of targets and container-field-accesses' do
335
347
  with_engine do
348
+ # single simple query
336
349
  e1 = 'select count(*) as cnt from TestTable.win:time_batch(10 seconds) where path = "/" and size > 100 and (param.length()) > 0'
337
350
  x1 = 'select count(*) as cnt from T1.win:time_batch(10 seconds) where path = "/" and size > 100 and (param.length()) > 0'
338
351
  model = administrator.compileEPL(e1)
339
352
  mapping = {'TestTable' => 'T1'}
340
353
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x1)
341
354
 
355
+ # nested container field access
342
356
  e2 = 'select max(result.$0.size) as cnt from TestTable.win:time_batch(10 seconds) where req.path = "/" and result.$0.size > 100 and (req.param.length()) > 0'
343
357
  x2 = 'select max(result$$0$size) as cnt from T1.win:time_batch(10 seconds) where req$path = "/" and result$$0$size > 100 and (req$param.length()) > 0'
344
358
  model = administrator.compileEPL(e2)
345
359
  mapping = {'TestTable' => 'T1'}
346
360
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x2)
347
361
 
362
+ # nested container field access w/ function call and alias
348
363
  e3 = 'select product, max(sta.param.size) as maxsize from StreamA.win:keepall() as sta, StreamB(size > 10).win:time(20 seconds) as stb where (sta.data.$0.$$body.substr(0, 8)) = stb.header and (Math.abs(sta.size)) > 3'
349
364
  x3 = 'select product, max(sta.param$size) as maxsize from S1.win:keepall() as sta, S2(size > 10).win:time(20 seconds) as stb where (sta.data$$0$$$body.substr(0, 8)) = stb.header and (Math.abs(sta.size)) > 3'
350
365
  model = administrator.compileEPL(e3)
351
366
  mapping = {'StreamA' => 'S1', 'StreamB' => 'S2'}
352
367
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x3)
353
368
 
369
+ # nested function call
370
+ e3a = 'select path.substring(0, path.index("?")) as urlpath, count(*) as count from TestTable.win:time_batch(60 seconds) group by path.substring(0, path.index("?"))'
371
+ x3a = 'select path.substring(0, path.index("?")) as urlpath, count(*) as count from T1.win:time_batch(60 seconds) group by path.substring(0, path.index("?"))'
372
+ model = administrator.compileEPL(e3a)
373
+ mapping = {'TestTable' => 'T1'}
374
+ expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x3a)
375
+
376
+ # nested function call w/ container field access
377
+ e3b = 'select path.f1.substring(0, path.f1.index("?")) as urlpath, count(*) as count from TestTable.win:time_batch(60 seconds) group by path.f1.substring(0, path.f1.index("?"))'
378
+ x3b = 'select path$f1.substring(0, path$f1.index("?")) as urlpath, count(*) as count from T1.win:time_batch(60 seconds) group by path$f1.substring(0, path$f1.index("?"))'
379
+ model = administrator.compileEPL(e3b)
380
+ mapping = {'TestTable' => 'T1'}
381
+ expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x3b)
382
+
383
+
384
+ # Fully-qualified field access
354
385
  e4 = 'select count(*) as cnt from TestTable.win:time_batch(10 seconds) where path = "/" and TestTable.size > 100 and (param.length()) > 0'
355
386
  x4 = 'select count(*) as cnt from T1.win:time_batch(10 seconds) where path = "/" and T1.size > 100 and (param.length()) > 0'
356
387
  model = administrator.compileEPL(e4)
357
388
  mapping = {'TestTable' => 'T1'}
358
389
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x4)
359
390
 
391
+ # Fully-qualified field access w/ container field access
360
392
  e5 = 'select RfidEvent.zoneId.$0, (select name.x from Zones.std:unique(zoneName) where zoneId = RfidEvent.zoneId.$0) as name from RfidEvent'
361
393
  x5 = 'select R1.zoneId$$0, (select name$x from Z1.std:unique(zoneName) where zoneId = R1.zoneId$$0) as name from R1'
362
394
  model = administrator.compileEPL(e5)
363
395
  mapping = {'RfidEvent' => 'R1', 'Zones' => 'Z1'}
364
396
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x5)
365
397
 
398
+ # Fully-qualified field access w/ container field access and function calls, JOINs
366
399
  e6 = 'select StreamA.product, max(sta.param.size) as maxsize from StreamA.win:keepall() as sta, StreamB(size > 10).win:time(20 seconds) as stb where (sta.data.$0.$$body.substr(0, 8)) = StreamB.header.$0 and (Math.abs(StreamA.size.$0.$$abs)) > 3'
367
400
  x6 = 'select S1.product, max(sta.param$size) as maxsize from S1.win:keepall() as sta, S2(size > 10).win:time(20 seconds) as stb where (sta.data$$0$$$body.substr(0, 8)) = S2.header$$0 and (Math.abs(S1.size$$0$$$abs)) > 3'
368
401
  model = administrator.compileEPL(e6)
369
402
  mapping = {'StreamA' => 'S1', 'StreamB' => 'S2'}
370
403
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x6)
371
404
 
405
+ # ??? simple query
372
406
  e7 = 'select count(*) as cnt from TestTable.win:time_batch(10 seconds) where path = "/" and size > 100 and (param.length()) > 0'
373
407
  x7 = 'select count(*) as cnt from T1.win:time_batch(10 seconds) where path = "/" and size > 100 and (param.length()) > 0'
374
408
  model = administrator.compileEPL(e7)
375
409
  mapping = {'TestTable' => 'T1'}
376
410
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x7)
377
411
 
412
+ # subquery
378
413
  e8 = 'select RfidEvent.zoneId.$0, (select name.x from Zones.std:unique(zoneName) where zoneId = RfidEvent.zoneId.$0) as name from RfidEvent'
379
414
  x8 = 'select R1.zoneId$$0, (select name$x from Z1.std:unique(zoneName) where zoneId = R1.zoneId$$0) as name from R1'
380
415
  model = administrator.compileEPL(e8)
381
416
  mapping = {'Zones' => 'Z1', 'RfidEvent' => 'R1'}
382
417
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x8)
383
418
 
419
+ # filters and subquery
384
420
  e9 = 'select * from BarData(ticker = "MSFT" and (sub(closePrice, (select movAgv from SMA20Stream(ticker = "MSFT").std:lastevent())) > 0))'
385
421
  x9 = 'select * from B1(ticker = "MSFT" and (sub(closePrice, (select movAgv from S1(ticker = "MSFT").std:lastevent()))) > 0)'
386
422
  model = administrator.compileEPL(e9)
387
423
  mapping = {'BarData' => 'B1', 'SMA20Stream' => 'S1'}
388
424
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x9)
389
425
 
426
+ # JOINs
390
427
  e10 = 'select product, max(sta.size) as maxsize from StreamA.win:keepall() as sta, StreamB(size > 10).win:time(20 seconds) as stb where (sta.data.substr(0, 8)) = stb.header and (Math.abs(sta.size)) > 3'
391
428
  x10 = 'select product, max(sta.size) as maxsize from S1.win:keepall() as sta, S2(size > 10).win:time(20 seconds) as stb where (sta.data.substr(0, 8)) = stb.header and (Math.abs(sta.size)) > 3'
392
429
  model = administrator.compileEPL(e10)
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: 0.1.5
4
+ version: 0.1.6
5
5
  platform: java
6
6
  authors:
7
7
  - TAGOMORI Satoshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-28 00:00:00.000000000 Z
11
+ date: 2014-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mizuno