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] } ].freeze
- OPERATORS_SUPPORTING_MULTIPLES =
%w[Eq Ne].freeze
Instance Method Summary collapse
- #boolean_escape(string) ⇒ Object
-
#character_escape(string) ⇒ Object
processes escape characters for a given string.
-
#compile(source, mapper) ⇒ Object
To be implemented by child class.
- #date_escape(string) ⇒ Object
-
#datetime_escape(string) ⇒ Object
datetime may have timezone info.
- #decimal_escape(string) ⇒ Object
- #dropped_errors? ⇒ Boolean
-
#errors ⇒ Object
Returns an array of errors.
-
#errors? ⇒ Boolean
delegate :errors?, :fatal_errors?, :dropped_errors?, :recovered_errors?, :to => :process_errors Since I don’t have rails delegate…
- #escape_value(expression) ⇒ Object
- #escape_value_list(expression) ⇒ Object
- #fatal_errors? ⇒ Boolean
- #integer_escape(string) ⇒ Object
- #max_expressions ⇒ Object
- #max_function_depth ⇒ Object
-
#max_level_depth ⇒ Object
Maximum supported nesting level for the parser filters.
- #max_values ⇒ Object
-
#process_errors ⇒ Object
Delegator for methods to process the error list.
- #recovered_errors? ⇒ Boolean
-
#rules_for_type(type) ⇒ Object
Returns the rule hash for a given type.
-
#supports_multiple?(type) ⇒ Boolean
true if a given type supports multiple values.
-
#time_escape(string) ⇒ Object
Per the lexer, times don’t have any timezone info.
-
#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.
Instance Method Details
#boolean_escape(string) ⇒ Object
180 181 182 |
# File 'lib/sparkql/parser_compatibility.rb', line 180 def boolean_escape(string) string == "true" end |
#character_escape(string) ⇒ Object
processes escape characters for a given string. May be overridden by child classes.
147 148 149 |
# File 'lib/sparkql/parser_compatibility.rb', line 147 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.
62 63 64 |
# File 'lib/sparkql/parser_compatibility.rb', line 62 def compile(source, mapper) raise NotImplementedError end |
#date_escape(string) ⇒ Object
159 160 161 |
# File 'lib/sparkql/parser_compatibility.rb', line 159 def date_escape(string) Date.parse(string) end |
#datetime_escape(string) ⇒ Object
datetime may have timezone info. Given that, we should honor it it when present or setting an appropriate default when not. Either way, we should convert to local appropriate for the parser when we’re done.
DateTime in ruby is deprecated as of ruby 3.0. We’ve switched to the Time class to be future compatible. The :time type in sparkql != a ruby Time instance
170 171 172 |
# File 'lib/sparkql/parser_compatibility.rb', line 170 def datetime_escape(string) Time.parse(string) end |
#decimal_escape(string) ⇒ Object
155 156 157 |
# File 'lib/sparkql/parser_compatibility.rb', line 155 def decimal_escape(string) string.to_f end |
#dropped_errors? ⇒ Boolean
99 100 101 |
# File 'lib/sparkql/parser_compatibility.rb', line 99 def dropped_errors? process_errors.dropped_errors? end |
#errors ⇒ Object
Returns an array of errors. This is an array of ParserError objects
79 80 81 82 |
# File 'lib/sparkql/parser_compatibility.rb', line 79 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…
91 92 93 |
# File 'lib/sparkql/parser_compatibility.rb', line 91 def errors? process_errors.errors? end |
#escape_value(expression) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/sparkql/parser_compatibility.rb', line 119 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
107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/sparkql/parser_compatibility.rb', line 107 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
95 96 97 |
# File 'lib/sparkql/parser_compatibility.rb', line 95 def fatal_errors? process_errors.fatal_errors? end |
#integer_escape(string) ⇒ Object
151 152 153 |
# File 'lib/sparkql/parser_compatibility.rb', line 151 def integer_escape(string) string.to_i end |
#max_expressions ⇒ Object
202 203 204 |
# File 'lib/sparkql/parser_compatibility.rb', line 202 def max_expressions MAXIMUM_EXPRESSIONS end |
#max_function_depth ⇒ Object
210 211 212 |
# File 'lib/sparkql/parser_compatibility.rb', line 210 def max_function_depth MAXIMUM_FUNCTION_DEPTH end |
#max_level_depth ⇒ Object
Maximum supported nesting level for the parser filters
198 199 200 |
# File 'lib/sparkql/parser_compatibility.rb', line 198 def max_level_depth MAXIMUM_LEVEL_DEPTH end |
#max_values ⇒ Object
206 207 208 |
# File 'lib/sparkql/parser_compatibility.rb', line 206 def max_values MAXIMUM_MULTIPLE_VALUES end |
#process_errors ⇒ Object
Delegator for methods to process the error list.
85 86 87 |
# File 'lib/sparkql/parser_compatibility.rb', line 85 def process_errors Sparkql::ErrorsProcessor.new(errors) end |
#recovered_errors? ⇒ Boolean
103 104 105 |
# File 'lib/sparkql/parser_compatibility.rb', line 103 def recovered_errors? process_errors.recovered_errors? end |
#rules_for_type(type) ⇒ Object
Returns the rule hash for a given type
185 186 187 188 189 190 |
# File 'lib/sparkql/parser_compatibility.rb', line 185 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
193 194 195 |
# File 'lib/sparkql/parser_compatibility.rb', line 193 def supports_multiple?(type) rules_for_type(type).include?(:multiple) end |
#time_escape(string) ⇒ Object
Per the lexer, times don’t have any timezone info. When parsing, pick the proper offset to set things at.
176 177 178 |
# File 'lib/sparkql/parser_compatibility.rb', line 176 def time_escape(string) Time.parse("#{string}#{offset}") 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.
69 70 71 72 73 74 75 76 |
# File 'lib/sparkql/parser_compatibility.rb', line 69 def tokenize(source) raise ArgumentError, "You must supply a source string to tokenize!" unless source.is_a?(String) # Reset the parser error stack @errors = [] self.parse(source) end |