class FluentQuery::Queries::Processor
Query
processor.
Its primary aim is to dive processing methods from query object as is. In fact, defines something as processing session.
Constants
- COLUMN_DIRECTIVE
Describes column directive. @var Regexp
- COLUMN_DIRECTIVE_SIMPLE
Holds simple column definition.
- COLUMN_REPLACEMENT
Indicates column replacement to perform. (Flag.)
- FORMATTING_DIRECTIVE
Describes formatting directive. @var Regexp
- FORMATTING_DIRECTIVE_SIMPLE
Holds simple column definition. @var Regexp
- FORMATTING_REPLACEMENT
Indicates formatting directive replacements to perform. (Flag.)
- STRING_DIRECTIVE
Describes string directive. @var Regexp
- STRING_REPLACEMENT
Indicates string replacement to perform. (Flag.)
Attributes
Public Class Methods
Constructs processor. @param MP_Fluent_Driver driver Driver
upon which processor should work upon.
# File lib/fluent-query/queries/processor.rb, line 111 def initialize(driver) @driver = driver end
Public Instance Methods
Compiles the string.
# File lib/fluent-query/queries/processor.rb, line 386 def compile(string) self.compiler.compile(string) end
Returns compiler.
# File lib/fluent-query/queries/processor.rb, line 374 def compiler if @_compiler.nil? @_compiler = FluentQuery::Compiler::new(self) end @_compiler end
Returns final fluent expander query.
# File lib/fluent-query/queries/processor.rb, line 344 def expander if @__fluent_expander.nil? @__fluent_expander = self.class::FORMATTING_DIRECTIVE end @__fluent_expander end
Returns NULL representation.
# File lib/fluent-query/queries/processor.rb, line 335 def null @driver.null end
Process array to some reasonable string form.
Joins its elements and separates them by commas. Quotes strings by by-driver-defined string quoting and integers by integer quoting.
# File lib/fluent-query/queries/processor.rb, line 123 def process_array(array, glue = ",") result = array.map do |i| self.quote_value(i) end return result.join(glue + " ") end
Processes fluent directive. Replacements is three bytes flag array.
# File lib/fluent-query/queries/processor.rb, line 299 def process_directive(directive, argument = nil, replacements = 7) if (replacements & self.class::COLUMN_REPLACEMENT > 0) and (directive[0].ord == 91) # "[", Column directive result = directive.gsub(self.class::COLUMN_DIRECTIVE_SIMPLE) { |value| self.quote_identifier(value[1..-2]) } elsif (replacements & self.class::STRING_REPLACEMENT > 0) and (directive[-1].ord == 34) # "\"", String directive result = directive.gsub('"', @driver.quote_string("").last) elsif (replacements & self.class::FORMATTING_REPLACEMENT > 0) and (directive[0..1] == "%%") # Formatting directive result = directive.gsub(self.class::FORMATTING_DIRECTIVE_SIMPLE) { |value| self.process_formatting(value[2..-1], argument) } else result = directive end return result end
Processed strings with format definitions and data specifications.
Mode can be :compile
, :build
, :prepare
or :finish
. Compiling means building the query without expanding the formatting directives. Finishing means building the compiled query. Building means both of them. Preparing is basically the same as compiling, but modifies behaviour of some tokens such as INSERT
.
# File lib/fluent-query/queries/processor.rb, line 242 def process_formatted(sequence, mode = :build) count = sequence.length i = 0 output = "" replacer_settings = self.class::COLUMN_REPLACEMENT | self.class::STRING_REPLACEMENT expander_settings = self.class::FORMATTING_REPLACEMENT while i < count item = sequence[i] ## if item.kind_of? String item = item.dup # Calls to each occurence of directive matching to directive # finding expression directive processing. In each call increases # sequence position counter so moves forward. if mode.in? [:compile, :build, :prepare] item.gsub!(self.replacer) do |directive| directive.strip! self.process_directive(directive, nil, replacer_settings) end end if mode.in? [:finish, :build] item.gsub!(self.expander) do |directive| self.process_directive(directive, sequence[i += 1], expander_settings) end end output << item elsif item.kind_of? Symbol output << self.quote_identifier(item) else output << item.to_s end output << " " i += 1 end return output end
Processes formatting directive.
# File lib/fluent-query/queries/processor.rb, line 318 def process_formatting(directive, argument) proc = self.compiler.compile_formatting(directive) if proc output = proc.call(argument) else output = "" end return output end
Process hash to some reasonable string form.
Joins its elements to name = value form and separates them by commas. Quotes string value by by-driver-defined string quoting and integers by integer quoting. Quotes name by identifiers quoting.
Handles two modes:
* "assigning" which classicaly keeps for example the '=' operator, * "comparing" which sets for example 'IS' operator for booleans.
# File lib/fluent-query/queries/processor.rb, line 143 def process_hash(hash, glue = ",", equality = :comparing) result = [ ] mode = equality hash.each_pair do |key, value| operator = @driver.quote_equality(value, mode) key = self.quote_identifier(key) value = self.quote_value(value) result << (key + " " + operator + " " + value) end return result.join(" " << glue << " ") end
Processes identifier list to the string representation. Quotes them and joins them separated by commas.
# File lib/fluent-query/queries/processor.rb, line 226 def process_identifiers(identifiers) self.quote_identifiers(identifiers).join(", ") end
Quotes identifiers by identifier quoting.
# File lib/fluent-query/queries/processor.rb, line 207 def quote_identifier(identifier) @driver.quote_identifier(identifier.to_s) end
Quotes identifiers list.
# File lib/fluent-query/queries/processor.rb, line 216 def quote_identifiers(identifiers) identifiers.map { |i| self.quote_identifier(i) } end
Quotes subquery by driver subquery quoting.
# File lib/fluent-query/queries/processor.rb, line 194 def quote_subquery(subquery) if subquery.kind_of? FluentQuery::Query subquery = subquery.build! end return @driver.quote_subquery(subquery) end
Quotes string by driver string quoting and integers by integer
quoting. Other values are converted to string too and leaved unquoted.
# File lib/fluent-query/queries/processor.rb, line 165 def quote_value(value) if (value.string?) or (value.symbol?) result = @driver.quote_string(value.to_s) elsif value.kind_of? Integer result = @driver.quote_integer(value) elsif value.array? result = "(" << self.process_array(value) << ")" # TODO: question is, if we should do it here, if it's enough general just for processor elsif value.kind_of? Float result = @driver.quote_float(value) elsif (value.kind_of? TrueClass) or (value.kind_of? FalseClass) result = @driver.quote_boolean(value) elsif (value.kind_of? Date) or (value.kind_of? DateTime) result = @driver.quote_date_time(value) elsif value.nil? result = @driver.null else result = value.to_s end return result end
Returns final fluent formatter query.
# File lib/fluent-query/queries/processor.rb, line 357 def replacer if @__fluent_replacer.nil? parts = Array[self.class::COLUMN_DIRECTIVE, self.class::STRING_DIRECTIVE] result = "" result << "(?:(?:" << parts.join(")|(?:") << "))" @__fluent_replacer = Regexp::new(result) end @__fluent_replacer end