class Patriarch::ToolServices::RedisExtractorService
Service providing methods that extract information from Redis Database like which entities behaved on me or i behaved on and when without knowing how the internals work. Methods are hence wrapped into sugar when called from models For instance with add_behaviour :like, :on => [:item] embedded in model User we build a tool method called items_i_like_ids that knows how to call get_ids_from_sorted_set
but does not care about internals
Public Instance Methods
This gets ids stored in a given Redis::SortedSet and returns in an adapted format. Hence it supports various options.
Base options are born from those supported by Redis::SortedSet and allow some sorting on score with options :from and :limit Original options were :from and :to More on this in redis-objects documentation
Bipartite / With scores When storing data in bipartite transactions there is 2 protagonists hence, each protagonist only has on id to remember The output format is thus [id1,id2, …] or [ [id1,score1], [id2,score2], …] if called with option :with_scores
Tripartite / With scores / protagonist type When storing data in tripartite there are 3 protagonists. Each of them needs to know about the 2 others most of the time. We store then triplets built like this : [actor,target,medium]. Triplets are marshalled. We choose which of the protagonist we want to retrieve information about thanks to option :protagonist_type Values can be :actor, :target or :medium The output format is thus [id_protagonist_type1, id_protagonist_type2, …] or [[id_pt1, score1], [id_pt2,score2]] if called with option :with_scores
Sometimes we want to know it all from target or actor point of view we hence call with option :with_medium Option :with_scores is not supported here Output format is thus [{:actor1 => actor_id1, :target1 => target_id1, :medium1 => medium_id1}, {actor2,target2,medium2 …}, …]
For more information about redis dao return type, please go on github.com/nateware and visit redis-objects
# File lib/patriarch/tool_services/redis_extractor_service.rb, line 31 def get_ids_from_sorted_set(calling_entity,redis_key,options={}) from = options[:from] || 0 limit = options[:limit] || :infinity if limit == :infinity to = -1 else to = from + limit -1 end if options[:tripartite] dao = Redis::SortedSet.new("#{calling_entity.class.name.underscore}:#{calling_entity.id}:#{redis_key}", :marshal => true) else dao = Redis::SortedSet.new("#{calling_entity.class.name.underscore}:#{calling_entity.id}:#{redis_key}") end if options[:with_scores] # Do not use this anymore, go take the right redis objects not using this kind of methods ... ids_with_scores_from_redis = dao.revrange(from,to,:with_scores => true) || [] result = ids_with_scores_from_redis else ids_from_redis = dao.revrange(from,to) || [] result = ids_from_redis end if options[:with_medium] if options[:with_scores] raise Exception, "with_scores options is not supported along with_medium" end result.map!{ |triplet_id| {:actor => triplet_id[0].to_i, :target => triplet_id[1].to_i, :medium => triplet_id[2].to_i} } return result else if options[:tripartite] if options[:with_scores] if options[:protagonist_type] == :actor result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[0],tuple.last]} elsif options[:protagonist_type] == :target result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[1],tuple.last]} elsif options[:protagonist_type] == :medium result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[2],tuple.last]} end else if options[:protagonist_type] == :actor result.map!{ |triplet_id| triplet_id[0] } elsif options[:protagonist_type] == :target result.map!{ |triplet_id| triplet_id[1] } elsif options[:protagonist_type] == :medium result.map!{ |triplet_id| triplet_id[2] } end end end end # This sanitizes strings returned by Redis::Objects into integers. result.map! do |x| if x.is_a? Array x[0].to_i x # FIXME Bullshit détecté ici else x.to_i end end result end
Tool method allowing to instantiate models from ids we find with method get_ids_from_sorted_sets
# File lib/patriarch/tool_services/redis_extractor_service.rb, line 98 def get_models_from_ids(calling_entity,model,get_id_method,options={}) if options[:with_medium] id_hash_from_redis = calling_entity.send(get_id_method,options) return id_hash_from_redis end if options[:with_scores] ids_with_scores_from_redis = calling_entity.send(get_id_method,options) ids_with_scores_from_redis.map! do |id,score| [model.find(id),score] end else ids_from_redis = calling_entity.send(get_id_method,options) model.find(ids_from_redis) end end