Class: OdataDuty::SearchExpression

Inherits:
Object
  • Object
show all
Defined in:
lib/odata_duty/parslet_search_expression.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(terms, operator = :and) ⇒ SearchExpression

Returns a new instance of SearchExpression.



7
8
9
10
# File 'lib/odata_duty/parslet_search_expression.rb', line 7

def initialize(terms, operator = :and)
  @terms = terms
  @operator = operator
end

Instance Attribute Details

#operatorObject (readonly)

Returns the value of attribute operator.



5
6
7
# File 'lib/odata_duty/parslet_search_expression.rb', line 5

def operator
  @operator
end

#termsObject (readonly)

Returns the value of attribute terms.



5
6
7
# File 'lib/odata_duty/parslet_search_expression.rb', line 5

def terms
  @terms
end

Class Method Details

.build_parse_tree(search_string) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/odata_duty/parslet_search_expression.rb', line 28

def self.build_parse_tree(search_string)
  parser = ParsletSearchExpressionParser.new
  parser.parse(search_string)
rescue Parslet::ParseFailed => e
  if search_string.include?('(') || search_string.include?(')')
    raise NoImplementationError, 'Parentheses are not supported'
  end
  if search_string.include?(' AND ') && search_string.include?(' OR ')
    raise NoImplementationError, 'Mixed AND/OR operators are not supported'
  end

  raise InvalidQueryOptionError, "Invalid search expression: #{e}"
end

.parse(search_string) ⇒ Object



20
21
22
23
24
25
26
# File 'lib/odata_duty/parslet_search_expression.rb', line 20

def self.parse(search_string)
  return new([]) unless search_string.match?(/\S/)

  parse_tree = build_parse_tree(search_string)
  validate_parse_tree(parse_tree)
  transform(parse_tree)
end

.transform(parse_tree) ⇒ Object



50
51
52
53
# File 'lib/odata_duty/parslet_search_expression.rb', line 50

def self.transform(parse_tree)
  transformer = ParsletSearchExpressionTransformer.new
  transformer.apply(parse_tree)
end

.validate_parse_tree(parse_tree) ⇒ Object



42
43
44
45
46
47
48
# File 'lib/odata_duty/parslet_search_expression.rb', line 42

def self.validate_parse_tree(parse_tree)
  and_sub_tree = parse_tree[:explicit_and_expr] || parse_tree[:implicit_and_expr]
  return unless and_sub_tree

  contains_or = and_sub_tree.any? { |t| t.dig(:term, :word) == 'OR' }
  raise NoImplementationError, 'Mixed AND/OR operators are not supported' if contains_or
end

Instance Method Details

#and?Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/odata_duty/parslet_search_expression.rb', line 16

def and?
  @operator == :and
end

#or?Boolean

Returns:

  • (Boolean)


12
13
14
# File 'lib/odata_duty/parslet_search_expression.rb', line 12

def or?
  @operator == :or
end