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

#intermediates, #leafs

Constructor Details

#initialize(identifier, attribute, separator = nil) ⇒ TagExpressionNode



783
784
785
786
787
788
# File 'lib/hotdog/commands/search.rb', line 783

def initialize(identifier, attribute, separator=nil)
  @identifier = identifier
  @attribute = attribute
  @separator = separator
  @fallback = nil
end

Instance Attribute Details

#attributeObject (readonly)

Returns the value of attribute attribute.



790
791
792
# File 'lib/hotdog/commands/search.rb', line 790

def attribute
  @attribute
end

#identifierObject (readonly)

Returns the value of attribute identifier.



789
790
791
# File 'lib/hotdog/commands/search.rb', line 789

def identifier
  @identifier
end

#separatorObject (readonly)

Returns the value of attribute separator.



791
792
793
# File 'lib/hotdog/commands/search.rb', line 791

def separator
  @separator
end

Instance Method Details

#==(other) ⇒ Object



886
887
888
# File 'lib/hotdog/commands/search.rb', line 886

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

#attribute?Boolean



797
798
799
# File 'lib/hotdog/commands/search.rb', line 797

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

#condition(options = {}) ⇒ Object

Raises:

  • (NotImplementedError)


831
832
833
# File 'lib/hotdog/commands/search.rb', line 831

def condition(options={})
  raise(NotImplementedError.new("must be overridden"))
end

#condition_tables(options = {}) ⇒ Object

Raises:

  • (NotImplementedError)


835
836
837
# File 'lib/hotdog/commands/search.rb', line 835

def condition_tables(options={})
  raise(NotImplementedError.new("must be overridden"))
end

#condition_values(options = {}) ⇒ Object

Raises:

  • (NotImplementedError)


839
840
841
# File 'lib/hotdog/commands/search.rb', line 839

def condition_values(options={})
  raise(NotImplementedError.new("must be overridden"))
end

#dump(options = {}) ⇒ Object



916
917
918
919
920
921
922
923
# File 'lib/hotdog/commands/search.rb', line 916

def dump(options={})
  data = {}
  data[:identifier] = identifier.to_s if identifier
  data[:separator] = separator.to_s if separator
  data[:attribute] = attribute.to_s if attribute
  data[:fallback ] = @fallback.dump(options) if @fallback
  data
end

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



843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
# File 'lib/hotdog/commands/search.rb', line 843

def evaluate(environment, options={})
  if q = maybe_query(options)
    values = environment.execute(q, condition_values(options)).map { |row| row.first }
    if values.empty?
      if options[:did_fallback]
        []
      else
        if not environment.fixed_string? and @fallback
          # avoid optimizing @fallback to prevent infinite recursion
          values = @fallback.evaluate(environment, options.merge(did_fallback: true))
          if values.empty?
            if reload(environment, options)
              evaluate(environment, options).tap do |values|
                if values.empty?
                  environment.logger.info("no result: #{self.dump.inspect}")
                end
              end
            else
              []
            end
          else
            values
          end
        else
          if reload(environment, options)
            evaluate(environment, options).tap do |values|
              if values.empty?
                environment.logger.info("no result: #{self.dump.inspect}")
              end
            end
          else
            []
          end
        end
      end
    else
      values
    end
  else
    []
  end
end

#identifier?Boolean



793
794
795
# File 'lib/hotdog/commands/search.rb', line 793

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

#maybe_fallback(options = {}) ⇒ Object



925
926
927
# File 'lib/hotdog/commands/search.rb', line 925

def maybe_fallback(options={})
  nil
end

#maybe_glob(s) ⇒ Object



900
901
902
# File 'lib/hotdog/commands/search.rb', line 900

def maybe_glob(s)
  s ? to_glob(s.to_s) : nil
end

#maybe_query(options = {}) ⇒ Object



805
806
807
808
809
810
811
# File 'lib/hotdog/commands/search.rb', line 805

def maybe_query(options={})
  if query_without_condition = maybe_query_without_condition(options)
    query_without_condition.sub(/\s*;\s*\z/, "") + " WHERE " + condition(options) + ";"
  else
    nil
  end
end

#maybe_query_without_condition(options = {}) ⇒ Object



813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
# File 'lib/hotdog/commands/search.rb', line 813

def maybe_query_without_condition(options={})
  tables = condition_tables(options)
  if tables.empty?
    nil
  else
    case tables
    when [:hosts]
      "SELECT hosts.id AS host_id FROM hosts;"
    when [:hosts, :tags]
      "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;"
    when [:tags]
      "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags INNER JOIN tags ON hosts_tags.tag_id = tags.id;"
    else
      raise(NotImplementedError.new("unknown tables: #{tables.join(", ")}"))
    end
  end
end

#optimize(options = {}) ⇒ Object



890
891
892
893
894
# File 'lib/hotdog/commands/search.rb', line 890

def optimize(options={})
  # fallback to glob expression
  @fallback = maybe_fallback(options)
  self
end

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



904
905
906
907
908
909
910
911
912
913
914
# File 'lib/hotdog/commands/search.rb', line 904

def reload(environment, options={})
  $did_reload ||= false
  if $did_reload
    false
  else
    $did_reload = true
    environment.logger.info("force reloading all hosts and tags.")
    environment.reload(force: true)
    true
  end
end

#separator?Boolean



801
802
803
# File 'lib/hotdog/commands/search.rb', line 801

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

#to_glob(s) ⇒ Object



896
897
898
# File 'lib/hotdog/commands/search.rb', line 896

def to_glob(s)
  (s.start_with?("*") ? "" : "*") + s.gsub(/[-.\/_]/, "?") + (s.end_with?("*") ? "" : "*")
end