hotdog 0.6.1 → 0.6.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b087123acdf59f344d374145bdf0915f57757f6
4
- data.tar.gz: 0f22b57543b9b6d83e904d9f643eac3ccc3a6a52
3
+ metadata.gz: 91215663a09880593d00a5067b5f65ce3cb4b288
4
+ data.tar.gz: e840f3478257b84e516d4af7f6c4464cdaa7306b
5
5
  SHA512:
6
- metadata.gz: 51f9b047b0bc2cf02ae5abb013d02e1c0c52e5e7530ec7b27e313663a5e2022214d578a7bb58531e1f8c6e7833de1f2b4205e8c78bd319659c4499b67eb5edf1
7
- data.tar.gz: f6017f78210111e9bc19492b0a2b0724c15cfebe568e68d2902d71f5b2861428a3665caff8c25794d1ce07cbe057eb2ca05338a02a598b32b39611fd03514d9d
6
+ metadata.gz: 8beeb9c046d7467a48025aa7156f9b8e04c19f3923eb544086b5bec52f7cc0afddae29cad26cd699803fe0046c623e0179159917a3dc5e41b2996a0b39ae8246
7
+ data.tar.gz: 199c17a2d104dbb24c5135ac2cc180b9a26f594b1d2aaf9eb1870f3ba6e7b209a27b6b08d061c34598877ed385b4accb505d35ee3543f79f95554668b56b5695
@@ -44,17 +44,6 @@ module Hotdog
44
44
  end
45
45
  end
46
46
 
47
- def parse_options(optparse, args=[])
48
- if args.index("--")
49
- @remote_command = args.slice(args.index("--") + 1, args.length).join(" ")
50
- optparse.parse(args.slice(0, args.index("--")))
51
- else
52
- @remote_command = nil
53
- optparse.parse(args)
54
- end
55
- end
56
- attr_reader :remote_command
57
-
58
47
  def run(args=[], options={})
59
48
  expression = args.join(" ").strip
60
49
  if expression.empty?
@@ -12,7 +12,21 @@ module Hotdog
12
12
  end
13
13
  end
14
14
 
15
+ def parse_options(optparse, args=[])
16
+ if args.index("--")
17
+ @remote_command = args.slice(args.index("--") + 1, args.length).join(" ")
18
+ optparse.parse(args.slice(0, args.index("--")))
19
+ else
20
+ @remote_command = nil
21
+ optparse.parse(args)
22
+ end
23
+ end
24
+ attr_reader :remote_command
25
+
15
26
  def run(args=[], options={})
27
+ if @remote_command
28
+ logger.warn("ignore remote command: #{@remote_command}")
29
+ end
16
30
  expression = args.join(" ").strip
17
31
  if expression.empty?
18
32
  # return everything if given expression is empty
@@ -65,6 +79,7 @@ module Hotdog
65
79
  end
66
80
 
67
81
  def parse(expression)
82
+ logger.debug(expression)
68
83
  parser = ExpressionParser.new
69
84
  parser.parse(expression).tap do |parsed|
70
85
  logger.debug {
@@ -214,14 +229,14 @@ module Hotdog
214
229
  }
215
230
  rule(identifier_regexp: simple(:identifier_regexp), separator: simple(:separator)) {
216
231
  if "host" == identifier_regexp
217
- AnyHostNode.new(separator)
232
+ EverythingNode.new()
218
233
  else
219
234
  RegexpTagNameNode.new(identifier_regexp.to_s, separator)
220
235
  end
221
236
  }
222
237
  rule(identifier_regexp: simple(:identifier_regexp)) {
223
238
  if "host" == identifier_regexp
224
- AnyHostNode.new(separator)
239
+ EverythingNode.new()
225
240
  else
226
241
  RegexpNode.new(identifier_regexp.to_s)
227
242
  end
@@ -242,14 +257,14 @@ module Hotdog
242
257
  }
243
258
  rule(identifier_glob: simple(:identifier_glob), separator: simple(:separator)) {
244
259
  if "host" == identifier_glob
245
- AnyHostNode.new(separator)
260
+ EverythingNode.new()
246
261
  else
247
262
  GlobTagNameNode.new(identifier_glob.to_s, separator)
248
263
  end
249
264
  }
250
265
  rule(identifier_glob: simple(:identifier_glob)) {
251
266
  if "host" == identifier_glob
252
- AnyHostNode.new(separator)
267
+ EverythingNode.new()
253
268
  else
254
269
  GlobNode.new(identifier_glob.to_s)
255
270
  end
@@ -270,14 +285,14 @@ module Hotdog
270
285
  }
271
286
  rule(identifier: simple(:identifier), separator: simple(:separator)) {
272
287
  if "host" == identifier
273
- AnyHostNode.new(separator)
288
+ EverythingNode.new()
274
289
  else
275
290
  StringTagNameNode.new(identifier.to_s, separator)
276
291
  end
277
292
  }
278
293
  rule(identifier: simple(:identifier)) {
279
294
  if "host" == identifier
280
- AnyHostNode.new(separator)
295
+ EverythingNode.new()
281
296
  else
282
297
  StringNode.new(identifier.to_s)
283
298
  end
@@ -328,7 +343,7 @@ module Hotdog
328
343
  attr_reader :op, :expression
329
344
 
330
345
  def initialize(op, expression)
331
- case op
346
+ case (op || "not").to_s
332
347
  when "!", "~", /\Anot\z/i
333
348
  @op = :NOT
334
349
  else
@@ -369,7 +384,14 @@ module Hotdog
369
384
  @expression = @expression.optimize(options)
370
385
  case op
371
386
  when :NOT
372
- optimize1(options)
387
+ case expression
388
+ when EverythingNode
389
+ NothingNode.new(options)
390
+ when NothingNode
391
+ EverythingNode.new(options)
392
+ else
393
+ optimize1(options)
394
+ end
373
395
  else
374
396
  self
375
397
  end
@@ -398,7 +420,16 @@ module Hotdog
398
420
  if UnaryExpressionNode === expression and expression.op == :NOT
399
421
  expression.expression
400
422
  else
401
- if TagExpressionNode === expression
423
+ case expression
424
+ when QueryExpressionNode
425
+ q = expression.query
426
+ v = expression.values
427
+ if q and v.length <= SQLITE_LIMIT_COMPOUND_SELECT
428
+ QueryExpressionNode.new("SELECT id AS host_id FROM hosts EXCEPT #{q.sub(/\s*;\s*\z/, "")};", v)
429
+ else
430
+ self
431
+ end
432
+ when TagExpressionNode
402
433
  q = expression.maybe_query(options)
403
434
  v = expression.condition_values(options)
404
435
  if q and v.length <= SQLITE_LIMIT_COMPOUND_SELECT
@@ -420,7 +451,7 @@ module Hotdog
420
451
  attr_reader :op, :left, :right
421
452
 
422
453
  def initialize(op, left, right)
423
- case op || "or"
454
+ case (op || "or").to_s
424
455
  when "&&", "&", /\Aand\z/i
425
456
  @op = :AND
426
457
  when "||", "|", /\Aor\z/i
@@ -529,30 +560,44 @@ module Hotdog
529
560
  @right = @right.optimize(options)
530
561
  case op
531
562
  when :AND
532
- if left == right
563
+ case left
564
+ when EverythingNode
565
+ right
566
+ when NothingNode
533
567
  left
534
568
  else
535
- optimize1(options)
569
+ if left == right
570
+ left
571
+ else
572
+ optimize1(options)
573
+ end
536
574
  end
537
575
  when :OR
538
- if left == right
576
+ case left
577
+ when EverythingNode
578
+ left
579
+ when NothingNode
539
580
  left
540
581
  else
541
- if MultinaryExpressionNode === left
542
- if left.op == op
543
- left.merge(right, fallback: self)
544
- else
545
- optimize1(options)
546
- end
582
+ if left == right
583
+ left
547
584
  else
548
- if MultinaryExpressionNode === right
549
- if right.op == op
550
- right.merge(left, fallback: self)
585
+ if MultinaryExpressionNode === left
586
+ if left.op == op
587
+ left.merge(right, fallback: self)
551
588
  else
552
589
  optimize1(options)
553
590
  end
554
591
  else
555
- MultinaryExpressionNode.new(op, [left, right], fallback: self)
592
+ if MultinaryExpressionNode === right
593
+ if right.op == op
594
+ right.merge(left, fallback: self)
595
+ else
596
+ optimize1(options)
597
+ end
598
+ else
599
+ MultinaryExpressionNode.new(op, [left, right], fallback: self)
600
+ end
556
601
  end
557
602
  end
558
603
  end
@@ -619,8 +664,8 @@ module Hotdog
619
664
  attr_reader :op, :expressions
620
665
 
621
666
  def initialize(op, expressions, options={})
622
- case op
623
- when :OR
667
+ case (op || "or").to_s
668
+ when "||", "|", /\Aor\z/i
624
669
  @op = :OR
625
670
  else
626
671
  raise(SyntaxError.new("unknown multinary operator: #{op.inspect}"))
@@ -686,14 +731,16 @@ module Hotdog
686
731
  end
687
732
 
688
733
  class QueryExpressionNode < ExpressionNode
689
- def initialize(query, args=[], options={})
734
+ def initialize(query, values=[], options={})
690
735
  @query = query
691
- @args = args
736
+ @values = values
692
737
  @fallback = options[:fallback]
693
738
  end
739
+ attr_reader :query
740
+ attr_reader :values
694
741
 
695
742
  def evaluate(environment, options={})
696
- values = environment.execute(@query, @args).map { |row| row.first }
743
+ values = environment.execute(@query, @values).map { |row| row.first }
697
744
  if values.empty? and @fallback
698
745
  @fallback.evaluate(environment, options).tap do |values|
699
746
  if values.empty?
@@ -706,12 +753,32 @@ module Hotdog
706
753
  end
707
754
 
708
755
  def dump(options={})
709
- data = {query: @query, arguments: @args}
756
+ data = {query: @query, values: @values}
710
757
  data[:fallback] = @fallback.dump(options) if @fallback
711
758
  data
712
759
  end
713
760
  end
714
761
 
762
+ class EverythingNode < QueryExpressionNode
763
+ def initialize(options={})
764
+ super("SELECT id AS host_id FROM hosts", [], options)
765
+ end
766
+ end
767
+
768
+ class NothingNode < QueryExpressionNode
769
+ def initialize(options={})
770
+ super("SELECT NULL AS host_id WHERE host_id NOT NULL", [], options)
771
+ end
772
+
773
+ def evaluate(environment, options={})
774
+ if @fallback
775
+ @fallback.evaluate(environment, options)
776
+ else
777
+ []
778
+ end
779
+ end
780
+ end
781
+
715
782
  class TagExpressionNode < ExpressionNode
716
783
  def initialize(identifier, attribute, separator=nil)
717
784
  @identifier = identifier
@@ -878,24 +945,6 @@ module Hotdog
878
945
  end
879
946
  end
880
947
 
881
- class AnyTagNode < TagExpressionNode
882
- def initialize(separator=nil)
883
- super(nil, nil, separator)
884
- end
885
-
886
- def condition(options={})
887
- "1"
888
- end
889
-
890
- def condition_tables(options={})
891
- [:tags]
892
- end
893
-
894
- def condition_values(options={})
895
- []
896
- end
897
- end
898
-
899
948
  class StringExpressionNode < TagExpressionNode
900
949
  end
901
950
 
@@ -39,17 +39,6 @@ module Hotdog
39
39
  end
40
40
  end
41
41
 
42
- def parse_options(optparse, args=[])
43
- if args.index("--")
44
- @remote_command = args.slice(args.index("--") + 1, args.length).join(" ")
45
- optparse.parse(args.slice(0, args.index("--")))
46
- else
47
- @remote_command = nil
48
- optparse.parse(args)
49
- end
50
- end
51
- attr_reader :remote_command
52
-
53
42
  def run(args=[], options={})
54
43
  expression = args.join(" ").strip
55
44
  if expression.empty?
@@ -1,3 +1,3 @@
1
1
  module Hotdog
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.2"
3
3
  end
@@ -69,10 +69,11 @@ describe "tag glob expression" do
69
69
  expr = Hotdog::Commands::Search::GlobTagValueNode.new("foo*", ":")
70
70
  q = [
71
71
  "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
72
+ "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
72
73
  "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
73
- "WHERE LOWER(tags.value) GLOB LOWER(?);",
74
+ "WHERE LOWER(hosts.name) GLOB LOWER(?) OR LOWER(tags.value) GLOB LOWER(?);",
74
75
  ]
75
- allow(cmd).to receive(:execute).with(q.join(" "), ["foo*"]) {
76
+ allow(cmd).to receive(:execute).with(q.join(" "), ["foo*", "foo*"]) {
76
77
  [[1], [2], [3]]
77
78
  }
78
79
  expect(expr.evaluate(cmd)).to eq([1, 2, 3])
@@ -83,10 +84,11 @@ describe "tag glob expression" do
83
84
  expr = Hotdog::Commands::Search::GlobTagValueNode.new("foo*", nil)
84
85
  q = [
85
86
  "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
87
+ "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
86
88
  "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
87
- "WHERE LOWER(tags.value) GLOB LOWER(?);",
89
+ "WHERE LOWER(hosts.name) GLOB LOWER(?) OR LOWER(tags.value) GLOB LOWER(?);",
88
90
  ]
89
- allow(cmd).to receive(:execute).with(q.join(" "), ["foo*"]) {
91
+ allow(cmd).to receive(:execute).with(q.join(" "), ["foo*", "foo*"]) {
90
92
  [[1], [2], [3]]
91
93
  }
92
94
  expect(expr.evaluate(cmd)).to eq([1, 2, 3])
@@ -69,10 +69,11 @@ describe "tag regexp expression" do
69
69
  expr = Hotdog::Commands::Search::RegexpTagValueNode.new("foo", ":")
70
70
  q = [
71
71
  "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
72
+ "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
72
73
  "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
73
- "WHERE tags.value REGEXP ?;",
74
+ "WHERE hosts.name REGEXP ? OR tags.value REGEXP ?;",
74
75
  ]
75
- allow(cmd).to receive(:execute).with(q.join(" "), ["foo"]) {
76
+ allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "foo"]) {
76
77
  [[1], [2], [3]]
77
78
  }
78
79
  expect(expr.evaluate(cmd)).to eq([1, 2, 3])
@@ -83,10 +84,11 @@ describe "tag regexp expression" do
83
84
  expr = Hotdog::Commands::Search::RegexpTagValueNode.new("foo", nil)
84
85
  q = [
85
86
  "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
87
+ "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
86
88
  "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
87
- "WHERE tags.value REGEXP ?;",
89
+ "WHERE hosts.name REGEXP ? OR tags.value REGEXP ?;",
88
90
  ]
89
- allow(cmd).to receive(:execute).with(q.join(" "), ["foo"]) {
91
+ allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "foo"]) {
90
92
  [[1], [2], [3]]
91
93
  }
92
94
  expect(expr.evaluate(cmd)).to eq([1, 2, 3])
@@ -69,10 +69,11 @@ describe "tag expression" do
69
69
  expr = Hotdog::Commands::Search::StringTagValueNode.new("foo", ":")
70
70
  q = [
71
71
  "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
72
+ "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
72
73
  "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
73
- "WHERE tags.value = ?;",
74
+ "WHERE hosts.name = ? OR tags.value = ?;",
74
75
  ]
75
- allow(cmd).to receive(:execute).with(q.join(" "), ["foo"]) {
76
+ allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "foo"]) {
76
77
  [[1], [2], [3]]
77
78
  }
78
79
  expect(expr.evaluate(cmd)).to eq([1, 2, 3])
@@ -83,10 +84,11 @@ describe "tag expression" do
83
84
  expr = Hotdog::Commands::Search::StringTagValueNode.new("foo", nil)
84
85
  q = [
85
86
  "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags",
87
+ "INNER JOIN hosts ON hosts_tags.host_id = hosts.id",
86
88
  "INNER JOIN tags ON hosts_tags.tag_id = tags.id",
87
- "WHERE tags.value = ?;",
89
+ "WHERE hosts.name = ? OR tags.value = ?;",
88
90
  ]
89
- allow(cmd).to receive(:execute).with(q.join(" "), ["foo"]) {
91
+ allow(cmd).to receive(:execute).with(q.join(" "), ["foo", "foo"]) {
90
92
  [[1], [2], [3]]
91
93
  }
92
94
  expect(expr.evaluate(cmd)).to eq([1, 2, 3])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hotdog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yamashita Yuu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-08 00:00:00.000000000 Z
11
+ date: 2015-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler