Class: Hotdog::Commands::Search::TagExpressionNode

Inherits:
ExpressionNode show all
Defined in:
lib/hotdog/commands/search.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ExpressionNode

#optimize

Constructor Details

#initialize(identifier, attribute) ⇒ TagExpressionNode

Returns a new instance of TagExpressionNode.



353
354
355
356
# File 'lib/hotdog/commands/search.rb', line 353

def initialize(identifier, attribute)
  @identifier = identifier
  @attribute = attribute
end

Instance Attribute Details

#attributeObject (readonly)

Returns the value of attribute attribute.



358
359
360
# File 'lib/hotdog/commands/search.rb', line 358

def attribute
  @attribute
end

#identifierObject (readonly)

Returns the value of attribute identifier.



357
358
359
# File 'lib/hotdog/commands/search.rb', line 357

def identifier
  @identifier
end

Instance Method Details

#==(other) ⇒ Object



406
407
408
# File 'lib/hotdog/commands/search.rb', line 406

def ==(other)
  self.class == other.class and @identifier == other.identifier and @attribute == other.attribute
end

#attribute?Boolean

Returns:

  • (Boolean)


364
365
366
# File 'lib/hotdog/commands/search.rb', line 364

def attribute?
  !(attribute.nil? or attribute.to_s.empty?)
end

#evaluate(environment, options = {}) ⇒ Object



368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/hotdog/commands/search.rb', line 368

def evaluate(environment, options={})
  if identifier?
    if attribute?
      case identifier
      when /\Ahost\z/i
        q = "SELECT hosts.id FROM hosts " \
              "WHERE hosts.name = ?;"
        values = environment.execute(q, [attribute]).map { |row| row.first }
      else
        q = "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags " \
              "INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
                "WHERE tags.name = ? AND tags.value = ?;"
        values = environment.execute(q, [identifier, attribute]).map { |row| row.first }
      end
    else
      q = "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags " \
            "INNER JOIN hosts ON hosts_tags.host_id = hosts.id " \
            "INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
              "WHERE hosts.name = ? OR tags.name = ? OR tags.value = ?;"
      values = environment.execute(q, [identifier, identifier, identifier]).map { |row| row.first }
    end
  else
    if attribute?
       q = "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags " \
             "INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
               "WHERE tags.value = ?;"
      values = environment.execute(q, [attribute]).map { |row| row.first }
    else
      return []
    end
  end
  if values.empty?
    fallback(environment, options)
  else
    values
  end
end

#fallback(environment, options = {}) ⇒ Object



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'lib/hotdog/commands/search.rb', line 410

def fallback(environment, options={})
  if environment.fixed_string?
    []
  else
    # fallback to glob expression
    identifier_glob = identifier.gsub(/[-.\/_]/, "?") if identifier?
    attribute_glob = attribute.gsub(/[-.\/_]/, "?") if attribute?
    if (identifier? and identifier != identifier_glob) or (attribute? and attribute != attribute_glob)
      environment.logger.info("fallback to glob expression: %s:%s" % [identifier_glob, attribute_glob])
      values = TagGlobExpressionNode.new(identifier_glob, attribute_glob).evaluate(environment, options)
      if values.empty?
        reload(environment, options)
      else
        values
      end
    else
      []
    end
  end
end

#identifier?Boolean

Returns:

  • (Boolean)


360
361
362
# File 'lib/hotdog/commands/search.rb', line 360

def identifier?
  !(identifier.nil? or identifier.to_s.empty?)
end

#reload(environment, options = {}) ⇒ Object



431
432
433
434
435
436
437
438
439
440
# File 'lib/hotdog/commands/search.rb', line 431

def reload(environment, options={})
  ttl = options.fetch(:ttl, 1)
  if 0 < ttl
    environment.logger.info("force reloading all hosts and tags.")
    environment.reload(force: true)
    self.class.new(identifier, attribute).evaluate(environment, options.merge(ttl: ttl-1))
  else
    []
  end
end