Class: Hotdog::Commands::Search::MultinaryExpressionNode

Inherits:
ExpressionNode
  • Object
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(op, expressions, options = {}) ⇒ MultinaryExpressionNode

Returns a new instance of MultinaryExpressionNode.



689
690
691
692
693
694
695
696
697
698
699
700
701
# File 'lib/hotdog/commands/search.rb', line 689

def initialize(op, expressions, options={})
  case (op || "or").to_s
  when ",", "||", "|", "OR", "or"
    @op = :OR
  else
    raise(SyntaxError.new("unknown multinary operator: #{op.inspect}"))
  end
  if SQLITE_LIMIT_COMPOUND_SELECT < expressions.length
    raise(ArgumentError.new("expressions limit exceeded: #{expressions.length} for #{SQLITE_LIMIT_COMPOUND_SELECT}"))
  end
  @expressions = expressions
  @fallback = options[:fallback]
end

Instance Attribute Details

#expressionsObject (readonly)

Returns the value of attribute expressions.



687
688
689
# File 'lib/hotdog/commands/search.rb', line 687

def expressions
  @expressions
end

#opObject (readonly)

Returns the value of attribute op.



687
688
689
# File 'lib/hotdog/commands/search.rb', line 687

def op
  @op
end

Instance Method Details

#dump(options = {}) ⇒ Object



744
745
746
# File 'lib/hotdog/commands/search.rb', line 744

def dump(options={})
  {multinary_op: @op.to_s, expressions: expressions.map { |expression| expression.dump(options) }}
end

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



711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
# File 'lib/hotdog/commands/search.rb', line 711

def evaluate(environment, options={})
  case @op
  when :OR
    if expressions.all? { |expression| TagExpressionNode === expression }
      values = expressions.group_by { |expression| expression.class }.values.flat_map { |expressions|
        query_without_condition = expressions.first.maybe_query_without_condition(options)
        if query_without_condition
          condition_length = expressions.map { |expression| expression.condition_values(options).length }.max
          expressions.each_slice(SQLITE_LIMIT_COMPOUND_SELECT / condition_length).flat_map { |expressions|
            q = query_without_condition.sub(/\s*;\s*\z/, "") + " WHERE " + expressions.map { |expression| "( %s )" % expression.condition(options) }.join(" OR ") + ";"
            environment.execute(q, expressions.flat_map { |expression| expression.condition_values(options) }).map { |row| row.first }
          }
        else
          []
        end
      }
    else
      values = []
    end
  else
    values = []
  end
  if values.empty?
    if @fallback
      @fallback.evaluate(environment, options={})
    else
      []
    end
  else
    values
  end
end

#intermediatesObject



748
749
750
# File 'lib/hotdog/commands/search.rb', line 748

def intermediates()
  [self] + @expression.flat_map { |expression| expression.intermediates }
end

#leafsObject



752
753
754
# File 'lib/hotdog/commands/search.rb', line 752

def leafs()
  @expressions.flat_map { |expression| expression.leafs }
end

#merge(other, options = {}) ⇒ Object



703
704
705
706
707
708
709
# File 'lib/hotdog/commands/search.rb', line 703

def merge(other, options={})
  if MultinaryExpressionNode === other and op == other.op
    MultinaryExpressionNode.new(op, expressions + other.expressions, options)
  else
    MultinaryExpressionNode.new(op, expressions + [other], options)
  end
end