class Cuprum::Collections::Queries::ParseBlock

Command for parsing a Query#where block into criteria.

@example An Empty Query

command = Cuprum::Collections::Queries::ParseBlock.new
result  = command.call { {} }
result.value #=> []

@example A Value Query

command = Cuprum::Collections::Queries::ParseBlock.new
result  = command.call do
  {
    author: 'Nnedi Okorafor',
    series: 'Binti',
    genre:  'Africanfuturism'
  }
end
result.value #=>
# [
#   ['author', :eq, 'Nnedi Okorafor'],
#   ['series', :eq, 'Binti'],
#   ['genre',  :eq, 'Africanfuturism']
# ]

@example A Query With Operators

command = Cuprum::Collections::Queries::ParseBlock.new
result  = command.call do
  {
    author: equal('Nnedi Okorafor'),
    series: not_equal('Binti')
  }
end
result.value #=>
# [
#   ['author', :eq, 'Nnedi Okorafor'],
#   ['series', :ne, 'Binti']
# ]

Private Class Methods

validation_contract() click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 128
def validation_contract
  self::MethodValidations.contracts.fetch(:call)
end

Private Instance Methods

call_block(&block) click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 139
def call_block(&block)
  handle_unknown_operator { Builder.new.instance_exec(&block) }
rescue StandardError => exception
  error = Cuprum::Errors::UncaughtException.new(
    exception: exception,
    message:   'uncaught exception when parsing query block'
  )

  failure(error)
end
generate_criteria(hsh) click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 150
def generate_criteria(hsh)
  hsh.map do |key, value|
    unless partial_criterion?(value)
      next [key.to_s, Cuprum::Collections::Queries::Operators::EQUAL, value]
    end

    value.tap { |ary| ary[0] = key.to_s }
  end
end
handle_unknown_operator() { || ... } click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 160
def handle_unknown_operator
  yield
rescue NoMethodError => exception
  error = Cuprum::Collections::Errors::UnknownOperator.new(
    operator: exception.name
  )

  failure(error)
end
invalid_query_error(errors:, message: nil) click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 170
def invalid_query_error(errors:, message: nil)
  Cuprum::Collections::Errors::InvalidQuery.new(
    errors:   errors,
    message:  message,
    strategy: :block
  )
end
partial_criterion?(obj) click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 178
def partial_criterion?(obj)
  return false unless obj.is_a?(Array) && obj.size == 3

  attribute, operator, _value = obj

  return false unless attribute.nil?

  Cuprum::Collections::Queries::VALID_OPERATORS.include?(operator)
end
process(where:) click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 188
def process(where:)
  hsh = step { call_block(&where) }

  step { validate_hash(hsh) }

  generate_criteria(hsh)
end
validate_hash(obj) click to toggle source
# File lib/cuprum/collections/queries/parse_block.rb, line 196
def validate_hash(obj)
  constraint    = Cuprum::Collections::Constraints::QueryHash.new
  match, errors = constraint.match(obj)

  return if match

  message = 'query block returned invalid value'
  failure(invalid_query_error(errors: errors, message: message))
end