class Hotdog::Expression::FuncallNode

Attributes

args[R]
function[R]

Public Class Methods

new(function, args, options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 498
def initialize(function, args, options={})
  # FIXME: smart argument handling (e.g. arity & type checking)
  case function.to_s
  when "HEAD", "head"
    @function = :HEAD
  when "GROUP_BY", "group_by"
    @function = :GROUP_BY
  when "LIMIT", "limit"
    @function = :HEAD
  when "ORDER_BY", "order_by"
    @function = :ORDER_BY
  when "REVERSE", "reverse"
    @function = :REVERSE
  when "SAMPLE", "sample"
    @function = :HEAD
    args[0] = FuncallNode.new("SHUFFLE", [args[0]])
  when "SHUFFLE", "shuffle"
    @function = :SHUFFLE
  when "SLICE", "slice"
    @function = :SLICE
  when "SORT", "sort"
    @function = :ORDER_BY
  when "TAIL", "tail"
    @function = :TAIL
  else
    raise(SyntaxError.new("unknown function call: #{function}"))
  end
  @args = args
  @options = options
end

Public Instance Methods

dump(options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 529
def dump(options={})
  args = @args.map { |arg|
    if ExpressionNode === arg
      arg.dump(options)
    else
      arg
    end
  }
  {funcall: @function.to_s, args: args}
end
evaluate(environment, options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 575
def evaluate(environment, options={})
  case function
  when :HEAD
    args[0].evaluate(environment, options).take(args[1] || 1)
  when :GROUP_BY
    intermediate = args[0].evaluate(environment, options)
    q = "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags " \
          "INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
          "WHERE tags.name = ? AND hosts_tags.host_id IN (%s) " \
          "GROUP BY tags.value;" % intermediate.map { "?" }.join(", ")
    QueryExpressionNode.new(q, [args[1]] + intermediate).evaluate(environment, options)
  when :ORDER_BY
    intermediate = args[0].evaluate(environment, options)
    if args[1]
      q = "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags " \
            "INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
            "WHERE tags.name = ? AND hosts_tags.host_id IN (%s) " \
            "ORDER BY tags.value;" % intermediate.map { "?" }.join(", ")
      QueryExpressionNode.new(q, [args[1]] + intermediate).evaluate(environment, options)
    else
      q = "SELECT DISTINCT hosts_tags.host_id FROM hosts_tags " \
            "INNER JOIN tags ON hosts_tags.tag_id = tags.id " \
            "WHERE hosts_tags.host_id IN (%s) " \
            "ORDER BY hosts_tags.host_id;" % intermediate.map { "?" }.join(", ")
      QueryExpressionNode.new(q, intermediate).evaluate(environment, options)
    end
  when :REVERSE
    args[0].evaluate(environment, options).reverse()
  when :SHUFFLE
    args[0].evaluate(environment, options).shuffle()
  when :SLICE
    args[0].evaluate(environment, options).slice(args[1], args[2] || 1)
  when :TAIL
    args[0].evaluate(environment, options).last(args[1] || 1)
  else
    []
  end
end
optimize(options={}) click to toggle source
# File lib/hotdog/expression/semantics.rb, line 540
def optimize(options={})
  case function
  when :GROUP_BY
    o_args = [@args[0].optimize(options)]
    if TagExpressionNode === args[1]
      # workaround for expressions like `ORDER_BY((environment:development),role)`
      o_args << @args[1].tagname
    else
      o_args << @args[1]
    end
  when :ORDER_BY
    o_args = [@args[0].optimize(options)]
    if @args[1]
      if TagExpressionNode === @args[1]
        # workaround for expressions like `ORDER_BY((environment:development),role)`
        o_args << @args[1].tagname
      else
        o_args << @args[1]
      end
    end
  else
    o_args = @args.map { |arg|
      if ExpressionNode === arg
        arg.optimize(options)
      else
        arg
      end
    }
  end
  FuncallNode.new(
    @function,
    o_args,
  )
end