module Whereable::ClassMethods

Public Instance Methods

whereable_deparse(hash) click to toggle source

deparse hash tree to Arel

# File lib/whereable.rb, line 58
def whereable_deparse(hash)
  raise FilterInvalid, "Invalid hash #{hash}" if hash.size > 1

  key, value = hash.first

  case key
  when :and, :or
    arel = whereable_deparse(value.first)
    value[1..-1].each do |o|
      arel = arel.public_send(key, whereable_deparse(o))
    end
    arel
  when :eq, :not_eq, :gt, :gteq, :lt, :lteq
    column = whereable_valid_column(value[:column])
    literal = whereable_valid_literal(column, value[:literal])
    arel_table[column].public_send(key, literal)
  when :between
    column = whereable_valid_column(value[:column])
    literals = value[:literals]
    raise(FilterInvalid, "Invalid operation for #{column}") if defined_enums.key?(column)

    arel_table[column].between(literals)
  when :in
    column = whereable_valid_column(value[:column])
    literals = value[:literals].map { |l| whereable_valid_literal(column, l) }

    arel_table[column].in(literals)
  else
    raise FilterInvalid, "Invalid hash #{hash}"
  end
end
whereable_hash_tree(filter) click to toggle source

Parse filter to hash tree using Treetop PEG

# File lib/whereable.rb, line 30
def whereable_hash_tree(filter)
  parser = WhereableClauseParser.new
  hash = parser.parse(filter.strip)&.to_h

  raise FilterInvalid, "Invalid filter at #{filter[parser.max_terminal_failure_index..-1]}" if hash.nil?

  hash
end
whereable_valid_column(column) click to toggle source

Test column validity

# File lib/whereable.rb, line 40
def whereable_valid_column(column)
  raise FilterInvalid, "Invalid column #{column}" unless column_names.include?(column)

  column
end
whereable_valid_literal(column, literal) click to toggle source

Test literal validity

# File lib/whereable.rb, line 47
def whereable_valid_literal(column, literal)
  if defined_enums.key?(column)
    raise(FilterInvalid, "Invalid value #{literal} for #{column}") unless defined_enums[column].key?(literal)

    defined_enums[column][literal]
  else
    literal
  end
end