class ConvenientGrouper::HashConverter

Attributes

groups[R]
restrictions[R]

Public Class Methods

new(hash_arg, options=Default::OPTIONS) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 18
def initialize(hash_arg, options=Default::OPTIONS)
  @hash = hash_arg
  validate_hash

  @options = options
  validate_options

  @restrict = (@options[:restrict] == true)

  create_groups
  create_restrictions
end

Private Instance Methods

array_str(array) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 122
def array_str(array)
  mapped_str = array.map { |v| insert_val(v) }.join(', ')
  "IN (#{mapped_str})"
end
cases() click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 64
def cases
  parse_hash do |column, group, value|
    "WHEN #{column_value_matcher(column, value)} THEN '#{group}'"
  end
end
column_value_matcher(column, value) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 78
def column_value_matcher(column, value)
  "(#{column} #{lookup_str(value)})"
end
create_groups() click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 51
def create_groups
  @groups = "CASE #{[*cases, default_group].compact.join(' ')} END"
end
create_restrictions() click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 55
def create_restrictions
  @restrictions =
    if @restrict
      parse_hash do |column, _, value|
        column_value_matcher(column, value)
      end.join(' OR ')
    end || ""
end
default_group() click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 82
def default_group
  hash = @hash.values.first
  group = hash[nil] || Default::GROUP
  "ELSE '#{group}'"
end
insert_val(value) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 131
def insert_val(value)
  if value.is_a?(Numeric)
    value
  else
    "'#{value.to_s}'"
  end
end
lookup_str(value) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 88
def lookup_str(value)
  case value
  when Range
    range_str(value)
  when Array
    array_str(value)
  when lambda { |x| Regex.matches?(x) }
    value
  when Numeric, String
    value_str(value)
  when NilClass
    'IS NULL'
  else
    raise_error("Unsupported type #{value.class.name} for #{value}.")
  end
end
matches_conditions?() click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 45
def matches_conditions?
  @hash.is_a?(Hash) &&
  (@hash.each_key.count == 1) &&
  @hash.each_value.all? { |v| v.is_a?(Hash) }
end
parse_hash() { |column, group, value| ... } click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 70
def parse_hash
  @hash.each_with_object([]) do |(column, values_hash), array|
    values_hash.each do |group, value|
      array << yield(column, group, value) if group
    end
  end
end
raise_error(msg) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 139
def raise_error(msg)
  raise Error.new(msg)
end
range_str(range) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 105
def range_str(range)
  validate_range(range)

  min = insert_val(range.min)
  max = insert_val(range.max)

  "BETWEEN #{min} AND #{max}"
end
validate_hash() click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 31
def validate_hash
  raise_error("Incompatible hash: #{@hash}.") unless matches_conditions?
end
validate_options() click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 35
def validate_options
  valid_keys = Default::OPTIONS.keys
  invalid_keys = @options.keys - valid_keys
  return if valid = invalid_keys.empty?

  valid_keys_str = valid_keys.join(', ')
  invalid_keys_str = invalid_keys.join(', ')
  raise_error "You provided invalid options: #{invalid_keys_str}. Supported options include: #{valid_keys_str}."
end
validate_range(range) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 114
def validate_range(range)
  min = range.min
  max = range.max

  valid = min && max && (min < max)
  raise_error("Improper range: #{range}.") unless valid
end
value_str(value) click to toggle source
# File lib/convenient_grouper/hash_converter.rb, line 127
def value_str(value)
  "= #{insert_val(value)}"
end