socialization-cassandra 0.0.1.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +0 -0
  5. data/Gemfile +9 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +144 -0
  8. data/Rakefile +10 -0
  9. data/init.rb +1 -0
  10. data/lib/generators/socialization/socialization_generator.rb +17 -0
  11. data/lib/generators/socialization/templates/cassandra/model_comment.rb +2 -0
  12. data/lib/generators/socialization/templates/cassandra/model_follow.rb +2 -0
  13. data/lib/generators/socialization/templates/cassandra/model_like.rb +2 -0
  14. data/lib/generators/socialization/templates/cassandra/model_share.rb +2 -0
  15. data/lib/generators/socialization/templates/socialization_cassandra_migrations.rake +141 -0
  16. data/lib/socialization/actors/commenter.rb +79 -0
  17. data/lib/socialization/actors/follower.rb +79 -0
  18. data/lib/socialization/actors/liker.rb +79 -0
  19. data/lib/socialization/actors/mentioner.rb +79 -0
  20. data/lib/socialization/actors/sharer.rb +79 -0
  21. data/lib/socialization/config/config.rb +51 -0
  22. data/lib/socialization/helpers/acts_as_helpers.rb +49 -0
  23. data/lib/socialization/helpers/string.rb +17 -0
  24. data/lib/socialization/lib/exceptions.rb +3 -0
  25. data/lib/socialization/stores/cassandra/base.rb +149 -0
  26. data/lib/socialization/stores/cassandra/comment.rb +28 -0
  27. data/lib/socialization/stores/cassandra/config.rb +29 -0
  28. data/lib/socialization/stores/cassandra/follow.rb +36 -0
  29. data/lib/socialization/stores/cassandra/like.rb +35 -0
  30. data/lib/socialization/stores/cassandra/mixins/base.rb +8 -0
  31. data/lib/socialization/stores/cassandra/share.rb +28 -0
  32. data/lib/socialization/stores/mixins/base.rb +22 -0
  33. data/lib/socialization/stores/mixins/follow.rb +39 -0
  34. data/lib/socialization/stores/mixins/like.rb +40 -0
  35. data/lib/socialization/stores/mixins/mention.rb +40 -0
  36. data/lib/socialization/version.rb +3 -0
  37. data/lib/socialization/victims/commentable.rb +51 -0
  38. data/lib/socialization/victims/followable.rb +50 -0
  39. data/lib/socialization/victims/likeable.rb +51 -0
  40. data/lib/socialization/victims/shareable.rb +51 -0
  41. data/lib/socialization.rb +17 -0
  42. data/socialization-cassandra.gemspec +30 -0
  43. data/test/actors/follower_test.rb +129 -0
  44. data/test/actors/liker_test.rb +121 -0
  45. data/test/stores/cassandra/base_test.rb +186 -0
  46. data/test/stores/cassandra/config_test.rb +36 -0
  47. data/test/stores/cassandra/follow_store_test.rb +28 -0
  48. data/test/stores/cassandra/like_store_test.rb +26 -0
  49. data/test/string_test.rb +13 -0
  50. data/test/test_helper.rb +259 -0
  51. data/test/victims/followable_test.rb +65 -0
  52. data/test/victims/likeable_test.rb +67 -0
  53. data/test/world_test.rb +107 -0
  54. metadata +209 -0
@@ -0,0 +1,79 @@
1
+ module Socialization
2
+ module Mentioner
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ after_destroy { Socialization.mention_model.remove_mentionables(self) }
7
+
8
+ # Specifies if self can mention {Mentionable} objects.
9
+ #
10
+ # @return [Boolean]
11
+ def is_mentioner?
12
+ true
13
+ end
14
+ alias mentioner? is_mentioner?
15
+
16
+ # Create a new {Mention mention} relationship.
17
+ #
18
+ # @param [Mentionable] mentionable the object to be mentioned.
19
+ # @return [Boolean]
20
+ def mention!(mentionable)
21
+ raise Socialization::ArgumentError, "#{mentionable} is not mentionable!" unless mentionable.respond_to?(:is_mentionable?) && mentionable.is_mentionable?
22
+ Socialization.mention_model.mention!(self, mentionable)
23
+ end
24
+
25
+ # Delete a {Mention mention} relationship.
26
+ #
27
+ # @param [Mentionable] mentionable the object to unmention.
28
+ # @return [Boolean]
29
+ def unmention!(mentionable)
30
+ raise Socialization::ArgumentError, "#{mentionable} is not mentionable!" unless mentionable.respond_to?(:is_mentionable?) && mentionable.is_mentionable?
31
+ Socialization.mention_model.unmention!(self, mentionable)
32
+ end
33
+
34
+ # Toggles a {Mention mention} relationship.
35
+ #
36
+ # @param [Mentionable] mentionable the object to mention/unmention.
37
+ # @return [Boolean]
38
+ def toggle_mention!(mentionable)
39
+ raise Socialization::ArgumentError, "#{mentionable} is not mentionable!" unless mentionable.respond_to?(:is_mentionable?) && mentionable.is_mentionable?
40
+ if mentions?(mentionable)
41
+ unmention!(mentionable)
42
+ false
43
+ else
44
+ mention!(mentionable)
45
+ true
46
+ end
47
+ end
48
+
49
+ # Specifies if self mentions a {Mentionable} object.
50
+ #
51
+ # @param [Mentionable] mentionable the {Mentionable} object to test against.
52
+ # @return [Boolean]
53
+ def mentions?(mentionable)
54
+ raise Socialization::ArgumentError, "#{mentionable} is not mentionable!" unless mentionable.respond_to?(:is_mentionable?) && mentionable.is_mentionable?
55
+ Socialization.mention_model.mentions?(self, mentionable)
56
+ end
57
+
58
+ # Returns all the mentionables of a certain type that are mentioned by self
59
+ #
60
+ # @params [Mentionable] klass the type of {Mentionable} you want
61
+ # @params [Hash] opts a hash of options
62
+ # @return [Array<Mentionable, Numeric>] An array of Mentionable objects or IDs
63
+ def mentionables(klass, opts = {})
64
+ Socialization.mention_model.mentionables(self, klass, opts)
65
+ end
66
+ alias :mentionees :mentionables
67
+
68
+ # Returns a relation for all the mentionables of a certain type that are mentioned by self
69
+ #
70
+ # @params [Mentionable] klass the type of {Mentionable} you want
71
+ # @params [Hash] opts a hash of options
72
+ # @return ActiveRecord::Relation
73
+ def mentionables_relation(klass, opts = {})
74
+ Socialization.mention_model.mentionables_relation(self, klass, opts)
75
+ end
76
+ alias :mentionees_relation :mentionables_relation
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,79 @@
1
+ module Socialization
2
+ module Sharer
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ after_destroy { Socialization.share_model.remove_shareables(self) }
7
+
8
+ # Specifies if self can share {Shareable} objects.
9
+ #
10
+ # @return [Boolean]
11
+ def is_sharer?
12
+ true
13
+ end
14
+ alias sharer? is_sharer?
15
+
16
+ # Create a new {Share share} relationship.
17
+ #
18
+ # @param [Shareable] shareable the object to be shared.
19
+ # @return [Boolean]
20
+ def share!(shareable)
21
+ raise Socialization::ArgumentError, "#{shareable} is not shareable!" unless shareable.respond_to?(:is_shareable?) && shareable.is_shareable?
22
+ Socialization.share_model.share!(self, shareable)
23
+ end
24
+
25
+ # Delete a {Share share} relationship.
26
+ #
27
+ # @param [Shareable] shareable the object to unshare.
28
+ # @return [Boolean]
29
+ def unshare!(shareable)
30
+ raise Socialization::ArgumentError, "#{shareable} is not shareable!" unless shareable.respond_to?(:is_shareable?) && shareable.is_shareable?
31
+ Socialization.share_model.unshare!(self, shareable)
32
+ end
33
+
34
+ # Toggles a {Share share} relationship.
35
+ #
36
+ # @param [Shareable] shareable the object to share/unshare.
37
+ # @return [Boolean]
38
+ def toggle_share!(shareable)
39
+ raise Socialization::ArgumentError, "#{shareable} is not shareable!" unless shareable.respond_to?(:is_shareable?) && shareable.is_shareable?
40
+ if shares?(shareable)
41
+ unshare!(shareable)
42
+ false
43
+ else
44
+ share!(shareable)
45
+ true
46
+ end
47
+ end
48
+
49
+ # Specifies if self shares a {Shareable} object.
50
+ #
51
+ # @param [Shareable] shareable the {Shareable} object to test against.
52
+ # @return [Boolean]
53
+ def shares?(shareable)
54
+ raise Socialization::ArgumentError, "#{shareable} is not shareable!" unless shareable.respond_to?(:is_shareable?) && shareable.is_shareable?
55
+ Socialization.share_model.shares?(self, shareable)
56
+ end
57
+
58
+ # Returns all the shareables of a certain type that are shared by self
59
+ #
60
+ # @params [Shareable] klass the type of {Shareable} you want
61
+ # @params [Hash] opts a hash of options
62
+ # @return [Array<Shareable, Numeric>] An array of Shareable objects or IDs
63
+ def shareables(klass, opts = {})
64
+ Socialization.share_model.shareables(self, klass, opts)
65
+ end
66
+ alias :sharees :shareables
67
+
68
+ # Returns a relation for all the shareables of a certain type that are shared by self
69
+ #
70
+ # @params [Shareable] klass the type of {Shareable} you want
71
+ # @params [Hash] opts a hash of options
72
+ # @return ActiveRecord::Relation
73
+ def shareables_relation(klass, opts = {})
74
+ Socialization.share_model.shareables_relation(self, klass, opts)
75
+ end
76
+ alias :sharees_relation :shareables_relation
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,51 @@
1
+ module Socialization
2
+ class << self
3
+ def follow_model
4
+ if @follow_model
5
+ @follow_model
6
+ else
7
+ ::Follow
8
+ end
9
+ end
10
+
11
+ def follow_model=(klass)
12
+ @follow_model = klass
13
+ end
14
+
15
+ def like_model
16
+ if @like_model
17
+ @like_model
18
+ else
19
+ ::Like
20
+ end
21
+ end
22
+
23
+ def like_model=(klass)
24
+ @like_model = klass
25
+ end
26
+
27
+ def comment_model
28
+ if @comment_model
29
+ @comment_model
30
+ else
31
+ ::Comment
32
+ end
33
+ end
34
+
35
+ def comment_model=(klass)
36
+ @comment_model = klass
37
+ end
38
+
39
+ def share_model
40
+ if @share_model
41
+ @share_model
42
+ else
43
+ ::Share
44
+ end
45
+ end
46
+
47
+ def share_model=(klass)
48
+ @share_model = klass
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,49 @@
1
+ require 'active_support/concern'
2
+
3
+ module Socialization
4
+ module ActsAsHelpers
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ # Make the current class a {Socialization::Follower}
9
+ def acts_as_follower(opts = {})
10
+ include Socialization::Follower
11
+ end
12
+
13
+ # Make the current class a {Socialization::Followable}
14
+ def acts_as_followable(opts = {})
15
+ include Socialization::Followable
16
+ end
17
+
18
+ # Make the current class a {Socialization::Liker}
19
+ def acts_as_liker(opts = {})
20
+ include Socialization::Liker
21
+ end
22
+
23
+ # Make the current class a {Socialization::Likeable}
24
+ def acts_as_likeable(opts = {})
25
+ include Socialization::Likeable
26
+ end
27
+
28
+ # Make the current class a {Socialization::Commenter}
29
+ def acts_as_commenter(opts = {})
30
+ include Socialization::Commenter
31
+ end
32
+
33
+ # Make the current class a {Socialization::Commentable}
34
+ def acts_as_commentable(opts = {})
35
+ include Socialization::Commentable
36
+ end
37
+
38
+ # Make the current class a {Socialization::Sharer}
39
+ def acts_as_sharer(opts = {})
40
+ include Socialization::Sharer
41
+ end
42
+
43
+ # Make the current class a {Socialization::Shareable}
44
+ def acts_as_shareable(opts = {})
45
+ include Socialization::Shareable
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ class String
2
+
3
+ def deep_const_get
4
+ result = nil
5
+ path = self.clone.split("::")
6
+
7
+ path.each do |p|
8
+ result = (result || Kernel).const_get(p)
9
+ end
10
+ result
11
+ end
12
+
13
+ def is_integer?
14
+ self.to_i.to_s == self
15
+ end
16
+
17
+ end
@@ -0,0 +1,3 @@
1
+ module Socialization
2
+ class ArgumentError < ::ArgumentError; end
3
+ end
@@ -0,0 +1,149 @@
1
+ module Socialization
2
+ module CassandraStores
3
+ class Base
4
+
5
+ class << self
6
+ protected
7
+ def actors(victim, klass, options = {})
8
+ if options[:pluck]
9
+ query_result = Socialization.cassandra_session.execute("SELECT actor_type, actor_id from #{backward_table_name} WHERE victim_type = '#{victim.class}' AND victim_id = #{victim.id}")
10
+ return [] if query_result.blank? || query_result.rows.blank?
11
+ query_result.rows.collect {|i| i['actor_id'] if i['actor_type'] == klass.to_s}
12
+ else
13
+ actors_relation(victim, klass, options).to_a
14
+ end
15
+ end
16
+
17
+ def actors_cnt(victim, klass, options = {})
18
+ return 0 if counter_backward_table_name.nil?
19
+ query_result = Socialization.cassandra_session.execute("SELECT cnt from #{counter_backward_table_name} WHERE victim_type = '#{victim.class}' AND victim_id = #{victim.id}")
20
+ return 0 if query_result.blank? || query_result.rows.blank?
21
+ query_result.rows.first['cnt']
22
+ end
23
+
24
+ def actors_relation(victim, klass, options = {})
25
+ ids = actors(victim, klass, :pluck => :id)
26
+ klass.where("#{klass.table_name}.id IN (?)", ids)
27
+ end
28
+
29
+ def victims_relation(actor, klass, options = {})
30
+ ids = victims(actor, klass, :pluck => :id)
31
+ klass.where("#{klass.table_name}.id IN (?)", ids)
32
+ end
33
+
34
+ def victims(actor, klass, options = {})
35
+ if options[:pluck]
36
+ query_result = Socialization.cassandra_session.execute("SELECT victim_type, victim_id from #{forward_table_name} WHERE actor_type='#{actor.class}' AND actor_id=#{actor.id}")
37
+ return [] if query_result.blank? || query_result.rows.blank?
38
+ query_result.rows.collect {|i| i['victim_id'] if i['victim_type'] == klass.to_s}
39
+ else
40
+ victims_relation(actor, klass, options).to_a
41
+ end
42
+ end
43
+
44
+ def victims_cnt(actor, klass, options = {})
45
+ return 0 if counter_forward_table_name.nil?
46
+ query_result = Socialization.cassandra_session.execute("SELECT cnt from #{counter_forward_table_name} WHERE actor_type = '#{actor.class}' AND actor_id = #{actor.id}")
47
+ return 0 if query_result.blank? || query_result.rows.blank?
48
+ query_result.rows.first['cnt']
49
+ end
50
+
51
+ def relation!(actor, victim, options = {})
52
+ unless options[:skip_check] || relation?(actor, victim)
53
+ add_new_entry(actor, victim, {})
54
+ call_after_create_hooks(actor, victim)
55
+ true
56
+ else
57
+ false
58
+ end
59
+ end
60
+
61
+ def unrelation!(actor, victim, options = {})
62
+ if options[:skip_check] || relation?(actor, victim)
63
+ delete_entry(actor, victim, {})
64
+ call_after_destroy_hooks(actor, victim)
65
+ true
66
+ else
67
+ false
68
+ end
69
+ end
70
+
71
+ def relation?(actor, victim)
72
+ if backward_table_name
73
+ query_result = Socialization.cassandra_session.execute("SELECT * FROM #{backward_table_name} WHERE victim_type = '#{victim.class}' AND victim_id = #{victim.id} AND actor_type = '#{actor.class}' AND actor_id = #{actor.id} ALLOW FILTERING")
74
+ !query_result.rows.to_a.empty?
75
+ else
76
+ false
77
+ end
78
+ end
79
+
80
+ def remove_actor_relations(victim)
81
+ query_result = Socialization.cassandra_session.execute("SELECT * FROM #{backward_table_name} WHERE victim_type='#{victim.class}' AND victim_id=#{victim.id}")
82
+ if query_result.present? && query_result.rows.present?
83
+ query_result.rows.to_a.each do |i|
84
+ delete_entry_from_forward_table_name(i['actor_type'], i['actor_id'], victim.class, victim.id)
85
+ Socialization.cassandra_session.execute("DELETE FROM #{backward_table_name} WHERE victim_type='#{victim.class}' AND victim_id=#{victim.id} AND created_at=#{i["created_at"]}")
86
+ end
87
+ end
88
+ # puts "DELETE FROM #{backward_table_name} WHERE victim_type=#{victim.class} AND victim_id=#{victim.id}"
89
+ # Socialization.cassandra_session.execute("DELETE FROM #{backward_table_name} WHERE victim_type=#{victim.class} AND victim_id=#{victim.id}")
90
+ true
91
+ end
92
+
93
+ def remove_victim_relations(actor)
94
+ query_result = Socialization.cassandra_session.execute("SELECT * FROM #{forward_table_name} WHERE actor_type='#{actor.class}' AND actor_id=#{actor.id}")
95
+ if query_result.present? && query_result.rows.present?
96
+ query_result.rows.to_a.each do |i|
97
+ delete_entry_from_backward_table_name(actor.class, actor.id, i['victim_type'], i['victim_id'])
98
+ Socialization.cassandra_session.execute("DELETE FROM #{forward_table_name} WHERE actor_type='#{actor.class}' AND actor_id=#{actor.id} AND created_at=#{i["created_at"]}")
99
+ end
100
+ end
101
+ # Socialization.cassandra_session.execute("DELETE FROM #{forward_table_name} WHERE actor_type='#{actor.class}' AND actor_id=#{actor.id}")
102
+ true
103
+ end
104
+
105
+
106
+ private
107
+
108
+ def add_new_entry(actor, victim, options={})
109
+ [forward_table_name, backward_table_name].uniq.each do |table_name|
110
+ query_columns = "actor_type, actor_id, victim_type, victim_id, created_at"
111
+ query_values = "'#{actor.class}', #{actor.id}, '#{victim.class}', #{victim.id}, #{(Time.now.to_f * 100000).to_i}"
112
+ if options[:text]
113
+ query_columns += ", text"
114
+ query_values += ", '#{options[:text]}'"
115
+ end
116
+ if options[:networks] && options[:networks].is_a?(Array)
117
+ query_columns += ", networks"
118
+ query_values += ", #{options[:networks].to_s.gsub('[', '{').gsub(']', '}')}"
119
+ end
120
+ Socialization.cassandra_session.execute("INSERT INTO #{table_name} (#{query_columns}) VALUES (#{query_values})")
121
+ end
122
+ Socialization.cassandra_session.execute("UPDATE #{counter_forward_table_name} SET cnt = cnt + 1 WHERE actor_type = '#{actor.class}' AND actor_id = #{actor.id}") if counter_forward_table_name
123
+ Socialization.cassandra_session.execute("UPDATE #{counter_backward_table_name} SET cnt = cnt + 1 WHERE victim_type = '#{victim.class}' AND victim_id = #{victim.id}") if counter_backward_table_name
124
+ end
125
+
126
+ def delete_entry_from_forward_table_name(actor_type, actor_id, victim_type, victim_id)
127
+ row = Socialization.cassandra_session.execute("SELECT * FROM #{forward_table_name} WHERE actor_type='#{actor_type}' AND actor_id=#{actor_id} AND victim_type='#{victim_type}' AND victim_id=#{victim_id} ALLOW FILTERING").rows.first
128
+ Socialization.cassandra_session.execute("DELETE FROM #{forward_table_name} WHERE actor_type='#{actor_type}' AND actor_id=#{actor_id} AND created_at=#{row["created_at"]}") # if row
129
+ Socialization.cassandra_session.execute("UPDATE #{counter_forward_table_name} SET cnt = cnt - 1 WHERE actor_type = '#{actor_type}' AND actor_id = #{actor_id}") if counter_forward_table_name
130
+ end
131
+
132
+ def delete_entry_from_backward_table_name(actor_type, actor_id, victim_type, victim_id)
133
+ row = Socialization.cassandra_session.execute("SELECT * FROM #{backward_table_name} WHERE actor_type='#{actor_type}' AND actor_id=#{actor_id} AND victim_type='#{victim_type}' AND victim_id=#{victim_id} ALLOW FILTERING").rows.to_a.first
134
+ Socialization.cassandra_session.execute("DELETE FROM #{backward_table_name} WHERE victim_type='#{victim_type}' AND victim_id=#{victim_id} AND created_at=#{row["created_at"]}") if row
135
+ Socialization.cassandra_session.execute("UPDATE #{counter_forward_table_name} SET cnt = cnt - 1 WHERE actor_type = '#{actor_type}' AND actor_id = #{actor_id}") if counter_forward_table_name
136
+ end
137
+
138
+ def delete_entry(actor, victim, options={})
139
+ delete_entry_from_forward_table_name(actor.class, actor.id, victim.class, victim.id) if forward_table_name
140
+ delete_entry_from_backward_table_name(actor.class, actor.id, victim.class, victim.id) if backward_table_name
141
+ Socialization.cassandra_session.execute("UPDATE #{counter_forward_table_name} SET cnt = cnt - 1 WHERE actor_type = '#{actor.class}' AND actor_id = #{actor.id}") if counter_forward_table_name
142
+ Socialization.cassandra_session.execute("UPDATE #{counter_backward_table_name} SET cnt = cnt - 1 WHERE victim_type = '#{victim.class}' AND victim_id = #{victim.id}") if counter_backward_table_name
143
+ end
144
+
145
+ end # class << self
146
+
147
+ end # Base
148
+ end # CassandraStores
149
+ end # Socialization
@@ -0,0 +1,28 @@
1
+ module Socialization
2
+ module CassandraStores
3
+ class Comment< Socialization::CassandraStores::Base
4
+ extend Socialization::Stores::Mixins::Base
5
+ extend Socialization::Stores::Mixins::Like
6
+ extend Socialization::CassandraStores::Mixins::Base
7
+
8
+ class << self
9
+ def forward_table_name
10
+ nil
11
+ end
12
+ def backward_table_name
13
+ "comments"
14
+ end
15
+ def counter_forward_table_name
16
+ nil
17
+ end
18
+ def counter_backward_table_name
19
+ "comment_counter"
20
+ end
21
+ alias_method :comment!, :relation!; public :comment!
22
+ alias_method :remove_comments, :remove_actor_relations; public :remove_comments
23
+ alias_method :comments_cnt, :actors_cnt; public :comments_cnt
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ module Socialization
2
+ class << self
3
+ def cassandra
4
+ @cassandra
5
+ end
6
+
7
+ def cassandra=(cassandra)
8
+ @cassandra = cassandra
9
+ end
10
+
11
+ def keyspace
12
+ @cas_keyspace
13
+ end
14
+
15
+ def keyspace=(keyspace)
16
+ @cas_keyspace = keyspace
17
+ @cassandra_session = cassandra.connect(keyspace)
18
+ end
19
+
20
+ def cassandra_session
21
+ @cassandra_session ||= @cassandra.connect(@cas_keyspace)
22
+ rescue
23
+ @cassandra = Cassandra.cluster
24
+ @cas_keyspace = 'test'
25
+ @cassandra_session ||= @cassandra.connect(@cas_keyspace)
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,36 @@
1
+ module Socialization
2
+ module CassandraStores
3
+ class Follow < Socialization::CassandraStores::Base
4
+ extend Socialization::Stores::Mixins::Base
5
+ extend Socialization::Stores::Mixins::Follow
6
+ extend Socialization::CassandraStores::Mixins::Base
7
+
8
+ class << self
9
+ def forward_table_name
10
+ "followings"
11
+ end
12
+ def backward_table_name
13
+ "followers"
14
+ end
15
+ def counter_forward_table_name
16
+ "following_counter"
17
+ end
18
+ def counter_backward_table_name
19
+ "follower_counter"
20
+ end
21
+ alias_method :follow!, :relation!; public :follow!
22
+ alias_method :unfollow!, :unrelation!; public :unfollow!
23
+ alias_method :follows?, :relation?; public :follows?
24
+ alias_method :followers_relation, :actors_relation; public :followers_relation
25
+ alias_method :followers, :actors; public :followers
26
+ alias_method :followables_relation, :victims_relation; public :followables_relation
27
+ alias_method :followables, :victims; public :followables
28
+ alias_method :remove_followers, :remove_actor_relations; public :remove_followers
29
+ alias_method :remove_followables, :remove_victim_relations; public :remove_followables
30
+ alias_method :followers_cnt, :actors_cnt; public :followers_cnt
31
+ alias_method :following_cnt, :victims_cnt; public :following_cnt
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ module Socialization
2
+ module CassandraStores
3
+ class Like < Socialization::CassandraStores::Base
4
+ extend Socialization::Stores::Mixins::Base
5
+ extend Socialization::Stores::Mixins::Like
6
+ extend Socialization::CassandraStores::Mixins::Base
7
+
8
+ class << self
9
+ def forward_table_name
10
+ "likes"
11
+ end
12
+ def backward_table_name
13
+ "likers"
14
+ end
15
+ def counter_forward_table_name
16
+ nil
17
+ end
18
+ def counter_backward_table_name
19
+ "liker_counter"
20
+ end
21
+ alias_method :like!, :relation!; public :like!
22
+ alias_method :unlike!, :unrelation!; public :unlike!
23
+ alias_method :likes?, :relation?; public :likes?
24
+ alias_method :likers_relation, :actors_relation; public :likers_relation
25
+ alias_method :likers, :actors; public :likers
26
+ alias_method :likeables_relation, :victims_relation; public :likeables_relation
27
+ alias_method :likeables, :victims; public :likeables
28
+ alias_method :remove_likers, :remove_actor_relations; public :remove_likers
29
+ alias_method :remove_likeables, :remove_victim_relations; public :remove_likeables
30
+ alias_method :likers_cnt, :actors_cnt; public :likers_cnt
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,8 @@
1
+ module Socialization
2
+ module CassandraStores
3
+ module Mixins
4
+ module Base
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,28 @@
1
+ module Socialization
2
+ module CassandraStores
3
+ class Share < Socialization::CassandraStores::Base
4
+ extend Socialization::Stores::Mixins::Base
5
+ extend Socialization::Stores::Mixins::Like
6
+ extend Socialization::CassandraStores::Mixins::Base
7
+
8
+ class << self
9
+ def forward_table_name
10
+ nil
11
+ end
12
+ def backward_table_name
13
+ "shares"
14
+ end
15
+ def counter_forward_table_name
16
+ nil
17
+ end
18
+ def counter_backward_table_name
19
+ "share_counter"
20
+ end
21
+ alias_method :share!, :relation!; public :share!
22
+ alias_method :remove_shares, :remove_actor_relations; public :remove_shares
23
+ alias_method :shares_cnt, :actors_cnt; public :shares_cnt
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module Socialization
2
+ module Stores
3
+ module Mixins
4
+ module Base
5
+ def touch_dependents(actor, victim)
6
+ actor.touch if touch_actor?(actor)
7
+ victim.touch if touch_victim?(victim)
8
+ end
9
+
10
+ def touch_actor?(actor)
11
+ return false unless actor.respond_to?(:touch)
12
+ touch == :all || touch.to_s =~ /er$/i
13
+ end
14
+
15
+ def touch_victim?(victim)
16
+ return false unless victim.respond_to?(:touch)
17
+ touch == :all || touch.to_s =~ /able$/i
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ module Socialization
2
+ module Stores
3
+ module Mixins
4
+ module Follow
5
+
6
+ public
7
+ def touch(what = nil)
8
+ if what.nil?
9
+ @touch || false
10
+ else
11
+ raise Socialization::ArgumentError unless [:all, :follower, :followable, false, nil].include?(what)
12
+ @touch = what
13
+ end
14
+ end
15
+
16
+ def after_follow(method)
17
+ raise Socialization::ArgumentError unless method.is_a?(Symbol) || method.nil?
18
+ @after_create_hook = method
19
+ end
20
+
21
+ def after_unfollow(method)
22
+ raise Socialization::ArgumentError unless method.is_a?(Symbol) || method.nil?
23
+ @after_destroy_hook = method
24
+ end
25
+
26
+ protected
27
+ def call_after_create_hooks(follower, followable)
28
+ self.send(@after_create_hook, follower, followable) if @after_create_hook
29
+ touch_dependents(follower, followable)
30
+ end
31
+
32
+ def call_after_destroy_hooks(follower, followable)
33
+ self.send(@after_destroy_hook, follower, followable) if @after_destroy_hook
34
+ touch_dependents(follower, followable)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end