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,
}

Instance Method Summary collapse

Methods included from MSFLVisitors::VisitorHelpers

#composable_expr_for, #escape_es_special_regex_chars, #escaped_regex_helper

Constructor Details

#initialize(visitor) ⇒ AggregationsVisitor

Returns a new instance of AggregationsVisitor.



161
162
163
# File 'lib/msfl_visitors/visitor.rb', line 161

def initialize(visitor)
  @visitor = visitor
end

Instance Method Details

#visit(node) ⇒ Object



174
175
176
177
178
179
180
181
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
# File 'lib/msfl_visitors/visitor.rb', line 174

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('|')
        # regex = node.right.contents.map { |right_child| right_child.value.to_s }.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
      esc = Regexp.escape("#{node.value.to_s}")
      composable_expr_for(escaped_regex_helper(esc).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::And
      { and: 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