class Hotdog::Expression::MultinaryExpressionNode

Attributes

expressions[R]
op[R]

Public Class Methods

new(op, expressions, options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 408
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
  sqlite_limit_compound_select = options[:sqlite_limit_compound_select] || SQLITE_LIMIT_COMPOUND_SELECT
  if sqlite_limit_compound_select < expressions.length
    raise(ArgumentError.new("expressions limit exceeded: #{expressions.length} for #{sqlite_limit_compound_select}"))
  end
  @expressions = expressions
  @options = options
end

Public Instance Methods

dump(options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 465
def dump(options={})
  {multinary_op: @op.to_s, expressions: expressions.map { |expression| expression.dump(options) }}
end
evaluate(environment, options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 431
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
          sqlite_limit_compound_select = options[:sqlite_limit_compound_select] || SQLITE_LIMIT_COMPOUND_SELECT
          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 @options[:fallback]
      @options[:fallback].evaluate(environment, options={})
    else
      []
    end
  else
    values
  end
end
merge(other, options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 423
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