hotdog 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hotdog/commands/pssh.rb +0 -11
- data/lib/hotdog/commands/search.rb +96 -47
- data/lib/hotdog/commands/ssh.rb +0 -11
- data/lib/hotdog/version.rb +1 -1
- data/spec/parser/glob_expression_spec.rb +6 -4
- data/spec/parser/regexp_expression_spec.rb +6 -4
- data/spec/parser/string_expression_spec.rb +6 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91215663a09880593d00a5067b5f65ce3cb4b288
|
4
|
+
data.tar.gz: e840f3478257b84e516d4af7f6c4464cdaa7306b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8beeb9c046d7467a48025aa7156f9b8e04c19f3923eb544086b5bec52f7cc0afddae29cad26cd699803fe0046c623e0179159917a3dc5e41b2996a0b39ae8246
|
7
|
+
data.tar.gz: 199c17a2d104dbb24c5135ac2cc180b9a26f594b1d2aaf9eb1870f3ba6e7b209a27b6b08d061c34598877ed385b4accb505d35ee3543f79f95554668b56b5695
|
data/lib/hotdog/commands/pssh.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
563
|
+
case left
|
564
|
+
when EverythingNode
|
565
|
+
right
|
566
|
+
when NothingNode
|
533
567
|
left
|
534
568
|
else
|
535
|
-
|
569
|
+
if left == right
|
570
|
+
left
|
571
|
+
else
|
572
|
+
optimize1(options)
|
573
|
+
end
|
536
574
|
end
|
537
575
|
when :OR
|
538
|
-
|
576
|
+
case left
|
577
|
+
when EverythingNode
|
578
|
+
left
|
579
|
+
when NothingNode
|
539
580
|
left
|
540
581
|
else
|
541
|
-
if
|
542
|
-
|
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 ===
|
549
|
-
if
|
550
|
-
|
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
|
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
|
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,
|
734
|
+
def initialize(query, values=[], options={})
|
690
735
|
@query = query
|
691
|
-
@
|
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, @
|
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,
|
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
|
|
data/lib/hotdog/commands/ssh.rb
CHANGED
@@ -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?
|
data/lib/hotdog/version.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2015-10-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|