class Basepack::FilterQL

Constants

PREDICATE_MAP
PREDICATE_MAP_REVERSE

Public Class Methods

conditions_to_ql(conditions) click to toggle source
# File lib/basepack/filter_ql.rb, line 216
def self.conditions_to_ql(conditions)
  conditions.map do |name, predicate_name, value|
    if predicates[predicate_name][:type] == :boolean
      "#{name} #{PREDICATE_MAP_REVERSE[predicate_name]}"
    else
      case value
      when String then value = value_to_string(value)
      when Hash   then value = value_to_jshash(value)
      end
      "#{name} #{PREDICATE_MAP_REVERSE[predicate_name]} #{value}"
    end
  end.join(" and ")
end
new(options = nil) click to toggle source
# File lib/basepack/filter_ql.rb, line 184
def initialize(options = nil)
  @parser = Parser.new
  @transformer = Transformer.new
  @options = (options || {}).freeze
end
predicates() click to toggle source
# File lib/basepack/filter_ql.rb, line 230
def self.predicates
  @predicates ||= begin
    Hash[Ransack.predicates.map do |k, predicate|
      [k, {
        name:     k,
        label:    Ransack::Translate.predicate(k),
        type:     predicate.type,
        compound: predicate.compound,
        wants_array: predicate.wants_array,
      }]
    end.compact]
  end
end
string_to_value(string) click to toggle source
# File lib/basepack/filter_ql.rb, line 255
def self.string_to_value(string)
  string.gsub(/\\(.)/, '\1')
end
test() click to toggle source

Basepack::FilterQL.test

# File lib/basepack/filter_ql.rb, line 204
def self.test
  new(
    functions: {
      user: proc {|builder, arg| arg.inspect }
    }
  ).parse(
    "a0 = user() and a01 = user('I') and a02 = user({ x: 1}) and a03 = user([1,2,'3']) and " +
    "a1 = 3 and a2 like 'asd' and a3 not like 'asd' and a4 is null and a5 is not null and a6 != 'as\\'d' and a7 = \"str\\\"s\" and " +
    "a8 = { key:'value', key2:1 } and a9 = ['str', 4, 3.5] ",
  )
end
value_to_jshash(value) click to toggle source
# File lib/basepack/filter_ql.rb, line 248
def self.value_to_jshash(value)
  res = value.inject([]) do |r,(k,v)|
    r << "#{k}: #{v.inspect}"
  end.join(", ")
  "{ #{res} }"
end
value_to_string(value) click to toggle source
# File lib/basepack/filter_ql.rb, line 244
def self.value_to_string(value)
  "'#{value.gsub(/(['\\])/, '\\\\\1')}'"
end

Public Instance Methods

parse(query, options = nil) click to toggle source
# File lib/basepack/filter_ql.rb, line 190
def parse(query, options = nil)
  builder = Builder.new(query, @options)
  begin
    ast = @parser.parse(query, reporter: Parslet::ErrorReporter::Deepest.new)
    @transformer.apply(ast, builder: builder)
  rescue Parslet::ParseFailed => e
    #puts e.cause.ascii_tree
    deepest = deepest_cause(e.cause)
    line, column = deepest.source.line_and_column(deepest.pos)
    builder.raise_error_for_pos("Neočekáváný vstup", deepest.pos, line, column)
  end
end

Private Instance Methods

deepest_cause(cause) click to toggle source
# File lib/basepack/filter_ql.rb, line 261
def deepest_cause(cause)
  if cause.children.any?
    deepest_cause(cause.children.first)
  else
    cause
  end
end