Skip to content

Instantly share code, notes, and snippets.

@goodfeel
Created August 20, 2014 08:10
Show Gist options
  • Save goodfeel/f1306f3c44cb9b38e71f to your computer and use it in GitHub Desktop.
Save goodfeel/f1306f3c44cb9b38e71f to your computer and use it in GitHub Desktop.
My custom HstoreQuery, this is a hacking solution with typecast on hStore value for comparison. My model already infers the data type.
class HstoreQuery
attr_accessor :klass, :hstore_field, :parent
# parent = Game.first.players
# a = HstoreQuery.new Player, 'game_values', parent
# a.search 'float_money', '>', 9
def initialize(klass, field, parent = nil)
self.klass = klass
self.hstore_field = field
self.parent = parent
end
def search(field, operator, value)
get_actor
query = "(#{self.hstore_field} -> '#{field}')#{get_type(field)} #{operator} '#{value}'"
@actor.where(query)
end
# [{field: '...', operator: '..', value: '...', connector: 'OR'}, ....]
# arr = [{field: 'float_money', operator: '>', value: '0', connector: 'OR'}, {field: 'boolean_funny', operator: '=', value: 'false', connector: ''}]
def array_search(conditions = [])
get_actor
query = ""
conditions.each do |c|
query += "(#{self.hstore_field} -> '#{c[:field]}')#{get_type(c[:field])} #{c[:operator]} '#{c[:value]}' "
query += "#{get_condition_predicate(c[:connector])} " if c[:connector]
end
@actor.where(query)
end
def keys(limit = 6)
query = ActiveRecord::Base.connection.execute("SELECT key, count(*) FROM (SELECT (each(#{self.hstore_field})).key FROM #{self.klass.table_name}) AS stat GROUP BY key ORDER BY count DESC, key LIMIT #{limit}")
query.map { |x| x }
end
private
def get_actor
@actor = parent.nil? ? klass : parent
end
def get_type(field)
temp_field = field.split('_')
if ['int', 'decimal', 'float', 'boolean'].include? temp_field[0]
"::#{temp_field[0]}"
else
''
end
end
# Just in case to use Squeel or Arel.
def get_condition_predicate(connector)
if connector == 'OR'
"OR"
elsif connector == 'AND'
"AND"
else
""
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment