217 lines
5.2 KiB
Ruby
217 lines
5.2 KiB
Ruby
module JamRuby
|
|
class BaseSearch < JsonStore
|
|
|
|
attr_accessor :page_count, :results, :page_number
|
|
|
|
ANY_VAL_STR = 'any'
|
|
ANY_VAL_INT = -1
|
|
|
|
VAL_YES = 'yes'
|
|
VAL_NO = 'no'
|
|
|
|
PER_PAGE = 10
|
|
PG_SMALLINT_MAX = 32767
|
|
|
|
KEY_SKILL = 'skill_level'
|
|
KEY_GENRES = 'genres'
|
|
KEY_INSTRUMENTS = 'instruments'
|
|
KEY_GIGS = 'concert_gigs'
|
|
KEY_SORT_ORDER = 'sort_order'
|
|
|
|
SORT_VALS = %W{ latency distance }
|
|
SORT_ORDERS = {
|
|
SORT_VALS[0] => 'Latency to Me',
|
|
SORT_VALS[1] => 'Distance to Me'
|
|
}
|
|
|
|
SKILL_VALS = [ANY_VAL_INT, 1, 2]
|
|
SKILL_LEVELS = {
|
|
SKILL_VALS[0] => 'Any',
|
|
SKILL_VALS[1] => 'Amateur',
|
|
SKILL_VALS[2] => 'Pro',
|
|
}
|
|
|
|
GIG_COUNTS = [ANY_VAL_INT, 0, 1, 2, 3, 4]
|
|
GIG_LABELS = {
|
|
GIG_COUNTS[0] => 'Any',
|
|
GIG_COUNTS[1] => 'under 10',
|
|
GIG_COUNTS[2] => '10 to 50',
|
|
GIG_COUNTS[3] => '50 to 100',
|
|
GIG_COUNTS[4] => 'over 100'
|
|
}
|
|
|
|
INSTRUMENT_PROFICIENCY = {
|
|
1 => 'Beginner',
|
|
2 => 'Intermediate',
|
|
3 => 'Expert',
|
|
}
|
|
|
|
def self.json_schema
|
|
{
|
|
KEY_SORT_ORDER => self::SORT_VALS[0],
|
|
KEY_INSTRUMENTS => [],
|
|
KEY_GENRES => [],
|
|
KEY_GIGS => self::GIG_COUNTS[0].to_s,
|
|
}
|
|
end
|
|
|
|
def self.search_filter_meta(jschema=nil, sort_order=nil)
|
|
jschema ||= self.json_schema
|
|
schema_keys = jschema.keys
|
|
sort_order ||= { keys: self::SORT_VALS, map: self::SORT_ORDERS }
|
|
multi_keys = jschema.collect { |kk,vv| vv.is_a?(Array) ? kk : nil }.compact
|
|
{
|
|
per_page: self::PER_PAGE,
|
|
filter_keys: {
|
|
keys: schema_keys,
|
|
multi: multi_keys,
|
|
single: schema_keys - multi_keys,
|
|
},
|
|
sort_order: sort_order
|
|
}
|
|
end
|
|
|
|
RESULT_FOLLOW = :follows
|
|
RESULT_FRIEND = :friends
|
|
|
|
COUNT_FRIEND = :count_friend
|
|
COUNT_FOLLOW = :count_follow
|
|
COUNT_RECORD = :count_record
|
|
COUNT_SESSION = :count_session
|
|
COUNTERS = [COUNT_FRIEND, COUNT_FOLLOW, COUNT_RECORD, COUNT_SESSION]
|
|
|
|
def self.user_search_filter(user)
|
|
unless ss = user.send(self.name.demodulize.tableize.singularize)
|
|
ss = self.create_search(user)
|
|
end
|
|
ss
|
|
end
|
|
|
|
def self.search_filter_json(user)
|
|
self.user_search_filter(user).json
|
|
end
|
|
|
|
def self.create_search(user)
|
|
ms = self.new
|
|
ms.user = user
|
|
ms.data_blob = self.json_schema
|
|
ms.save!
|
|
ms
|
|
end
|
|
|
|
def self.search_target_class
|
|
end
|
|
|
|
def self.genre_ids
|
|
@@genre_ids ||= Hash[ *Genre.pluck(:id).collect { |v| [ v, v ] }.flatten ]
|
|
end
|
|
|
|
def self.instrument_ids
|
|
@@instrument_ids ||= Hash[ *Instrument.pluck(:id).collect { |v| [ v, v ] }.flatten ]
|
|
end
|
|
|
|
def _genres(rel, query_data=json)
|
|
gids = query_data[KEY_GENRES]
|
|
unless gids.blank?
|
|
allgids = self.class.genre_ids
|
|
gids = gids.select { |gg| allgids.has_key?(gg) }
|
|
|
|
unless gids.blank?
|
|
gidsql = gids.join("','")
|
|
gpsql = "SELECT player_id FROM genre_players WHERE (player_type = '#{self.class.search_target_class.name}' AND genre_id IN ('#{gidsql}'))"
|
|
rel = rel.where("#{self.class.search_target_class.table_name}.id IN (#{gpsql})")
|
|
end
|
|
end
|
|
rel
|
|
end
|
|
|
|
def _instruments(rel, query_data=json)
|
|
unless (instruments = query_data[KEY_INSTRUMENTS]).blank?
|
|
instrids = self.class.instrument_ids
|
|
instruments = instruments.select { |ii| instrids.has_key?(ii['instrument_id']) }
|
|
|
|
unless instruments.blank?
|
|
instsql = "SELECT player_id FROM musicians_instruments WHERE (("
|
|
instsql += instruments.collect do |inst|
|
|
unless MusicianInstrument::PROFICIENCY_RANGE === (proflvl=inst['proficiency_level'].to_i)
|
|
proflvl = MusicianInstrument::LEVEL_INTERMEDIATE
|
|
end
|
|
"instrument_id = '#{inst['instrument_id']}' AND proficiency_level = #{proflvl}"
|
|
end.join(") OR (")
|
|
instsql += "))"
|
|
|
|
rel = rel.where("#{self.class.search_target_class.table_name}.id IN (#{instsql})")
|
|
end
|
|
end
|
|
rel
|
|
end
|
|
|
|
def _gigs(rel)
|
|
gg = json[KEY_GIGS].to_i
|
|
rel = rel.where('concert_count = ?',gg) if 0 <= gg
|
|
rel
|
|
end
|
|
|
|
def _skills(rel)
|
|
if 0 < (val = json[KEY_SKILL].to_i)
|
|
rel = rel.where(['skill_level = ?', val])
|
|
end
|
|
rel
|
|
end
|
|
|
|
def _sort_order(rel)
|
|
end
|
|
|
|
def do_search(params={})
|
|
end
|
|
|
|
def process_results_page(objs)
|
|
end
|
|
|
|
def search_includes(rel)
|
|
rel
|
|
end
|
|
|
|
def search_results_page(filter=nil, page=1)
|
|
if filter
|
|
self.data_blob = filter
|
|
self.save
|
|
else
|
|
filter = self.data_blob
|
|
end
|
|
|
|
rel = do_search(filter)
|
|
|
|
@page_number = [page.to_i, 1].max
|
|
rel = rel.paginate(:page => @page_number, :per_page => self.class::PER_PAGE)
|
|
|
|
rel = self.search_includes(rel)
|
|
@page_count = rel.total_pages
|
|
|
|
process_results_page(rel.all)
|
|
end
|
|
|
|
def reset_filter
|
|
self.data_blob = self.class.json_schema
|
|
self.save
|
|
end
|
|
|
|
def reset_search_results
|
|
reset_filter
|
|
search_results_page
|
|
end
|
|
|
|
def search_type
|
|
self.class.to_s
|
|
end
|
|
|
|
def is_blank?
|
|
self.data_blob == self.class.json_schema
|
|
end
|
|
|
|
def description
|
|
end
|
|
|
|
end
|
|
end
|