hotdog 0.1.18 → 0.2.0

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: 8deb5895caacf3aa169eaeb03aec5beb9a71a4d0
4
- data.tar.gz: 9f26224eff745ee809401e997040509eea818d10
3
+ metadata.gz: 017715f50e986cf3c0f61cb4834859c296ddf6f7
4
+ data.tar.gz: 137f2e8504b9c9908635b8dfe7db6d2b1541be9b
5
5
  SHA512:
6
- metadata.gz: 5b77afe9612c45e00862544ae90c2d01dfa8dd5f4eeff755ec2c431ae17d98ac702df9e655b26819f771978a7b4e3a75ec8403230c863f932251aa9225697c19
7
- data.tar.gz: 14e5e13f1d5f0e4532b5ca7b7cd981cb2eda765b24af1575bf5448acaf07426402dcebc3f774c611e746f99d8a70950cddb44ab9643ec85bcf65307a47a0e711
6
+ metadata.gz: 3b406633a8f174b328dca17c976b4585d6e187f8cefc2dfe7c19ca094f2469faf292a1335d8aaea75f8e440c7d24f1878782710ac9b4c8456cea65466ced87cc
7
+ data.tar.gz: a1f2843dd806045110b64c915c8fda049f1a228654e8fc1282f5aa057280e129ecd5da06ca88a80db37b0f35c3c3054ec6e57338fb20d0e9ca176169fb17811c
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.6
4
+ - 2.2.3
5
+ script: rspec spec
6
+ sudo: false
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Hotdog
2
2
 
3
+ [![Build Status](https://travis-ci.org/yyuu/hotdog.svg)](https://travis-ci.org/yyuu/hotdog)
4
+
3
5
  Yet another command-line tools for [Datadog](https://www.datadoghq.com/).
4
6
 
5
7
  ## Installation
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"
@@ -29,9 +29,9 @@ module Hotdog
29
29
  end
30
30
 
31
31
  # Remove persistent.db to schedule update on next invocation
32
- if not @db.nil?
33
- @db.close
34
- FileUtils.rm_f(File.join(@options[:confdir], PERSISTENT_DB))
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 DISTINCT host_id FROM hosts_tags").to_a.reduce(:+)
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(<<-EOS, host_name).map { |row| row.first }
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(<<-EOS, host_name).map { |row| row.first }
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
- exit(1)
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(node, environment)
74
- node = ExpressionTransformer.new.apply(node)
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 >> (str('&') >> str('&').maybe).as(:binary_op) >> spacing.maybe >> expression.as(:right) \
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 >> str('!').as(:unary_op) >> atom.as(:expression) \
95
- | spacing.maybe >> str('~').as(:unary_op) >> atom.as(:expression) \
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(:attribute_glob) >> spacing.maybe \
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
- @op = op
215
- @op ||= "or" # use OR expression by default
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 "&&", "&", /\Aand\z/i
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 "||", "|", /\Aor\z/i
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
- raise(SyntaxError.new("unknown binary operator: #{@op.inspect}"))
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
- @op = op
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 "!", "~", /\Anot\z/i
290
+ when :NOT
249
291
  values = @expression.evaluate(environment)
250
292
  if values.empty?
251
- environment.execute(<<-EOS).map { |row| row.first }
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(<<-EOS % values.map { "?" }.join(", "), values).map { |row| row.first }
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
- raise(SyntaxError.new("unknown unary operator: #{@op.inspect}"))
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
- values = environment.execute(<<-EOS, attribute).map { |row| row.first }
284
- SELECT hosts.id FROM hosts
285
- WHERE LOWER(hosts.name) = LOWER(?);
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
- values = environment.execute(<<-EOS, identifier, attribute).map { |row| row.first }
289
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
290
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
291
- WHERE LOWER(tags.name) = LOWER(?) AND LOWER(tags.value) = LOWER(?);
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
- values = environment.execute(<<-EOS, identifier, identifier, identifier).map { |row| row.first }
296
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
297
- INNER JOIN hosts ON hosts_tags.host_id = hosts.id
298
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
299
- WHERE LOWER(hosts.name) = LOWER(?) OR LOWER(tags.name) = LOWER(?) OR LOWER(tags.value) = LOWER(?);
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
- values = environment.execute(<<-EOS, attribute).map { |row| row.first }
305
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
306
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
307
- WHERE LOWER(tags.value) = LOWER(?);
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
- values = environment.execute(<<-EOS, attribute).map { |row| row.first }
360
- SELECT hosts.id FROM hosts
361
- WHERE LOWER(hosts.name) GLOB LOWER(?);
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
- values = environment.execute(<<-EOS, identifier, attribute).map { |row| row.first }
365
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
366
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
367
- WHERE LOWER(tags.name) GLOB LOWER(?) AND LOWER(tags.value) GLOB LOWER(?);
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
- values = environment.execute(<<-EOS, identifier, identifier, identifier).map { |row| row.first }
372
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
373
- INNER JOIN hosts ON hosts_tags.host_id = hosts.id
374
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
375
- WHERE LOWER(hosts.name) GLOB LOWER(?) OR LOWER(tags.name) GLOB LOWER(?) OR LOWER(tags.value) GLOB LOWER(?);
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
- values = environment.execute(<<-EOS, attribute).map { |row| row.first }
381
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
382
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
383
- WHERE LOWER(tags.value) GLOB LOWER(?);
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
- values = environment.execute(<<-EOS, attribute).map { |row| row.first }
409
- SELECT hosts.id FROM hosts
410
- WHERE LOWER(hosts.name) REGEXP LOWER(?);
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
- values = environment.execute(<<-EOS, identifier, attribute).map { |row| row.first }
414
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
415
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
416
- WHERE LOWER(tags.name) REGEXP LOWER(?) AND LOWER(tags.value) REGEXP LOWER(?);
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
- values = environment.execute(<<-EOS, identifier, identifier, identifier).map { |row| row.first }
421
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
422
- INNER JOIN hosts ON hosts_tags.host_id = hosts.id
423
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
424
- WHERE LOWER(hosts.name) REGEXP LOWER(?) OR LOWER(tags.name) REGEXP LOWER(?) OR LOWER(tags.value) REGEXP LOWER(?);
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
- values = environment.execute(<<-EOS, attribute).map { |row| row.first }
430
- SELECT DISTINCT hosts_tags.host_id FROM hosts_tags
431
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
432
- WHERE LOWER(tags.value) REGEXP LOWER(?);
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
@@ -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.split(":", 2)
10
+ tag_name, tag_value = split_tag(tag)
11
11
  tag_name
12
12
  }
13
- result1 = fields.map { |tag_name|
14
- if not glob?(tag_name)
15
- execute(<<-EOS, tag_name).map { |row| row.join(",") }
16
- SELECT DISTINCT tags.value FROM hosts_tags
17
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
18
- WHERE tags.name = LOWER(?);
19
- EOS
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
- execute(<<-EOS, tag_name).map { |row| row.join(",") }
22
- SELECT DISTINCT tags.value FROM hosts_tags
23
- INNER JOIN tags ON hosts_tags.tag_id = tags.id
24
- WHERE tags.name GLOB LOWER(?);
25
- EOS
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(<<-EOS).map { |name, value| [0 < value.length ? "#{name}:#{value}" : name] }
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))
@@ -31,9 +31,9 @@ module Hotdog
31
31
  end
32
32
 
33
33
  # Remove persistent.db to schedule update on next invocation
34
- if not @db.nil?
35
- @db.close
36
- FileUtils.rm_f(File.join(@options[:confdir], PERSISTENT_DB))
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