Module: Sparkql::ParserCompatibility

Included in:
Parser
Defined in:
lib/sparkql/parser_compatibility.rb

Overview

Required interface for existing parser implementations

Constant Summary collapse

MAXIMUM_MULTIPLE_VALUES =
200
MAXIMUM_EXPRESSIONS =
75
MAXIMUM_LEVEL_DEPTH =
2
MAXIMUM_FUNCTION_DEPTH =
5
FILTER_VALUES =

Ordered by precedence.

[
  {
    :type => :datetime,
    :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
  },
  {
    :type => :date,
    :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
  },
  {
    :type => :time,
    :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
  },
  {
    :type => :character,
    :multiple => /^'([^'\\]*(\\.[^'\\]*)*)'/,
    :operators => Sparkql::Token::EQUALITY_OPERATORS
  },
  {
    :type => :integer,
    :multiple => /^\-?[0-9]+/,
    :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
  },
  {
    :type => :decimal,
    :multiple => /^\-?[0-9]+\.[0-9]+/,
    :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
  },
  {
    :type => :shape,
    :operators => Sparkql::Token::EQUALITY_OPERATORS
  },
  {
    :type => :boolean,
    :operators => Sparkql::Token::EQUALITY_OPERATORS
  },
  {
    :type => :null,
    :operators => Sparkql::Token::EQUALITY_OPERATORS
  },
  {
    :type => :function,
    :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
  },
]
OPERATORS_SUPPORTING_MULTIPLES =
["Eq","Ne"]

Instance Method Summary collapse

Instance Method Details

#boolean_escape(string) ⇒ Object



169
170
171
# File 'lib/sparkql/parser_compatibility.rb', line 169

def boolean_escape(string)
  "true" == string
end

#character_escape(string) ⇒ Object

processes escape characters for a given string. May be overridden by child classes.



145
146
147
# File 'lib/sparkql/parser_compatibility.rb', line 145

def character_escape( string )
  string.gsub(/^\'/,'').gsub(/\'$/,'').gsub(/\\'/, "'")
end

#compile(source, mapper) ⇒ Object

To be implemented by child class. Shall return a valid query string for the respective database, or nil if the source could not be processed. It may be possible to return a valid SQL string AND have errors ( as checked by errors? ), but this will be left to the discretion of the child class.

Raises:

  • (NotImplementedError)


63
64
65
# File 'lib/sparkql/parser_compatibility.rb', line 63

def compile( source, mapper )
 raise NotImplementedError
end

#date_escape(string) ⇒ Object



157
158
159
# File 'lib/sparkql/parser_compatibility.rb', line 157

def date_escape(string)
  Date.parse(string)
end

#datetime_escape(string) ⇒ Object



161
162
163
# File 'lib/sparkql/parser_compatibility.rb', line 161

def datetime_escape(string)
  DateTime.parse(string)
end

#decimal_escape(string) ⇒ Object



153
154
155
# File 'lib/sparkql/parser_compatibility.rb', line 153

def decimal_escape( string )
  string.to_f
end

#dropped_errors?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/sparkql/parser_compatibility.rb', line 99

def dropped_errors?
  process_errors.dropped_errors?
end

#errorsObject

Returns an array of errors. This is an array of ParserError objects



81
82
83
84
# File 'lib/sparkql/parser_compatibility.rb', line 81

def errors
  @errors = [] unless defined?(@errors)
  @errors
end

#errors?Boolean

delegate :errors?, :fatal_errors?, :dropped_errors?, :recovered_errors?, :to => :process_errors Since I don’t have rails delegate…

Returns:

  • (Boolean)


93
94
95
# File 'lib/sparkql/parser_compatibility.rb', line 93

def errors?
  process_errors.errors?
end

#escape_value(expression) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/sparkql/parser_compatibility.rb', line 118

def escape_value( expression )
  if expression[:value].is_a? Array
    return escape_value_list( expression )
  end
  case expression[:type]
  when :character
    return character_escape(expression[:value])
  when :integer
    return integer_escape(expression[:value])
  when :decimal
    return decimal_escape(expression[:value])
  when :date
    return date_escape(expression[:value])
  when :datetime
    return datetime_escape(expression[:value])
  when :time
    return time_escape(expression[:value])
  when :boolean
    return boolean_escape(expression[:value])
  when :null
    return nil
  end
  expression[:value]
end

#escape_value_list(expression) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/sparkql/parser_compatibility.rb', line 106

def escape_value_list( expression )
  final_list = []
  expression[:value].each do | value |
    new_exp = {
      :value => value,
      :type => expression[:type]
    }
    final_list << escape_value(new_exp)
  end
  expression[:value] = final_list
end

#fatal_errors?Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/sparkql/parser_compatibility.rb', line 96

def fatal_errors?
  process_errors.fatal_errors?
end

#integer_escape(string) ⇒ Object



149
150
151
# File 'lib/sparkql/parser_compatibility.rb', line 149

def integer_escape( string )
  string.to_i
end

#max_expressionsObject



191
192
193
# File 'lib/sparkql/parser_compatibility.rb', line 191

def max_expressions
  MAXIMUM_EXPRESSIONS
end

#max_function_depthObject



199
200
201
# File 'lib/sparkql/parser_compatibility.rb', line 199

def max_function_depth
  MAXIMUM_FUNCTION_DEPTH
end

#max_level_depthObject

Maximum supported nesting level for the parser filters



187
188
189
# File 'lib/sparkql/parser_compatibility.rb', line 187

def max_level_depth
  MAXIMUM_LEVEL_DEPTH
end

#max_valuesObject



195
196
197
# File 'lib/sparkql/parser_compatibility.rb', line 195

def max_values
  MAXIMUM_MULTIPLE_VALUES
end

#process_errorsObject

Delegator for methods to process the error list.



87
88
89
# File 'lib/sparkql/parser_compatibility.rb', line 87

def process_errors
  Sparkql::ErrorsProcessor.new(@errors)
end

#recovered_errors?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/sparkql/parser_compatibility.rb', line 102

def recovered_errors?
  process_errors.recovered_errors?
end

#rules_for_type(type) ⇒ Object

Returns the rule hash for a given type



174
175
176
177
178
179
# File 'lib/sparkql/parser_compatibility.rb', line 174

def rules_for_type( type )
  FILTER_VALUES.each do |rule|
    return rule if rule[:type] == type
  end
  nil
end

#supports_multiple?(type) ⇒ Boolean

true if a given type supports multiple values

Returns:

  • (Boolean)


182
183
184
# File 'lib/sparkql/parser_compatibility.rb', line 182

def supports_multiple?( type )
  rules_for_type(type).include?( :multiple )
end

#time_escape(string) ⇒ Object



165
166
167
# File 'lib/sparkql/parser_compatibility.rb', line 165

def time_escape(string)
  DateTime.parse(string)
end

#tokenize(source) ⇒ Object

Returns a list of expressions tokenized in the following format:

{ :field => IdentifierName, :operator => “Eq”, :value => “‘Fargo’”, :type => :character, :conjunction => “And” }

This step will set errors if source is not syntactically correct.

Raises:

  • (ArgumentError)


70
71
72
73
74
75
76
77
78
# File 'lib/sparkql/parser_compatibility.rb', line 70

def tokenize( source )
  raise ArgumentError, "You must supply a source string to tokenize!" unless source.is_a?(String)

  # Reset the parser error stack
  @errors = []

  expressions = self.parse(source)
  expressions
end