Created
August 20, 2014 08:10
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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