hotdog 0.1.18 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/README.md +2 -0
- data/hotdog.gemspec +1 -0
- data/lib/hotdog/commands/down.rb +3 -3
- data/lib/hotdog/commands/hosts.rb +3 -11
- data/lib/hotdog/commands/search.rb +146 -92
- data/lib/hotdog/commands/tags.rb +23 -17
- data/lib/hotdog/commands/up.rb +3 -3
- data/lib/hotdog/commands.rb +145 -195
- data/lib/hotdog/formatters/ltsv.rb +9 -4
- data/lib/hotdog/formatters/plain.rb +1 -1
- data/lib/hotdog/version.rb +1 -1
- data/spec/core/application_spec.rb +36 -0
- data/spec/formatter/csv_spec.rb +33 -0
- data/spec/formatter/json_spec.rb +66 -0
- data/spec/formatter/ltsv_spec.rb +32 -0
- data/spec/formatter/plain_spec.rb +76 -0
- data/spec/formatter/text_spec.rb +76 -0
- data/spec/formatter/tsv_spec.rb +33 -0
- data/spec/formatter/yaml_spec.rb +49 -0
- data/spec/parser/parser_spec.rb +300 -0
- data/spec/parser/tag_expression_spec.rb +63 -0
- data/spec/parser/tag_glob_expression_spec.rb +63 -0
- data/spec/parser/tag_regexp_expression_spec.rb +63 -0
- data/spec/spec_helper.rb +1 -0
- metadata +44 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 017715f50e986cf3c0f61cb4834859c296ddf6f7
|
4
|
+
data.tar.gz: 137f2e8504b9c9908635b8dfe7db6d2b1541be9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3b406633a8f174b328dca17c976b4585d6e187f8cefc2dfe7c19ca094f2469faf292a1335d8aaea75f8e440c7d24f1878782710ac9b4c8456cea65466ced87cc
|
7
|
+
data.tar.gz: a1f2843dd806045110b64c915c8fda049f1a228654e8fc1282f5aa057280e129ecd5da06ca88a80db37b0f35c3c3054ec6e57338fb20d0e9ca176169fb17811c
|
data/.travis.yml
ADDED
data/README.md
CHANGED
data/hotdog.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.7"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.3.0"
|
23
24
|
|
24
25
|
spec.add_dependency "dogapi", ">= 1.13.0"
|
25
26
|
spec.add_dependency "parslet", "~> 1.6.2"
|
data/lib/hotdog/commands/down.rb
CHANGED
@@ -29,9 +29,9 @@ module Hotdog
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# Remove persistent.db to schedule update on next invocation
|
32
|
-
if
|
33
|
-
@db
|
34
|
-
FileUtils.rm_f(File.join(
|
32
|
+
if @db
|
33
|
+
close_db(@db)
|
34
|
+
FileUtils.rm_f(File.join(options[:confdir], PERSISTENT_DB))
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -6,21 +6,13 @@ module Hotdog
|
|
6
6
|
def run(args=[])
|
7
7
|
args = optparse.parse(args)
|
8
8
|
if args.empty?
|
9
|
-
result = execute("SELECT
|
9
|
+
result = execute("SELECT id FROM hosts").to_a.reduce(:+)
|
10
10
|
else
|
11
11
|
result = args.map { |host_name|
|
12
12
|
if glob?(host_name)
|
13
|
-
execute(
|
14
|
-
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
15
|
-
INNER JOIN hosts ON hosts_tags.host_id = hosts.id
|
16
|
-
WHERE LOWER(hosts.name) GLOB LOWER(?);
|
17
|
-
EOS
|
13
|
+
execute("SELECT id FROM hosts WHERE name GLOB ?", [host_name]).to_a.reduce(:+)
|
18
14
|
else
|
19
|
-
execute(
|
20
|
-
SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
|
21
|
-
INNER JOIN hosts ON hosts_tags.host_id = hosts.id
|
22
|
-
WHERE LOWER(hosts.name) = LOWER(?);
|
23
|
-
EOS
|
15
|
+
execute("SELECT id FROM hosts WHERE name = ?", [host_name]).to_a.reduce(:+)
|
24
16
|
end
|
25
17
|
}.reduce(:+)
|
26
18
|
end
|
@@ -15,7 +15,8 @@ module Hotdog
|
|
15
15
|
args = optparse.parse(args)
|
16
16
|
expression = args.join(" ").strip
|
17
17
|
if expression.empty?
|
18
|
-
|
18
|
+
# return everything if given expression is empty
|
19
|
+
expression = "*"
|
19
20
|
end
|
20
21
|
|
21
22
|
begin
|
@@ -70,9 +71,9 @@ module Hotdog
|
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
|
-
def evaluate(
|
74
|
-
node = ExpressionTransformer.new.apply(
|
75
|
-
node.evaluate(environment)
|
74
|
+
def evaluate(data, environment)
|
75
|
+
node = ExpressionTransformer.new.apply(data)
|
76
|
+
node.optimize.evaluate(environment)
|
76
77
|
end
|
77
78
|
|
78
79
|
class ExpressionParser < Parslet::Parser
|
@@ -82,18 +83,27 @@ module Hotdog
|
|
82
83
|
| term \
|
83
84
|
)
|
84
85
|
}
|
86
|
+
rule(:binary_op) {
|
87
|
+
( str('&') >> str('&').maybe \
|
88
|
+
| str('|') >> str('|').maybe \
|
89
|
+
| match('[Aa]') >> match('[Nn]') >> match('[Dd]') \
|
90
|
+
| match('[Oo]') >> match('[Rr]') \
|
91
|
+
)
|
92
|
+
}
|
85
93
|
rule(:binary_expression) {
|
86
|
-
( term.as(:left) >> spacing.maybe >>
|
87
|
-
| term.as(:left) >> spacing.maybe >> (str('|') >> str('|').maybe).as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
88
|
-
| term.as(:left) >> spacing.maybe >> (match('[Aa]') >> match('[Nn]') >> match('[Dd]')).as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
89
|
-
| term.as(:left) >> spacing.maybe >> (match('[Oo]') >> match('[Rr]')).as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
94
|
+
( term.as(:left) >> spacing.maybe >> binary_op.as(:binary_op) >> spacing.maybe >> expression.as(:right) \
|
90
95
|
| term.as(:left) >> spacing.maybe.as(:binary_op) >> expression.as(:right) \
|
91
96
|
)
|
92
97
|
}
|
98
|
+
rule(:unary_op) {
|
99
|
+
( str('!') \
|
100
|
+
| str('~') \
|
101
|
+
| match('[Nn]') >> match('[Oo]') >> match('[Tt]') \
|
102
|
+
)
|
103
|
+
}
|
93
104
|
rule(:unary_expression) {
|
94
|
-
( spacing.maybe >>
|
95
|
-
| spacing.maybe >>
|
96
|
-
| spacing.maybe >> (match('[Nn]') >> match('[Oo]') >> match('[Tt]')).as(:unary_op) >> atom.as(:expression) \
|
105
|
+
( spacing.maybe >> unary_op.as(:unary_op) >> term.as(:expression) \
|
106
|
+
| spacing.maybe >> unary_op.as(:unary_op) >> expression.as(:expression) \
|
97
107
|
)
|
98
108
|
}
|
99
109
|
rule(:term) {
|
@@ -114,8 +124,9 @@ module Hotdog
|
|
114
124
|
| spacing.maybe >> identifier.as(:identifier) >> separator >> attribute.as(:attribute) >> spacing.maybe \
|
115
125
|
| spacing.maybe >> identifier.as(:identifier) >> separator >> spacing.maybe \
|
116
126
|
| spacing.maybe >> identifier.as(:identifier) >> spacing.maybe \
|
127
|
+
| spacing.maybe >> separator >> attribute_regexp.as(:attribute_regexp) >> spacing.maybe \
|
117
128
|
| spacing.maybe >> separator >> attribute_glob.as(:attribute_glob) >> spacing.maybe \
|
118
|
-
| spacing.maybe >> separator >> attribute.as(:
|
129
|
+
| spacing.maybe >> separator >> attribute.as(:attribute) >> spacing.maybe \
|
119
130
|
| spacing.maybe >> attribute_regexp.as(:attribute_regexp) >> spacing.maybe \
|
120
131
|
| spacing.maybe >> attribute_glob.as(:attribute_glob) >> spacing.maybe \
|
121
132
|
| spacing.maybe >> attribute.as(:attribute) >> spacing.maybe \
|
@@ -126,11 +137,11 @@ module Hotdog
|
|
126
137
|
)
|
127
138
|
}
|
128
139
|
rule(:identifier_glob) {
|
129
|
-
( identifier.repeat(0) >> (glob >> identifier.maybe).repeat(1) \
|
140
|
+
( unary_op.absent? >> binary_op.absent? >> identifier.repeat(0) >> (glob >> identifier.maybe).repeat(1) \
|
130
141
|
)
|
131
142
|
}
|
132
143
|
rule(:identifier) {
|
133
|
-
( match('[A-Za-z]') >> match('[-./0-9A-Z_a-z]').repeat(0) \
|
144
|
+
( unary_op.absent? >> binary_op.absent? >> match('[A-Za-z]') >> match('[-./0-9A-Z_a-z]').repeat(0) \
|
134
145
|
)
|
135
146
|
}
|
136
147
|
rule(:separator) {
|
@@ -143,11 +154,11 @@ module Hotdog
|
|
143
154
|
)
|
144
155
|
}
|
145
156
|
rule(:attribute_glob) {
|
146
|
-
( attribute.repeat(0) >> (glob >> attribute.maybe).repeat(1) \
|
157
|
+
( unary_op.absent? >> binary_op.absent? >> attribute.repeat(0) >> (glob >> attribute.maybe).repeat(1) \
|
147
158
|
)
|
148
159
|
}
|
149
160
|
rule(:attribute) {
|
150
|
-
( match('[-./0-9:A-Z_a-z]').repeat(1) \
|
161
|
+
( unary_op.absent? >> binary_op.absent? >> match('[-./0-9:A-Z_a-z]').repeat(1) \
|
151
162
|
)
|
152
163
|
}
|
153
164
|
rule(:glob) {
|
@@ -205,20 +216,31 @@ module Hotdog
|
|
205
216
|
def evaluate(environment, options={})
|
206
217
|
raise(NotImplementedError)
|
207
218
|
end
|
219
|
+
|
220
|
+
def optimize(options={})
|
221
|
+
self
|
222
|
+
end
|
208
223
|
end
|
209
224
|
|
210
225
|
class BinaryExpressionNode < ExpressionNode
|
211
|
-
attr_reader :left, :right
|
226
|
+
attr_reader :op, :left, :right
|
212
227
|
|
213
228
|
def initialize(op, left, right)
|
214
|
-
|
215
|
-
|
229
|
+
case op || "or"
|
230
|
+
when "&&", "&", /\Aand\z/i
|
231
|
+
@op = :AND
|
232
|
+
when "||", "|", /\Aor\z/i
|
233
|
+
@op = :OR
|
234
|
+
else
|
235
|
+
raise(SyntaxError.new("unknown binary operator: #{op.inspect}"))
|
236
|
+
end
|
216
237
|
@left = left
|
217
238
|
@right = right
|
218
239
|
end
|
240
|
+
|
219
241
|
def evaluate(environment, options={})
|
220
242
|
case @op
|
221
|
-
when
|
243
|
+
when :AND
|
222
244
|
left_values = @left.evaluate(environment)
|
223
245
|
if left_values.empty?
|
224
246
|
[]
|
@@ -226,40 +248,73 @@ module Hotdog
|
|
226
248
|
right_values = @right.evaluate(environment)
|
227
249
|
(left_values & right_values)
|
228
250
|
end
|
229
|
-
when
|
251
|
+
when :OR
|
230
252
|
left_values = @left.evaluate(environment)
|
231
253
|
right_values = @right.evaluate(environment)
|
232
254
|
(left_values | right_values).uniq
|
233
255
|
else
|
234
|
-
|
256
|
+
[]
|
235
257
|
end
|
236
258
|
end
|
259
|
+
|
260
|
+
def optimize(options={})
|
261
|
+
@left = @left.optimize(options)
|
262
|
+
@right = @right.optimize(options)
|
263
|
+
if @left == @right
|
264
|
+
@left
|
265
|
+
else
|
266
|
+
self
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def ==(other)
|
271
|
+
self.class === other and @op == other.op and @left == other.left and @right == other.right
|
272
|
+
end
|
237
273
|
end
|
238
274
|
|
239
275
|
class UnaryExpressionNode < ExpressionNode
|
240
|
-
attr_reader :expression
|
276
|
+
attr_reader :op, :expression
|
241
277
|
|
242
278
|
def initialize(op, expression)
|
243
|
-
|
279
|
+
case op
|
280
|
+
when "!", "~", /\Anot\z/i
|
281
|
+
@op = :NOT
|
282
|
+
else
|
283
|
+
raise(SyntaxError.new("unknown unary operator: #{@op.inspect}"))
|
284
|
+
end
|
244
285
|
@expression = expression
|
245
286
|
end
|
287
|
+
|
246
288
|
def evaluate(environment, options={})
|
247
289
|
case @op
|
248
|
-
when
|
290
|
+
when :NOT
|
249
291
|
values = @expression.evaluate(environment)
|
250
292
|
if values.empty?
|
251
|
-
environment.execute(
|
252
|
-
SELECT DISTINCT host_id FROM hosts_tags;
|
253
|
-
EOS
|
293
|
+
environment.execute("SELECT DISTINCT host_id FROM hosts_tags").map { |row| row.first }
|
254
294
|
else
|
255
|
-
environment.execute(
|
256
|
-
SELECT DISTINCT host_id FROM hosts_tags WHERE host_id NOT IN (%s);
|
257
|
-
EOS
|
295
|
+
environment.execute("SELECT DISTINCT host_id FROM hosts_tags WHERE host_id NOT IN (%s)" % values.map { "?" }.join(", "), values).map { |row| row.first }
|
258
296
|
end
|
259
297
|
else
|
260
|
-
|
298
|
+
[]
|
261
299
|
end
|
262
300
|
end
|
301
|
+
|
302
|
+
def optimize(options={})
|
303
|
+
@expression = @expression.optimize(options)
|
304
|
+
if UnaryExpressionNode === @expression
|
305
|
+
if @op == :NOT and @expression.op == :NOT
|
306
|
+
@expression.expression
|
307
|
+
else
|
308
|
+
self
|
309
|
+
end
|
310
|
+
else
|
311
|
+
self
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
def ==(other)
|
316
|
+
self.class === other and @op == other.op and @expression == other.expression
|
317
|
+
end
|
263
318
|
end
|
264
319
|
|
265
320
|
class TagExpressionNode < ExpressionNode
|
@@ -269,43 +324,43 @@ module Hotdog
|
|
269
324
|
end
|
270
325
|
attr_reader :identifier
|
271
326
|
attr_reader :attribute
|
327
|
+
|
272
328
|
def identifier?
|
273
329
|
!(identifier.nil? or identifier.to_s.empty?)
|
274
330
|
end
|
331
|
+
|
275
332
|
def attribute?
|
276
333
|
!(attribute.nil? or attribute.to_s.empty?)
|
277
334
|
end
|
335
|
+
|
278
336
|
def evaluate(environment, options={})
|
337
|
+
q = []
|
279
338
|
if identifier?
|
280
339
|
if attribute?
|
281
340
|
case identifier
|
282
341
|
when /\Ahost\z/i
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
EOS
|
342
|
+
q << "SELECT hosts.id FROM hosts"
|
343
|
+
q << "WHERE hosts.name = ?;"
|
344
|
+
values = environment.execute(q.join(" "), [attribute]).map { |row| row.first }
|
287
345
|
else
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
EOS
|
346
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
347
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
348
|
+
q << "WHERE tags.name = ? AND tags.value = ?;"
|
349
|
+
values = environment.execute(q.join(" "), [identifier, attribute]).map { |row| row.first }
|
293
350
|
end
|
294
351
|
else
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
EOS
|
352
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
353
|
+
q << "INNER JOIN hosts ON hosts_tags.host_id = hosts.id"
|
354
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
355
|
+
q << "WHERE hosts.name = ? OR tags.name = ? OR tags.value = ?;"
|
356
|
+
values = environment.execute(q.join(" "), [identifier, identifier, identifier]).map { |row| row.first }
|
301
357
|
end
|
302
358
|
else
|
303
359
|
if attribute?
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
EOS
|
360
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
361
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
362
|
+
q << "WHERE tags.value = ?;"
|
363
|
+
values = environment.execute(q.join(" "), [attribute]).map { |row| row.first }
|
309
364
|
else
|
310
365
|
return []
|
311
366
|
end
|
@@ -317,6 +372,10 @@ module Hotdog
|
|
317
372
|
end
|
318
373
|
end
|
319
374
|
|
375
|
+
def ==(other)
|
376
|
+
self.class == other.class and @identifier == other.identifier and @attribute == other.attribute
|
377
|
+
end
|
378
|
+
|
320
379
|
def fallback(environment, options={})
|
321
380
|
if environment.fixed_string?
|
322
381
|
[]
|
@@ -352,36 +411,33 @@ module Hotdog
|
|
352
411
|
|
353
412
|
class TagGlobExpressionNode < TagExpressionNode
|
354
413
|
def evaluate(environment, options={})
|
414
|
+
q = []
|
355
415
|
if identifier?
|
356
416
|
if attribute?
|
357
417
|
case identifier
|
358
418
|
when /\Ahost\z/i
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
EOS
|
419
|
+
q << "SELECT hosts.id FROM hosts"
|
420
|
+
q << "WHERE hosts.name GLOB ?;"
|
421
|
+
values = environment.execute(q.join(" "), [attribute]).map { |row| row.first }
|
363
422
|
else
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
EOS
|
423
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
424
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
425
|
+
q << "WHERE tags.name GLOB ? AND tags.value GLOB ?;"
|
426
|
+
values = environment.execute(q.join(" "), [identifier, attribute]).map { |row| row.first }
|
369
427
|
end
|
370
428
|
else
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
EOS
|
429
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
430
|
+
q << "INNER JOIN hosts ON hosts_tags.host_id = hosts.id"
|
431
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
432
|
+
q << "WHERE hosts.name GLOB ? OR tags.name GLOB ? OR tags.value GLOB ?;"
|
433
|
+
values = environment.execute(q.join(" "), [identifier, identifier, identifier]).map { |row| row.first }
|
377
434
|
end
|
378
435
|
else
|
379
436
|
if attribute?
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
EOS
|
437
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
438
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
439
|
+
q << "WHERE tags.value GLOB ?;"
|
440
|
+
values = environment.execute(q.join(" "), [attribute]).map { |row| row.first }
|
385
441
|
else
|
386
442
|
return []
|
387
443
|
end
|
@@ -400,37 +456,35 @@ module Hotdog
|
|
400
456
|
attribute = attribute.sub(%r{\A/(.*)/\z}) { $1 } if attribute
|
401
457
|
super(identifier, attribute)
|
402
458
|
end
|
459
|
+
|
403
460
|
def evaluate(environment, options={})
|
461
|
+
q = []
|
404
462
|
if identifier?
|
405
463
|
if attribute?
|
406
464
|
case identifier
|
407
465
|
when /\Ahost\z/i
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
EOS
|
466
|
+
q << "SELECT hosts.id FROM hosts"
|
467
|
+
q << "WHERE hosts.name REGEXP ?;"
|
468
|
+
values = environment.execute(q.join(" "), [attribute]).map { |row| row.first }
|
412
469
|
else
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
EOS
|
470
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
471
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
472
|
+
q << "WHERE tags.name REGEXP ? AND tags.value REGEXP ?;"
|
473
|
+
values = environment.execute(q.join(" "), [identifier, attribute]).map { |row| row.first }
|
418
474
|
end
|
419
475
|
else
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
EOS
|
476
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
477
|
+
q << "INNER JOIN hosts ON hosts_tags.host_id = hosts.id"
|
478
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
479
|
+
q << "WHERE hosts.name REGEXP ? OR tags.name REGEXP ? OR tags.value REGEXP ?;"
|
480
|
+
values = environment.execute(q.join(" "), [identifier, identifier, identifier]).map { |row| row.first }
|
426
481
|
end
|
427
482
|
else
|
428
483
|
if attribute?
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
EOS
|
484
|
+
q << "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags"
|
485
|
+
q << "INNER JOIN tags ON hosts_tags.tag_id = tags.id"
|
486
|
+
q << "WHERE tags.value REGEXP ?;"
|
487
|
+
values = environment.execute(q.join(" "), [attribute]).map { |row| row.first }
|
434
488
|
else
|
435
489
|
return []
|
436
490
|
end
|
data/lib/hotdog/commands/tags.rb
CHANGED
@@ -7,22 +7,31 @@ module Hotdog
|
|
7
7
|
args = optparse.parse(args)
|
8
8
|
if 0 < args.length
|
9
9
|
fields = args.map { |tag|
|
10
|
-
tag_name, tag_value = tag
|
10
|
+
tag_name, tag_value = split_tag(tag)
|
11
11
|
tag_name
|
12
12
|
}
|
13
|
-
result1 =
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
result1 = args.map { |tag|
|
14
|
+
tag_name, tag_value = split_tag(tag)
|
15
|
+
if glob?(tag_name)
|
16
|
+
if tag_value.empty?
|
17
|
+
execute("SELECT DISTINCT value FROM tags WHERE name GLOB ?", [tag_name]).map { |row| row.join(",") }
|
18
|
+
else
|
19
|
+
if glob?(tag_value)
|
20
|
+
execute("SELECT DISTINCT value FROM tags WHERE name GLOB ? AND value GLOB ?", [tag_name, tag_value]).map { |row| row.join(",") }
|
21
|
+
else
|
22
|
+
execute("SELECT DISTINCT value FROM tags WHERE name GLOB ? AND value = ?", [tag_name, tag_value]).map { |row| row.join(",") }
|
23
|
+
end
|
24
|
+
end
|
20
25
|
else
|
21
|
-
|
22
|
-
SELECT DISTINCT
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
if tag_value.empty?
|
27
|
+
execute("SELECT DISTINCT value FROM tags WHERE name = ?", [tag_name]).map { |row| row.join(",") }
|
28
|
+
else
|
29
|
+
if glob?(tag_value)
|
30
|
+
execute("SELECT DISTINCT value FROM tags WHERE name = ? AND value GLOB ?", [tag_name, tag_value]).map { |row| row.join(",") }
|
31
|
+
else
|
32
|
+
execute("SELECT DISTINCT value FROM tags WHERE name = ? AND value = ?", [tag_name, tag_value]).map { |row| row.join(",") }
|
33
|
+
end
|
34
|
+
end
|
26
35
|
end
|
27
36
|
}
|
28
37
|
result = (0...result1.reduce(0) { |max, values| [max, values.length].max }).map { |field_index|
|
@@ -30,10 +39,7 @@ module Hotdog
|
|
30
39
|
}
|
31
40
|
else
|
32
41
|
fields = ["tag"]
|
33
|
-
result = execute(
|
34
|
-
SELECT DISTINCT tags.name, tags.value FROM hosts_tags
|
35
|
-
INNER JOIN tags ON hosts_tags.tag_id = tags.id;
|
36
|
-
EOS
|
42
|
+
result = execute("SELECT DISTINCT name, value FROM tags").map { |name, value| [0 < value.length ? "#{name}:#{value}" : name] }
|
37
43
|
end
|
38
44
|
if 0 < result.length
|
39
45
|
STDOUT.print(format(result, fields: fields))
|
data/lib/hotdog/commands/up.rb
CHANGED
@@ -31,9 +31,9 @@ module Hotdog
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# Remove persistent.db to schedule update on next invocation
|
34
|
-
if
|
35
|
-
@db
|
36
|
-
FileUtils.rm_f(File.join(
|
34
|
+
if @db
|
35
|
+
close_db(@db)
|
36
|
+
FileUtils.rm_f(File.join(options[:confdir], PERSISTENT_DB))
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|