Class: MSFLVisitors::Visitor::AggregationsVisitor

Inherits:
Object
  • Object
show all
Includes:
MSFLVisitors::VisitorHelpers
Defined in:
lib/msfl_visitors/visitor.rb

Constant Summary collapse

RANGE_OPERATORS =
{
    Nodes::GreaterThan            => :gt,
    Nodes::GreaterThanEqual       => :gte,
    Nodes::LessThan               => :lt,
    Nodes::LessThanEqual          => :lte,
    Nodes::Equal                  => :eq,
    Nodes::QueryString            => :query_string,
}
ITERATOR_OPERATORS =
{
    Nodes::And => :and,
    Nodes::Or => :or,
}

Instance Method Summary collapse

Methods included from MSFLVisitors::VisitorHelpers

#composable_expr_for, #escape_es_special_regex_chars, #regex_escape

Constructor Details

#initialize(visitor) ⇒ AggregationsVisitor

Returns a new instance of AggregationsVisitor.



164
165
166
# File 'lib/msfl_visitors/visitor.rb', line 164

def initialize(visitor)
  @visitor = visitor
end

Instance Method Details

#visit(node) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# 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