class MSFLVisitors::Visitor::AggregationsVisitor

Constants

ITERATOR_OPERATORS
RANGE_OPERATORS

Attributes

visitor[R]

Public Class Methods

new(visitor) click to toggle source
# File lib/msfl_visitors/visitor.rb, line 164
def initialize(visitor)
  @visitor = visitor
end

Public Instance Methods

visit(node) click to toggle source
# File lib/msfl_visitors/visitor.rb, line 182
def visit(node)
  case node
    when Nodes::Partial
      # build the aggregate criteria clause first
      # agg_criteria_clause = { clause: { agg_field_name: :portfolio_size, operator: :gt, test_value: 2 }, method_to_execute: :aggregations }
      agg_criteria_clause = { clause: node.right.accept(visitor), method_to_execute: :aggregations }
      # switch to the term filter mode
      visitor.mode = :term
      given_clause = { clause: node.left.accept(visitor) }

      # switch back to the aggregations mode
      visitor.mode = :aggregations
      # return the result of the visitation
      [agg_criteria_clause, given_clause]

    when Nodes::Match
      if node.right.is_a? Nodes::Set
        regex = "(" + node.right.contents.map { |right_child| MSFLVisitors::Nodes::Regex.new(right_child.value.to_s).accept(visitor) }.join('|') + ")"
        { agg_field_name: node.left.accept(visitor), operator: :match, test_value: regex }
      else
        { agg_field_name: node.left.accept(visitor), operator: :match, test_value: MSFLVisitors::Nodes::Regex.new(node.right.value.to_s).accept(visitor) }
      end

    when Nodes::Field
      node.value.to_sym
    when Nodes::Date, Nodes::Time
      node.value.iso8601
    when  Nodes::Word,
          Nodes::Number,
          Nodes::Boolean,
          Nodes::Dataset
      node.value
    when  Nodes::Regex
      composable_expr_for(regex_escape(node.value.to_s).inspect)

    when  Nodes::GreaterThan,
          Nodes::GreaterThanEqual,
          Nodes::LessThan,
          Nodes::LessThanEqual,
          Nodes::Equal,
          Nodes::QueryString
      { agg_field_name: node.left.accept(visitor), operator: RANGE_OPERATORS[node.class], test_value: node.right.accept(visitor) }
    when Nodes::Given
      [:filter, node.contents.first.accept(visitor)]
    when Nodes::ExplicitFilter
      node.contents.map { |n| n.accept(visitor) }.first
    when Nodes::NamedValue
      node.value.accept(visitor)
    when Nodes::Containment
      { agg_field_name: node.left.accept(visitor).to_sym, operator: :in, test_value: node.right.accept(visitor) }
    when Nodes::Set
      node.contents.map { |n| n.accept(visitor) }
    when Nodes::Filter
      if node.contents.count == 1
        node.contents.first.accept visitor
      else
        { and: node.contents.map { |n| n.accept(visitor) } }
      end
    when Nodes::Iterator
      { ITERATOR_OPERATORS[node.class] => node.set.accept(visitor) }

    when Nodes::Foreign
      { foreign: Hash[[[:type, node.left.accept(visitor)], [:filter, node.right.accept(visitor)]]] }

    else
      fail ArgumentError, "AGGREGATIONS cannot visit: #{node.class.name}"
  end
end