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

get_ids_from_sorted_set(calling_entity,redis_key,options={}) click to toggle source

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
get_models_from_ids(calling_entity,model,get_id_method,options={}) click to toggle source

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