patriarch 0.0.4 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.md +43 -3
- data/lib/generators/patriarch/behaviour_generator.rb +117 -0
- data/lib/generators/patriarch/install_generator.rb +27 -10
- data/lib/generators/patriarch/templates/after_manager_service.rb +2 -1
- data/lib/generators/patriarch/templates/authorization_service.rb +1 -1
- data/lib/generators/patriarch/templates/before_manager_service.rb +2 -1
- data/lib/generators/patriarch/templates/before_service.rb +1 -1
- data/lib/generators/patriarch/templates/empty_behaviours_declaration.rb +2 -0
- data/lib/generators/patriarch/templates/empty_services_declaration.rb +2 -0
- data/lib/generators/patriarch/templates/manager_service-tripartite.rb +36 -0
- data/lib/generators/patriarch/templates/manager_service.rb +15 -8
- data/lib/generators/patriarch/templates/service-tripartite.rb +5 -0
- data/lib/generators/patriarch/templates/service.rb +1 -1
- data/lib/generators/patriarch/templates/tools_methods.rb +2 -1
- data/lib/generators/patriarch/templates/undo_service-tripartite.rb +5 -0
- data/lib/patriarch/behaviours.rb +170 -13
- data/lib/patriarch/dao_services/bipartite_relationship_builder_service.rb +0 -4
- data/lib/patriarch/dao_services/redis_mapper_service.rb +45 -8
- data/lib/patriarch/dao_services/retriever_service.rb +26 -4
- data/lib/patriarch/dao_services/tripartite_relationship_builder_service.rb +51 -0
- data/lib/patriarch/manager_service.rb +0 -9
- data/lib/patriarch/tool_services/redis_cleaner_service.rb +64 -0
- data/lib/patriarch/tool_services/redis_extractor_service.rb +33 -4
- data/lib/patriarch/transaction.rb +9 -4
- data/lib/patriarch/transaction_services/transaction_manager_service.rb +9 -0
- data/lib/patriarch/transaction_step.rb +10 -2
- data/lib/patriarch/version.rb +1 -1
- data/lib/patriarch.rb +11 -5
- data/patriarch.gemspec +2 -4
- data/spec/lib/patriarch/behaviours_spec.rb +233 -0
- data/spec/lib/patriarch/{bipartite_relationship_builder_spec.rb → dao_services/bipartite_relationship_builder_spec.rb} +19 -23
- data/spec/lib/patriarch/dao_services/tripartite_relationship_builder_spec.rb +49 -0
- data/spec/lib/patriarch/redis_mapper_service_spec.rb +46 -14
- data/spec/lib/patriarch/retriever_service_spec.rb +27 -8
- data/spec/lib/patriarch/tool_services/redis_cleaner_service_spec.rb +48 -0
- data/spec/lib/patriarch/transaction_spec.rb +13 -0
- data/spec/lib/patriarch/transaction_step_spec.rb +29 -0
- data/spec/spec_helper.rb +45 -11
- metadata +30 -53
- data/lib/generators/patriarch/patriarch_generator.rb +0 -114
- data/lib/patriarch/dao_services/.DAOinstancier.rb.swp +0 -0
- data/lib/patriarch/tool_services/redis_cleaner.rb +0 -47
- data/spec/lib/patriarch/add_behaviour_spec.rb +0 -59
- data/spec/lib/patriarch/like_service_spec.rb +0 -19
| @@ -2,11 +2,9 @@ require "redis/objects/sorted_sets" | |
| 2 2 |  | 
| 3 3 | 
             
            class Patriarch::DAOServices::BipartiteRelationshipBuilderService < Patriarch::Service
         | 
| 4 4 | 
             
              def create(transaction_item)
         | 
| 5 | 
            -
                # t => changer nom pour différencier de la date créée pour le Patriarch::Transaction 
         | 
| 6 5 | 
             
                t = Time.now.to_f
         | 
| 7 6 | 
             
                dao_tab = Patriarch::DAOServices::RetrieverService.instance.call(transaction_item)
         | 
| 8 7 |  | 
| 9 | 
            -
                # Go hash plz
         | 
| 10 8 | 
             
                actor_dao = dao_tab[:actor]
         | 
| 11 9 | 
             
                target_dao = dao_tab[:target]
         | 
| 12 10 |  | 
| @@ -21,14 +19,12 @@ class Patriarch::DAOServices::BipartiteRelationshipBuilderService < Patriarch::S | |
| 21 19 | 
             
              def destroy(transaction_item)
         | 
| 22 20 | 
             
                dao_tab = Patriarch::DAOServices::RetrieverService.instance.call(transaction_item)
         | 
| 23 21 |  | 
| 24 | 
            -
                # Go hash plz
         | 
| 25 22 | 
             
                actor_dao = dao_tab[:actor]
         | 
| 26 23 | 
             
                target_dao = dao_tab[:target]
         | 
| 27 24 |  | 
| 28 25 | 
             
                l   = lambda { actor_dao.delete transaction_item.target_id }
         | 
| 29 26 | 
             
                ll  = lambda { target_dao.delete transaction_item.actor_id }
         | 
| 30 27 |  | 
| 31 | 
            -
                # care about that, should be encapsulated into a beautiful add_to_queue method
         | 
| 32 28 | 
             
                transaction_item.add_to_queue l
         | 
| 33 29 | 
             
                transaction_item.add_to_queue ll
         | 
| 34 30 | 
             
              end
         | 
| @@ -5,31 +5,68 @@ class Patriarch::DAOServices::RedisMapperService < Patriarch::Service | |
| 5 5 | 
             
                relation_type     = transac.relation_type
         | 
| 6 6 | 
             
                actor_type        = transac.actor_type
         | 
| 7 7 | 
             
                target_type       = transac.target_type
         | 
| 8 | 
            +
                medium_type       = transac.medium_type
         | 
| 8 9 |  | 
| 9 10 | 
             
                relation_type_str = sanitize_relation_type(relation_type.to_s)
         | 
| 10 11 |  | 
| 11 | 
            -
                if  | 
| 12 | 
            -
                   | 
| 12 | 
            +
                if transac.tripartite?
         | 
| 13 | 
            +
                  if protagonist_type == :actor
         | 
| 14 | 
            +
                    redis_tripartite_config_for_actor(target_type,medium_type,relation_type_str)
         | 
| 15 | 
            +
                  elsif protagonist_type == :target
         | 
| 16 | 
            +
                    redis_tripartite_config_for_target(actor_type,medium_type,relation_type_str)
         | 
| 17 | 
            +
                  elsif protagonist_type == :medium
         | 
| 18 | 
            +
                   redis_tripartite_config_for_medium(actor_type,target_type,relation_type_str)
         | 
| 19 | 
            +
                  end 
         | 
| 13 20 | 
             
                else
         | 
| 14 | 
            -
                   | 
| 21 | 
            +
                  if protagonist_type == :actor
         | 
| 22 | 
            +
                    redis_bipartite_config_for_actor(target_type,relation_type_str)
         | 
| 23 | 
            +
                  elsif protagonist_type == :target
         | 
| 24 | 
            +
                    redis_bipartite_config_for_target(actor_type,relation_type_str)
         | 
| 25 | 
            +
                  end
         | 
| 15 26 | 
             
                end
         | 
| 16 27 | 
             
              end
         | 
| 17 28 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
              def redis_config_for_actor_on(model_name,relation_type_str)
         | 
| 29 | 
            +
              def redis_bipartite_config_for_actor(target_model_name,relation_type_str)
         | 
| 20 30 | 
             
                # example : items_i_like ...    
         | 
| 21 31 | 
             
                { 
         | 
| 22 | 
            -
                  :type => "sorted_set",  | 
| 32 | 
            +
                  :type => "sorted_set", 
         | 
| 33 | 
            +
                  :key => "patriarch_#{target_model_name.to_s.tableize}_i_#{relation_type_str}"
         | 
| 23 34 | 
             
                }
         | 
| 24 35 | 
             
              end
         | 
| 25 36 |  | 
| 26 | 
            -
              def  | 
| 37 | 
            +
              def redis_bipartite_config_for_target(actor_model_name,relation_type_str)
         | 
| 27 38 | 
             
                # example : items_liking_me ...
         | 
| 28 39 | 
             
                { 
         | 
| 29 | 
            -
                  :type => "sorted_set",  | 
| 40 | 
            +
                  :type => "sorted_set", 
         | 
| 41 | 
            +
                  :key => "patriarch_#{actor_model_name.to_s.tableize}_#{progressive_present(relation_type_str)}_me"
         | 
| 30 42 | 
             
                }
         | 
| 31 43 | 
             
              end  
         | 
| 32 44 |  | 
| 45 | 
            +
              def redis_tripartite_config_for_actor(target_model_name,medium_model_name,relation_type_str)
         | 
| 46 | 
            +
                { 
         | 
| 47 | 
            +
                  :type => "sorted_set", 
         | 
| 48 | 
            +
                  :key => "patriarch_#{target_model_name.to_s.tableize}_i_#{relation_type_str}_via_#{medium_model_name.to_s.tableize}",
         | 
| 49 | 
            +
                  :options => { :marshal => true }
         | 
| 50 | 
            +
                }
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
              
         | 
| 53 | 
            +
              def redis_tripartite_config_for_medium(actor_model_name,target_model_name,relation_type_str)
         | 
| 54 | 
            +
                { 
         | 
| 55 | 
            +
                  :type => "sorted_set", 
         | 
| 56 | 
            +
                  :key => "patriarch_#{actor_model_name.to_s.tableize}_#{progressive_present(relation_type_str)}_#{target_model_name.to_s.tableize}_via_me",
         | 
| 57 | 
            +
                  :options => { :marshal => true }      
         | 
| 58 | 
            +
                }       
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              def redis_tripartite_config_for_target(actor_model_name,medium_model_name,relation_type_str)
         | 
| 62 | 
            +
                # example : items_praising_me_via_comments
         | 
| 63 | 
            +
                { 
         | 
| 64 | 
            +
                  :type => "sorted_set", 
         | 
| 65 | 
            +
                  :key => "patriarch_#{actor_model_name.to_s.tableize}_#{progressive_present(relation_type_str)}_me_via_#{medium_model_name.to_s.tableize}",
         | 
| 66 | 
            +
                  :options => { :marshal => true }      
         | 
| 67 | 
            +
                }       
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
             | 
| 33 70 | 
             
              def progressive_present(behaviour_verb)
         | 
| 34 71 | 
             
                # like becomes => liking
         | 
| 35 72 | 
             
                (Verbs::Conjugator.conjugate behaviour_verb.to_sym, :aspect => :progressive).split(/ /).last
         | 
| @@ -7,8 +7,11 @@ class Patriarch::DAOServices::RetrieverService < Patriarch::Service | |
| 7 7 | 
             
              # go hash
         | 
| 8 8 | 
             
              def call(transaction_item)     
         | 
| 9 9 | 
             
                result = {}
         | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 10 | 
            +
                result[:actor]  = instantiate_DAO_for_actor(transaction_item)
         | 
| 11 | 
            +
                result[:target] = instantiate_DAO_for_target(transaction_item)
         | 
| 12 | 
            +
                if transaction_item.tripartite?
         | 
| 13 | 
            +
                  result[:medium] = instantiate_DAO_for_medium(transaction_item)    
         | 
| 14 | 
            +
                end
         | 
| 12 15 | 
             
                result  
         | 
| 13 16 | 
             
              end
         | 
| 14 17 |  | 
| @@ -21,6 +24,10 @@ class Patriarch::DAOServices::RetrieverService < Patriarch::Service | |
| 21 24 | 
             
              def get_DAO_info_for_target(transaction_item)
         | 
| 22 25 | 
             
                Patriarch::DAOServices::RedisMapperService.instance.call(transaction_item,:target)
         | 
| 23 26 | 
             
              end
         | 
| 27 | 
            +
              
         | 
| 28 | 
            +
              def get_DAO_info_for_medium(transaction_item)
         | 
| 29 | 
            +
                Patriarch::DAOServices::RedisMapperService.instance.call(transaction_item,:medium)
         | 
| 30 | 
            +
              end
         | 
| 24 31 |  | 
| 25 32 | 
             
              def instantiate_DAO_for_actor(transaction_item)
         | 
| 26 33 | 
             
                dao_info = get_DAO_info_for_actor(transaction_item) 
         | 
| @@ -33,9 +40,24 @@ class Patriarch::DAOServices::RetrieverService < Patriarch::Service | |
| 33 40 | 
             
                  raise InvalidRedisTypeException, "Redis constants available were #{Redis::Objects.constants} and supplied type was #{dao_info[:type]}"
         | 
| 34 41 | 
             
                end
         | 
| 35 42 |  | 
| 36 | 
            -
                redis_dao_class.new("#{actor_type}:#{actor_id}:#{dao_info[:key]}")
         | 
| 43 | 
            +
                redis_dao_class.new("#{actor_type}:#{actor_id}:#{dao_info[:key]}",dao_info[:options])
         | 
| 37 44 | 
             
              end
         | 
| 38 45 |  | 
| 46 | 
            +
              def instantiate_DAO_for_medium(transaction_item)
         | 
| 47 | 
            +
                dao_info = get_DAO_info_for_medium(transaction_item) 
         | 
| 48 | 
            +
                medium_id = transaction_item.medium_id
         | 
| 49 | 
            +
                medium_type = transaction_item.medium_type
         | 
| 50 | 
            +
                
         | 
| 51 | 
            +
                puts "#{medium_type} - #{medium_id}"
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                if Redis::Objects.constants.map(&:to_s).include?("#{dao_info[:type].pluralize.camelize}")
         | 
| 54 | 
            +
                  redis_dao_class = "Redis::#{dao_info[:type].camelize}".constantize
         | 
| 55 | 
            +
                else
         | 
| 56 | 
            +
                  raise InvalidRedisTypeException, "Redis constants available were #{Redis::Objects.constants} and supplied type was #{dao_info[:type]}"
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                redis_dao_class.new("#{medium_type}:#{medium_id}:#{dao_info[:key]}",dao_info[:options])
         | 
| 60 | 
            +
              end  
         | 
| 39 61 |  | 
| 40 62 | 
             
              def instantiate_DAO_for_target(transaction_item)
         | 
| 41 63 | 
             
                dao_info = get_DAO_info_for_target(transaction_item)
         | 
| @@ -47,7 +69,7 @@ class Patriarch::DAOServices::RetrieverService < Patriarch::Service | |
| 47 69 | 
             
                else
         | 
| 48 70 | 
             
                  raise InvalidRedisTypeException, "Redis constants available were #{Redis::Objects.constants} and supplied type was #{dao_info[:type]}"
         | 
| 49 71 | 
             
                end
         | 
| 50 | 
            -
                redis_dao_class.new("#{target_type}:#{target_id}:#{dao_info[:key]}")    
         | 
| 72 | 
            +
                redis_dao_class.new("#{target_type}:#{target_id}:#{dao_info[:key]}",dao_info[:options])    
         | 
| 51 73 | 
             
              end
         | 
| 52 74 | 
             
            end
         | 
| 53 75 |  | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            require "redis/objects/sorted_sets"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Patriarch::DAOServices::TripartiteRelationshipBuilderService < Patriarch::Service
         | 
| 4 | 
            +
              def create(transaction_item)
         | 
| 5 | 
            +
                t = Time.now.to_f
         | 
| 6 | 
            +
                dao_tab = Patriarch::DAOServices::RetrieverService.instance.call(transaction_item)
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                actor_dao = dao_tab[:actor]
         | 
| 9 | 
            +
                target_dao = dao_tab[:target]
         | 
| 10 | 
            +
                medium_dao = dao_tab[:medium]    
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                protagonist_ids = [transaction_item.actor_id,transaction_item.target_id,transaction_item.medium_id]
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                l    = build_lambda_for_create(actor_dao,protagonist_ids,t)
         | 
| 15 | 
            +
                ll   = build_lambda_for_create(target_dao,protagonist_ids,t)
         | 
| 16 | 
            +
                lll  = build_lambda_for_create(medium_dao,protagonist_ids,t)
         | 
| 17 | 
            +
             
         | 
| 18 | 
            +
                # care about that, should be encapsulated into a beautiful add_to_queue method
         | 
| 19 | 
            +
                transaction_item.add_to_queue l
         | 
| 20 | 
            +
                transaction_item.add_to_queue ll
         | 
| 21 | 
            +
                transaction_item.add_to_queue lll    
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def destroy(transaction_item)
         | 
| 25 | 
            +
                dao_tab = Patriarch::DAOServices::RetrieverService.instance.call(transaction_item)
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
                actor_dao = dao_tab[:actor]
         | 
| 28 | 
            +
                target_dao = dao_tab[:target]
         | 
| 29 | 
            +
                medium_dao = dao_tab[:medium]    
         | 
| 30 | 
            +
                
         | 
| 31 | 
            +
                protagonist_ids = [transaction_item.actor_id,transaction_item.target_id,transaction_item.medium_id]
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                l   = lambda { actor_dao.delete protagonist_ids }
         | 
| 34 | 
            +
                ll  = lambda { target_dao.delete protagonist_ids }
         | 
| 35 | 
            +
                lll = lambda { medium_dao.delete protagonist_ids }
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                transaction_item.add_to_queue l
         | 
| 38 | 
            +
                transaction_item.add_to_queue ll
         | 
| 39 | 
            +
                transaction_item.add_to_queue lll    
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              protected
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              def build_lambda_for_create(dao,ids,time)
         | 
| 45 | 
            +
                if dao.is_a? Redis::SortedSet
         | 
| 46 | 
            +
                  return lambda { dao.add ids, time }
         | 
| 47 | 
            +
                else
         | 
| 48 | 
            +
                  return lambda { dao.add ids }
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -3,14 +3,5 @@ require 'singleton' | |
| 3 3 | 
             
            module Patriarch
         | 
| 4 4 | 
             
              class ManagerService
         | 
| 5 5 | 
             
                include Singleton
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                # /!\ Changer l'architecture ici, l'idée est là
         | 
| 8 | 
            -
                #def resolve(*args, options={})
         | 
| 9 | 
            -
                  # Traitement des options
         | 
| 10 | 
            -
                  # ...
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                  # Traitement normal
         | 
| 13 | 
            -
                #  after_resolve(*args)
         | 
| 14 | 
            -
                #end
         | 
| 15 6 | 
             
              end
         | 
| 16 7 | 
             
            end
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            class Patriarch::ToolServices::RedisCleanerService < Patriarch::Service
         | 
| 2 | 
            +
              
         | 
| 3 | 
            +
              # Shall be tested before implementation ...  
         | 
| 4 | 
            +
              def clean_all(calling_entity)
         | 
| 5 | 
            +
                calling_entity.patriarch_behaviours.keys.each do |behaviour|
         | 
| 6 | 
            +
                  clean_behaviour(calling_entity,behaviour)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def clean_behaviour(calling_entity,behaviour)
         | 
| 11 | 
            +
                my_behaviours = calling_entity.class.patriarch_behaviours
         | 
| 12 | 
            +
                
         | 
| 13 | 
            +
                if my_behaviours.include? behaviour.to_s.underscore.to_sym
         | 
| 14 | 
            +
                  if my_behaviours[behaviour.to_s.underscore.to_sym][:medium_between]
         | 
| 15 | 
            +
                    clean_tripartite_behaviour(calling_entity,behaviour)
         | 
| 16 | 
            +
                  else
         | 
| 17 | 
            +
                    clean_bipartite_behaviour(calling_entity,behaviour)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def clean_bipartite_behaviour(calling_entity,behaviour)
         | 
| 23 | 
            +
                #
         | 
| 24 | 
            +
                # FIXME Shall clean in one blow, need to prevent transaction from "propagating"
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                # → → → include option to transmit transaction and prevent it from execute
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                # Shall provide an option (:hard) that justs get the job done without heavey transaction stuff if performances
         | 
| 29 | 
            +
                # are aching. Not now, for we have a transaction protecting us we go this way
         | 
| 30 | 
            +
                my_behaviours = calling_entity.class.patriarch_behaviours
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
                # Compute names based on conventions    
         | 
| 33 | 
            +
                progressive_present_behaviour = 
         | 
| 34 | 
            +
                  (Verbs::Conjugator.conjugate behaviour.to_s.underscore.to_sym, :aspect => :progressive).split(/ /).last
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                transac = Patriarch::TransactionServices::TransactionManagerService.instance.new_transaction("clean_#{behaviour.to_s}".to_sym)
         | 
| 37 | 
            +
                options = { :transac => transac, :stop_execution => true}
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                if my_behaviours.include? behaviour.to_s.underscore.to_sym
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  # Dealing with active behaviour
         | 
| 42 | 
            +
                  if my_behaviours[behaviour.to_s.underscore.to_sym][:on]
         | 
| 43 | 
            +
                    acted_on_models = my_behaviours[behaviour.to_s.underscore.to_sym][:on]
         | 
| 44 | 
            +
                    acted_on_models.each do |acted_on_model|
         | 
| 45 | 
            +
                      calling_entity.send("#{acted_on_model.to_s.tableize}_i_#{behaviour.to_s}").each do |target_i_behaved_on|
         | 
| 46 | 
            +
                        calling_entity.send(Patriarch.undo(behaviour.to_s).underscore,target_i_behaved_on,options)
         | 
| 47 | 
            +
                      end
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  
         | 
| 51 | 
            +
                  # Dealing with passive behaviour
         | 
| 52 | 
            +
                  if my_behaviours[behaviour.to_s.underscore.to_sym][:by]
         | 
| 53 | 
            +
                    targetted_by_models = my_behaviours[behaviour.to_s.underscore.to_sym][:by]
         | 
| 54 | 
            +
                    targetted_by_models.each do |targetted_by_model|
         | 
| 55 | 
            +
                      calling_entity.send("#{targetted_by_model.to_s.tableize}_#{progressive_present_behaviour}_me").each do |target_that_behaved_on_me|
         | 
| 56 | 
            +
                        target_that_behaved_on_me.send(Patriarch.undo(behaviour.to_s).underscore,calling_entity,options)
         | 
| 57 | 
            +
                      end
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end # if my_behaviours.include?
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                transac.execute
         | 
| 63 | 
            +
              end # #clean_behaviour
         | 
| 64 | 
            +
            end  # class Patriarch ...
         | 
| @@ -9,17 +9,46 @@ class Patriarch::ToolServices::RedisExtractorService < Patriarch::Service | |
| 9 9 | 
             
                  to = from + limit -1
         | 
| 10 10 | 
             
                end 
         | 
| 11 11 |  | 
| 12 | 
            -
                 | 
| 12 | 
            +
                if options[:tripartite]
         | 
| 13 | 
            +
                  dao = Redis::SortedSet.new("#{calling_entity.class.name.underscore}:#{calling_entity.id}:#{redis_key}", :marshal => true)
         | 
| 14 | 
            +
                else  
         | 
| 15 | 
            +
                  dao = Redis::SortedSet.new("#{calling_entity.class.name.underscore}:#{calling_entity.id}:#{redis_key}")
         | 
| 16 | 
            +
                end
         | 
| 13 17 |  | 
| 14 18 | 
             
                if options[:with_scores] 
         | 
| 15 19 | 
             
                  # Do not use this anymore, go take the right redis objects not using this kind of methods ...
         | 
| 16 | 
            -
                  # DEGOLASSE
         | 
| 17 20 | 
             
                  ids_with_scores_from_redis = dao.revrange(from,to,:with_scores => true) || []
         | 
| 18 | 
            -
                   | 
| 21 | 
            +
                  result = ids_with_scores_from_redis
         | 
| 19 22 | 
             
                else
         | 
| 20 23 | 
             
                  ids_from_redis = dao.revrange(from,to) || []
         | 
| 21 | 
            -
                  ids_from_redis | 
| 24 | 
            +
                  result = ids_from_redis      
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                if options[:tripartite]
         | 
| 28 | 
            +
                  if options[:with_scores]
         | 
| 29 | 
            +
                    if options[:protagonist_type] == :actor
         | 
| 30 | 
            +
                      result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[0],tuple.last]}
         | 
| 31 | 
            +
                    elsif options[:protagonist_type] == :target
         | 
| 32 | 
            +
                      result.map!{ |triplet_id_with_score| [triplet_id_with_score.first[1],tuple.last]}
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  else
         | 
| 35 | 
            +
                    if options[:protagonist_type] == :actor
         | 
| 36 | 
            +
                      result.map!{ |triplet_id| triplet_id[0] }
         | 
| 37 | 
            +
                    elsif options[:protagonist_type] == :target
         | 
| 38 | 
            +
                      result.map!{ |triplet_id| triplet_id[1] }
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                result.map! do |x| 
         | 
| 44 | 
            +
                  if x.is_a? Array
         | 
| 45 | 
            +
                    x[0].to_i
         | 
| 46 | 
            +
                    x
         | 
| 47 | 
            +
                  else 
         | 
| 48 | 
            +
                    x.to_i
         | 
| 49 | 
            +
                  end
         | 
| 22 50 | 
             
                end
         | 
| 51 | 
            +
                result
         | 
| 23 52 | 
             
              end 
         | 
| 24 53 |  | 
| 25 54 | 
             
              def get_models_from_ids(calling_entity,model,get_id_method,options={})        
         | 
| @@ -3,18 +3,18 @@ module Patriarch | |
| 3 3 | 
             
                attr_reader  :id, :steps, :current_step_number
         | 
| 4 4 | 
             
                attr_reader  :type
         | 
| 5 5 |  | 
| 6 | 
            -
                forwarded_methods_syms =  [:relation_type,:actor_type,:target_type,: | 
| 7 | 
            -
                                           : | 
| 6 | 
            +
                forwarded_methods_syms =  [:relation_type,:actor_type,:target_type,:medium_type,
         | 
| 7 | 
            +
                                           :actor_id,:target_id,:medium_id, 
         | 
| 8 | 
            +
                                           :context,:actor,:target,:medium]
         | 
| 8 9 |  | 
| 9 10 | 
             
                # Forward methods that are not this transaction's job to step object
         | 
| 10 11 | 
             
                forwarded_methods_syms.each do |method_sym|
         | 
| 11 | 
            -
                  define_method(method_sym) do
         | 
| 12 | 
            +
                  define_method(method_sym) do 
         | 
| 12 13 | 
             
                    current_step.send(method_sym)
         | 
| 13 14 | 
             
                  end
         | 
| 14 15 | 
             
                end
         | 
| 15 16 |  | 
| 16 17 |  | 
| 17 | 
            -
                # id => go $redis.incr
         | 
| 18 18 | 
             
                def initialize(type,id) #relation_type,actor,target,
         | 
| 19 19 | 
             
                  @type = type 
         | 
| 20 20 | 
             
                  @id = id 
         | 
| @@ -26,6 +26,7 @@ module Patriarch | |
| 26 26 | 
             
                # A step matches a "like", "follow", "own", etc.
         | 
| 27 27 | 
             
                # Register that we went a step further into the transaction processus
         | 
| 28 28 | 
             
                # Medium is nil by default (bipartite transactions does not require more than target/actor)
         | 
| 29 | 
            +
                # It is there for later support of tripartite transactions
         | 
| 29 30 | 
             
                def add_step(relation_type,actor,target,medium=nil)
         | 
| 30 31 | 
             
                  # Initializes a new step and stores it in the steps array right away
         | 
| 31 32 | 
             
                  new_step = Patriarch::TransactionStep.new(relation_type,actor,target,medium)
         | 
| @@ -47,6 +48,10 @@ module Patriarch | |
| 47 48 | 
             
                  end
         | 
| 48 49 | 
             
                end
         | 
| 49 50 |  | 
| 51 | 
            +
                def tripartite?
         | 
| 52 | 
            +
                  !medium.nil?
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 50 55 | 
             
                def transaction_queue
         | 
| 51 56 | 
             
                  transaction_queue = []
         | 
| 52 57 | 
             
                  steps.each do |step|
         | 
| @@ -6,8 +6,17 @@ end | |
| 6 6 | 
             
            class Patriarch::TransactionServices::TransactionManagerService < Patriarch::ManagerService
         | 
| 7 7 | 
             
              # Fill with logic to manage ressources with transactions ...
         | 
| 8 8 | 
             
              # Can registers transactions and so on ...
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              attr_accessor :count
         | 
| 11 | 
            +
             | 
| 9 12 | 
             
              def new_transaction(type)
         | 
| 10 13 | 
             
                id = Time.now.to_f
         | 
| 14 | 
            +
                incr_count
         | 
| 11 15 | 
             
                Patriarch::Transaction.new(type,id)
         | 
| 12 16 | 
             
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def incr_count
         | 
| 19 | 
            +
                @count ||= 0
         | 
| 20 | 
            +
                @count += 1
         | 
| 21 | 
            +
              end
         | 
| 13 22 | 
             
            end
         | 
| @@ -2,7 +2,7 @@ module Patriarch | |
| 2 2 | 
             
              class TransactionStep
         | 
| 3 3 | 
             
                attr_accessor :context, :queue
         | 
| 4 4 |  | 
| 5 | 
            -
                def initialize(relation_type,actor,target,medium)
         | 
| 5 | 
            +
                def initialize(relation_type,actor,target,medium = nil)
         | 
| 6 6 | 
             
                  @context = { 
         | 
| 7 7 | 
             
                    :relation_type  => relation_type,
         | 
| 8 8 | 
             
                    :actor_type     => actor.class.name.underscore.to_sym,
         | 
| @@ -10,16 +10,24 @@ module Patriarch | |
| 10 10 | 
             
                    :actor_id       => actor.id,
         | 
| 11 11 | 
             
                    :target_id      => target.id,
         | 
| 12 12 | 
             
                  }
         | 
| 13 | 
            +
                  if medium 
         | 
| 14 | 
            +
                    @context.merge! :medium_id => medium.id, :medium_type => medium.class.name.underscore.to_sym
         | 
| 15 | 
            +
                  end
         | 
| 13 16 | 
             
                  @queue = []
         | 
| 14 17 | 
             
                end
         | 
| 15 18 |  | 
| 16 19 | 
             
                # defines access methods to context fields letting it be encapsulated nicely
         | 
| 17 | 
            -
                [:relation_type,:actor_type,:target_type,:actor_id,:target_id].each do |context_key|
         | 
| 20 | 
            +
                [:relation_type,:actor_type,:target_type,:medium_type,:actor_id,:target_id,:medium_id].each do |context_key|
         | 
| 18 21 | 
             
                  define_method(context_key) do
         | 
| 19 22 | 
             
                    context[context_key]
         | 
| 20 23 | 
             
                  end
         | 
| 21 24 | 
             
                end
         | 
| 22 25 |  | 
| 26 | 
            +
                def medium
         | 
| 27 | 
            +
                  return nil unless medium_id && medium_type
         | 
| 28 | 
            +
                  medium_type.to_s.camelize.constantize.find medium_id
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 23 31 | 
             
                def actor
         | 
| 24 32 | 
             
                  actor_type.to_s.camelize.constantize.find actor_id
         | 
| 25 33 | 
             
                end
         | 
    
        data/lib/patriarch/version.rb
    CHANGED
    
    
    
        data/lib/patriarch.rb
    CHANGED
    
    | @@ -4,11 +4,16 @@ require "redis/objects" | |
| 4 4 | 
             
            require "redis/objects/sorted_sets"
         | 
| 5 5 | 
             
            require "rails/generators"
         | 
| 6 6 |  | 
| 7 | 
            -
             | 
| 8 | 
            -
            require File.expand_path('../generators/patriarch/ | 
| 7 | 
            +
            # TODO remove this
         | 
| 8 | 
            +
            # require File.expand_path('../generators/patriarch/behaviour_generator',__FILE__)
         | 
| 9 9 |  | 
| 10 10 | 
             
            module Patriarch
         | 
| 11 | 
            -
            	 | 
| 11 | 
            +
            	module Generators
         | 
| 12 | 
            +
                autoload :BehaviourGenerator,                   'generators/patriarch/behaviour_generator'
         | 
| 13 | 
            +
                autoload :InstallGenerator,                     'generators/patriarch/install_generator'
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              autoload :Service,																'patriarch/service'
         | 
| 12 17 | 
             
            	autoload :Transaction,														'patriarch/transaction'
         | 
| 13 18 | 
             
            	autoload :TransactionStep,                        'patriarch/transaction_step'
         | 
| 14 19 | 
             
            	autoload :AuthorizationService,										'patriarch/authorization_service'
         | 
| @@ -17,12 +22,13 @@ module Patriarch | |
| 17 22 |  | 
| 18 23 | 
             
              module DAOServices	
         | 
| 19 24 | 
             
            		autoload :BipartiteRelationshipBuilderService,  'patriarch/dao_services/bipartite_relationship_builder_service'
         | 
| 25 | 
            +
                autoload :TripartiteRelationshipBuilderService, 'patriarch/dao_services/tripartite_relationship_builder_service'    
         | 
| 20 26 | 
             
            		autoload :RedisMapperService,									  'patriarch/dao_services/redis_mapper_service'
         | 
| 21 27 | 
             
            		autoload :RetrieverService,											'patriarch/dao_services/retriever_service'
         | 
| 22 28 | 
             
            	end
         | 
| 23 29 |  | 
| 24 30 | 
             
            	module ToolServices
         | 
| 25 | 
            -
            		autoload : | 
| 31 | 
            +
            		autoload :RedisCleanerService,									'patriarch/tool_services/redis_cleaner_service'
         | 
| 26 32 | 
             
            		autoload :RedisExtractorService,								'patriarch/tool_services/redis_extractor_service'	
         | 
| 27 33 | 
             
            	end
         | 
| 28 34 |  | 
| @@ -38,4 +44,4 @@ module Patriarch | |
| 38 44 |  | 
| 39 45 | 
             
            end # Patriarch
         | 
| 40 46 |  | 
| 41 | 
            -
            require File.expand_path('../patriarch/behaviours',__FILE__)
         | 
| 47 | 
            +
            require File.expand_path('../patriarch/behaviours',__FILE__)
         | 
    
        data/patriarch.gemspec
    CHANGED
    
    | @@ -10,7 +10,7 @@ Gem::Specification.new do |spec| | |
| 10 10 |  | 
| 11 11 | 
             
            	spec.platform      = Gem::Platform::RUBY
         | 
| 12 12 | 
             
            	spec.licenses 		 = ['MIT']
         | 
| 13 | 
            -
            	spec.post_install_message = "Thanks for installing!"
         | 
| 13 | 
            +
            	spec.post_install_message = "Thanks for installing Patriarch ! Since it's my first gem, please give some advice so i can improve it or even better : contribute"
         | 
| 14 14 |  | 
| 15 15 | 
             
              # Main dependencies
         | 
| 16 16 | 
             
              spec.add_runtime_dependency     "verbs"
         | 
| @@ -19,9 +19,7 @@ Gem::Specification.new do |spec| | |
| 19 19 |  | 
| 20 20 | 
             
              # Dependencies needed for testing
         | 
| 21 21 | 
             
            	spec.add_development_dependency "rspec"
         | 
| 22 | 
            -
               | 
| 23 | 
            -
              spec.add_development_dependency "autotest-rails"
         | 
| 24 | 
            -
              spec.add_development_dependency "ZenTest" 
         | 
| 22 | 
            +
              # TODO run with autotest
         | 
| 25 23 |  | 
| 26 24 | 
             
              # Other options ...
         | 
| 27 25 | 
             
            	spec.files         = `git ls-files`.split($\)
         |