generation_cacheable 1.0.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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +2 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/ChangeLog +2 -0
  7. data/Gemfile +16 -0
  8. data/README.md +33 -0
  9. data/Rakefile +8 -0
  10. data/generation_cacheable.gemspec +23 -0
  11. data/lib/gen_cache.rb +32 -0
  12. data/lib/gen_cache/cache_io/fetching.rb +78 -0
  13. data/lib/gen_cache/cache_io/formatting.rb +75 -0
  14. data/lib/gen_cache/cache_io/parsing.rb +66 -0
  15. data/lib/gen_cache/cache_types/association_cache.rb +50 -0
  16. data/lib/gen_cache/cache_types/attribute_cache.rb +30 -0
  17. data/lib/gen_cache/cache_types/class_method_cache.rb +23 -0
  18. data/lib/gen_cache/cache_types/key_cache.rb +14 -0
  19. data/lib/gen_cache/cache_types/method_cache.rb +28 -0
  20. data/lib/gen_cache/caches.rb +15 -0
  21. data/lib/gen_cache/expiry.rb +37 -0
  22. data/lib/gen_cache/keys.rb +70 -0
  23. data/lib/gen_cache/version.rb +3 -0
  24. data/spec/gen_cache/cache_io/fetching_spec.rb +41 -0
  25. data/spec/gen_cache/cache_io/formatting_spec.rb +59 -0
  26. data/spec/gen_cache/cache_io/parsing_spec.rb +47 -0
  27. data/spec/gen_cache/cache_types/association_cache_spec.rb +313 -0
  28. data/spec/gen_cache/cache_types/attribute_cache_spec.rb +98 -0
  29. data/spec/gen_cache/cache_types/class_method_cache_spec.rb +72 -0
  30. data/spec/gen_cache/cache_types/key_cache_spec.rb +34 -0
  31. data/spec/gen_cache/cache_types/method_cache_spec.rb +108 -0
  32. data/spec/gen_cache/expiry_spec.rb +182 -0
  33. data/spec/gen_cache/keys_spec.rb +66 -0
  34. data/spec/gen_cache_spec.rb +76 -0
  35. data/spec/models/account.rb +7 -0
  36. data/spec/models/comment.rb +9 -0
  37. data/spec/models/descendant.rb +20 -0
  38. data/spec/models/group.rb +6 -0
  39. data/spec/models/image.rb +11 -0
  40. data/spec/models/location.rb +3 -0
  41. data/spec/models/post.rb +31 -0
  42. data/spec/models/tag.rb +6 -0
  43. data/spec/models/user.rb +54 -0
  44. data/spec/spec_helper.rb +96 -0
  45. metadata +149 -0
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe GenCache do
4
+ let(:cache) { Rails.cache }
5
+ let(:user) { User.create(:login => 'flyerhzm') }
6
+
7
+ context "methods" do
8
+
9
+ it "should generate a model prefix" do
10
+ schema_string = User.columns.sort_by(&:name).map { |c| "#{c.name}:#{c.type}"}.join(",")
11
+ schema_hash = CityHash.hash64(schema_string)
12
+ prefix = GenCache.model_prefix(User)
13
+ prefix.should == "users/#{schema_hash}"
14
+ end
15
+
16
+ it "should generate an instance prefix" do
17
+ attribute_string = user.attributes.sort.map { |k,v| [k,v].join(":")}.join(",")
18
+ attribute_hash = CityHash.hash64(attribute_string)
19
+ prefix = GenCache.instance_prefix(user)
20
+ prefix.should == GenCache.model_prefix(User) + "/#{user.id.to_s}/#{attribute_hash}"
21
+ end
22
+
23
+ it "should generate an instance key" do
24
+ expected_key = {type: :object, key: GenCache.model_prefix(User) + "/#{user.id.to_s}"}
25
+ GenCache.instance_key(User, user.id).should == expected_key
26
+ end
27
+
28
+ it "should generate an attribute key" do
29
+ expected_key = {type: :object, key: GenCache.model_prefix(User) + '/login/pathouse'}
30
+ att_key = GenCache.attribute_key(User, :login, ['pathouse'])
31
+ att_key.should == expected_key
32
+ end
33
+
34
+ it "should generate an all w/ attribute key" do
35
+ expected_key = {type: :object, key: GenCache.model_prefix(User) + "/all/login/pathouse"}
36
+ att_key = GenCache.attribute_key(User, :login, ['pathouse'], all: true)
37
+ att_key.should == expected_key
38
+ end
39
+
40
+ it "should generate a class method key" do
41
+ expected_key = {type: :method, key: GenCache.model_prefix(User) + "/default_name"}
42
+ cmethod_key = GenCache.class_method_key(User, :default_name)
43
+ cmethod_key.should == expected_key
44
+ end
45
+
46
+ it "should return all class method keys" do
47
+ all_cmethod_keys = GenCache.all_class_method_keys(User)
48
+ comparison = User.cached_class_methods.map do |cmeth|
49
+ GenCache.class_method_key(User, cmeth)
50
+ end
51
+ all_cmethod_keys.should == comparison
52
+ end
53
+
54
+ it "should generate a method key" do
55
+ expected_key = {type: :method, key: GenCache.instance_prefix(user) + "/last_post"}
56
+ method_key = GenCache.method_key(user, :last_post)
57
+ method_key.should == expected_key
58
+ end
59
+
60
+ it "should generate an association key" do
61
+ expected_key = {type: :association, key: GenCache.instance_prefix(user) + "/posts"}
62
+ assoc_key = GenCache.association_key(user, :posts)
63
+ assoc_key.should == expected_key
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cacheable do
4
+ let(:cache) { Rails.cache }
5
+ let(:user) { User.create(:login => 'flyerhzm') }
6
+
7
+ before :all do
8
+ @group1 = Group.create(name: "Ruby On Rails")
9
+ @account = user.create_account(group: @group1)
10
+ @post1 = user.posts.create(:title => 'post1')
11
+ @image1 = @post1.images.create
12
+ @comment1 = @post1.comments.create
13
+ @tag1 = @post1.tags.create(title: "Rails")
14
+ end
15
+
16
+ before :each do
17
+ cache.clear
18
+ user.reload
19
+ end
20
+
21
+ context "Association Expires on Save" do
22
+ it "should delete has_many with_association cache" do
23
+ user.cached_posts
24
+ key = Cacheable.association_key(user, :posts)
25
+ Rails.cache.read(key[:key]).should_not be_nil
26
+ @post1.update_attribute(:title, "Blarg")
27
+ old_key = Rails.cache.read(key[:key]).first
28
+ Rails.cache.read(old_key[:key]).should be_nil
29
+ end
30
+
31
+ it "should delete has_many with polymorphic with_association cache" do
32
+ @post1.cached_comments
33
+ key = Cacheable.association_key(@post1, :comments)
34
+ Rails.cache.read(key[:key]).should_not be_nil
35
+ @comment1.update_attribute(:commentable_type, "fart")
36
+ old_key = Rails.cache.read(key[:key]).first
37
+ Rails.cache.read(old_key[:key]).should be_nil
38
+ end
39
+
40
+ it "should delete has_many through with_association cache" do
41
+ user.cached_images
42
+ key = Cacheable.association_key(user, :images)
43
+ Rails.cache.read(key[:key]).should_not be_nil
44
+ @image1.update_attribute(:viewable_type, "Gralb")
45
+ old_key = Rails.cache.read(key[:key]).first
46
+ Rails.cache.read(old_key[:key]).should be_nil
47
+ end
48
+
49
+ it "should delete has_one with_association cache" do
50
+ user.cached_account
51
+ key = Cacheable.association_key(user, :account)
52
+ Rails.cache.read(key[:key]).should_not be_nil
53
+ @account.update_attribute(:group_id, 7)
54
+ old_key = Rails.cache.read(key[:key]).first
55
+ Rails.cache.read(old_key[:key]).should be_nil
56
+ end
57
+
58
+ it "should delete has_and_belongs_to_many with_association cache" do
59
+ @post1.cached_tags
60
+ key = Cacheable.association_key(@post1, :tags)
61
+ Rails.cache.read(key[:key]).should_not be_nil
62
+ old_key = Rails.cache.read(key[:key]).first
63
+ @tag1.update_attribute(:title, "new title")
64
+ Rails.cache.read(old_key[:key]).should be_nil
65
+ end
66
+
67
+ it "should delete has_one through belongs_to with_association cache" do
68
+ @account.update_attribute(:group_id, 1)
69
+ @group1.update_attribute(:name, "Poop Group")
70
+ key = Cacheable.association_key(user, :group)
71
+ Rails.cache.read(key[:key]).should be_nil
72
+ user.cached_group.should == @group1
73
+ Rails.cache.read(key[:key]).should == [Cacheable.instance_key(Group, @group1.id)]
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,7 @@
1
+ class Account < ActiveRecord::Base
2
+ include Cacheable
3
+
4
+ belongs_to :user
5
+
6
+ belongs_to :group
7
+ end
@@ -0,0 +1,9 @@
1
+ class Comment < ActiveRecord::Base
2
+ include Cacheable
3
+
4
+ belongs_to :commentable, :polymorphic => true
5
+
6
+ model_cache do
7
+ with_association :commentable
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ class Descendant < User
2
+
3
+ belongs_to :location
4
+
5
+ model_cache do
6
+ with_attribute :email
7
+ with_method :name
8
+ with_association :location
9
+ with_class_method :default_name
10
+ end
11
+
12
+ def name
13
+ "ScotterC"
14
+ end
15
+
16
+ def self.default_name
17
+ "ScotterC"
18
+ end
19
+
20
+ end
@@ -0,0 +1,6 @@
1
+ class Group < ActiveRecord::Base
2
+
3
+ has_many :accounts
4
+
5
+ has_many :images, as: :viewable
6
+ end
@@ -0,0 +1,11 @@
1
+ class Image < ActiveRecord::Base
2
+ include Cacheable
3
+
4
+ belongs_to :viewable, :polymorphic => true
5
+
6
+ after_commit :do_something
7
+
8
+ def do_something
9
+ e = 1337
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ class Location < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,31 @@
1
+ class Post < ActiveRecord::Base
2
+ include Cacheable
3
+
4
+ belongs_to :location
5
+ belongs_to :user
6
+
7
+ has_many :comments, :as => :commentable
8
+ has_many :images, :as => :viewable
9
+
10
+ has_and_belongs_to_many :tags
11
+
12
+ model_cache do
13
+ with_key
14
+ with_attribute :user_id
15
+ with_association :user, :comments, :images, :tags
16
+ with_class_method :default_post, :retrieve_with_user_id, :retrieve_with_both
17
+ end
18
+
19
+ def self.default_post
20
+ Post.first
21
+ end
22
+
23
+ def self.retrieve_with_user_id(user_id)
24
+ Post.find_by_user_id(user_id)
25
+ end
26
+
27
+ def self.retrieve_with_both(user_id, post_id)
28
+ Post.find(post_id) == Post.find_by_user_id(user_id)
29
+ end
30
+
31
+ end
@@ -0,0 +1,6 @@
1
+ class Tag < ActiveRecord::Base
2
+ include Cacheable
3
+
4
+ has_and_belongs_to_many :posts
5
+
6
+ end
@@ -0,0 +1,54 @@
1
+ class User < ActiveRecord::Base
2
+ include Cacheable
3
+
4
+ has_many :posts
5
+ has_one :account
6
+ has_many :images, through: :posts
7
+
8
+ has_one :group, through: :account
9
+
10
+ model_cache do
11
+ with_key
12
+ with_attribute :login
13
+ with_method :last_post, :bad_iv_name!, :bad_iv_name?
14
+ with_association :posts, :account, :images, :group
15
+ with_class_method :default_name, :user_with_id, :user_with_email,
16
+ :users_with_ids, :users_with_ids_in, :user_with_attributes
17
+ end
18
+
19
+ def last_post
20
+ posts.last
21
+ end
22
+
23
+ def self.default_name
24
+ "flyerhzm"
25
+ end
26
+
27
+ def bad_iv_name!
28
+ 42
29
+ end
30
+
31
+ def bad_iv_name?
32
+ 44
33
+ end
34
+
35
+ # accepts a number
36
+ def self.user_with_id(id)
37
+ User.find(id)
38
+ end
39
+
40
+ # accepts a string
41
+ def self.user_with_email(email)
42
+ User.find_by_email(email)
43
+ end
44
+
45
+ # accepts an array
46
+ def self.users_with_ids(ids)
47
+ User.find(ids)
48
+ end
49
+
50
+ # accepts a range
51
+ def self.users_with_ids_in(range)
52
+ User.select { |u| range.include?(u.id) }
53
+ end
54
+ end
@@ -0,0 +1,96 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+
4
+ require 'rails'
5
+ require 'active_record'
6
+ require 'rspec'
7
+ require 'mocha/api'
8
+ require 'memcached'
9
+ require 'cacheable'
10
+
11
+ # It needs this order otherwise cacheable throws
12
+ # errors when looking for reflection classes
13
+ # Specifically, post can't be before tag
14
+ # and user can't be before post
15
+ require 'models/location'
16
+ require 'models/account'
17
+ require 'models/group'
18
+ require 'models/comment'
19
+ require 'models/image'
20
+ require 'models/tag'
21
+ require 'models/post'
22
+ require 'models/user'
23
+ require 'models/descendant'
24
+
25
+ ActiveRecord::Migration.verbose = false
26
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
27
+
28
+ module Rails
29
+ class <<self
30
+ def cache
31
+ @cache ||= Memcached::Rails.new
32
+ end
33
+ end
34
+ end
35
+
36
+ RSpec.configure do |config|
37
+ config.mock_with :mocha
38
+
39
+ config.filter_run focus: true
40
+ config.run_all_when_everything_filtered = true
41
+
42
+ config.before :all do
43
+ ::ActiveRecord::Schema.define(:version => 1) do
44
+ create_table :users do |t|
45
+ t.string :login
46
+ t.string :email
47
+ end
48
+
49
+ create_table :accounts do |t|
50
+ t.integer :user_id
51
+ t.integer :group_id
52
+ end
53
+
54
+ create_table :posts do |t|
55
+ t.integer :user_id
56
+ t.string :title
57
+ t.integer :location_id
58
+ end
59
+
60
+ create_table :comments do |t|
61
+ t.integer :commentable_id
62
+ t.string :commentable_type
63
+ end
64
+
65
+ create_table :images do |t|
66
+ t.integer :viewable_id
67
+ t.string :viewable_type
68
+ t.string :name
69
+ end
70
+
71
+ create_table :tags do |t|
72
+ t.string :title
73
+ end
74
+
75
+ create_table :posts_tags, id: false do |t|
76
+ t.integer :post_id
77
+ t.integer :tag_id
78
+ end
79
+
80
+ create_table :groups do |t|
81
+ t.string :name
82
+ end
83
+
84
+ create_table :locations do |t|
85
+ t.string :city
86
+ end
87
+ end
88
+
89
+ end
90
+
91
+ config.after :all do
92
+ ::ActiveRecord::Base.connection.tables.each do |table|
93
+ ::ActiveRecord::Base.connection.drop_table(table)
94
+ end
95
+ end
96
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: generation_cacheable
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Pat McGee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: '2.8'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: '2.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mocha
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.10.5
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.10.5
55
+ description: a simple cache implementation with attribute based expiry
56
+ email:
57
+ - patmcgee331@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - .ruby-gemset
65
+ - .ruby-version
66
+ - ChangeLog
67
+ - Gemfile
68
+ - README.md
69
+ - Rakefile
70
+ - generation_cacheable.gemspec
71
+ - lib/gen_cache.rb
72
+ - lib/gen_cache/cache_io/fetching.rb
73
+ - lib/gen_cache/cache_io/formatting.rb
74
+ - lib/gen_cache/cache_io/parsing.rb
75
+ - lib/gen_cache/cache_types/association_cache.rb
76
+ - lib/gen_cache/cache_types/attribute_cache.rb
77
+ - lib/gen_cache/cache_types/class_method_cache.rb
78
+ - lib/gen_cache/cache_types/key_cache.rb
79
+ - lib/gen_cache/cache_types/method_cache.rb
80
+ - lib/gen_cache/caches.rb
81
+ - lib/gen_cache/expiry.rb
82
+ - lib/gen_cache/keys.rb
83
+ - lib/gen_cache/version.rb
84
+ - spec/gen_cache/cache_io/fetching_spec.rb
85
+ - spec/gen_cache/cache_io/formatting_spec.rb
86
+ - spec/gen_cache/cache_io/parsing_spec.rb
87
+ - spec/gen_cache/cache_types/association_cache_spec.rb
88
+ - spec/gen_cache/cache_types/attribute_cache_spec.rb
89
+ - spec/gen_cache/cache_types/class_method_cache_spec.rb
90
+ - spec/gen_cache/cache_types/key_cache_spec.rb
91
+ - spec/gen_cache/cache_types/method_cache_spec.rb
92
+ - spec/gen_cache/expiry_spec.rb
93
+ - spec/gen_cache/keys_spec.rb
94
+ - spec/gen_cache_spec.rb
95
+ - spec/models/account.rb
96
+ - spec/models/comment.rb
97
+ - spec/models/descendant.rb
98
+ - spec/models/group.rb
99
+ - spec/models/image.rb
100
+ - spec/models/location.rb
101
+ - spec/models/post.rb
102
+ - spec/models/tag.rb
103
+ - spec/models/user.rb
104
+ - spec/spec_helper.rb
105
+ homepage: https://github.com/pathouse/generation-cacheable
106
+ licenses: []
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.0.3
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: a simple cache implementation with attribute based expiry
128
+ test_files:
129
+ - spec/gen_cache/cache_io/fetching_spec.rb
130
+ - spec/gen_cache/cache_io/formatting_spec.rb
131
+ - spec/gen_cache/cache_io/parsing_spec.rb
132
+ - spec/gen_cache/cache_types/association_cache_spec.rb
133
+ - spec/gen_cache/cache_types/attribute_cache_spec.rb
134
+ - spec/gen_cache/cache_types/class_method_cache_spec.rb
135
+ - spec/gen_cache/cache_types/key_cache_spec.rb
136
+ - spec/gen_cache/cache_types/method_cache_spec.rb
137
+ - spec/gen_cache/expiry_spec.rb
138
+ - spec/gen_cache/keys_spec.rb
139
+ - spec/gen_cache_spec.rb
140
+ - spec/models/account.rb
141
+ - spec/models/comment.rb
142
+ - spec/models/descendant.rb
143
+ - spec/models/group.rb
144
+ - spec/models/image.rb
145
+ - spec/models/location.rb
146
+ - spec/models/post.rb
147
+ - spec/models/tag.rb
148
+ - spec/models/user.rb
149
+ - spec/spec_helper.rb