Sha256: e3ede356901cd3ae047744446ebf261d86b21d475b33c1e6fea165813fdd56e4

Contents?: true

Size: 1.67 KB

Versions: 2

Compression:

Stored size: 1.67 KB

Contents

# frozen_string_literal: true

module IronBank
  # A query builder helps buidling a syntaxically correct query using ZOQL.
  #
  class QueryBuilder
    private_class_method :new

    def self.zoql(object, fields, conditions = {})
      new(object, fields, conditions).zoql
    end

    def zoql
      query = "select #{query_fields} from #{object}"
      conditions.empty? ? query : "#{query} where #{query_conditions}"
    end

    private

    attr_reader :object, :fields, :conditions

    def initialize(object, fields, conditions)
      @object     = object
      @fields     = fields
      @conditions = conditions
    end

    def query_fields
      fields.join(",")
    end

    def query_conditions
      ensure_range_single_condition

      case conditions
      when Hash
        hash_query_conditions
      end
    end

    def range_query_builder(field, value)
      value.each.with_object([]) do |option, range_query|
        range_query << "#{field}='#{option}'"
      end.join(" OR ")
    end

    def hash_query_conditions
      conditions.each.with_object([]) do |(field, value), filters|
        # TODO: sanitize the value
        field = IronBank::Utils.camelize(field)
        filters << current_filter(field, value)
      end.join(" AND ")
    end

    def current_filter(field, value)
      if value.is_a?(Array)
        range_query_builder(field, value)
      elsif [true, false].include? value
        "#{field}=#{value}"
      else
        "#{field}='#{value}'"
      end
    end

    def ensure_range_single_condition
      return if conditions.count <= 1
      return unless conditions.values.any?(Array)

      raise "Filter ranges must be used in isolation."
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
iron_bank-5.4.1 lib/iron_bank/query_builder.rb
iron_bank-5.4.0 lib/iron_bank/query_builder.rb