ultracache 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.gitignore +2 -0
  2. data/.rvmrc +71 -0
  3. data/Gemfile +3 -0
  4. data/Gemfile.lock +55 -0
  5. data/README.md +130 -0
  6. data/Rakefile +20 -0
  7. data/lib/ultracache.rb +29 -0
  8. data/lib/ultracache/cached.rb +102 -0
  9. data/lib/ultracache/configurations.rb +79 -0
  10. data/lib/ultracache/macro.rb +40 -0
  11. data/lib/ultracache/models/mongoid_extension.rb +9 -0
  12. data/lib/ultracache/railtie.rb +16 -0
  13. data/lib/ultracache/relationship.rb +24 -0
  14. data/lib/ultracache/relationship/belongs_as_cached_queue.rb +96 -0
  15. data/lib/ultracache/relationship/has_cached_attribute.rb +51 -0
  16. data/lib/ultracache/relationship/has_cached_queue.rb +31 -0
  17. data/lib/ultracache/relationships.rb +41 -0
  18. data/lib/ultracache/serializer/base.rb +19 -0
  19. data/lib/ultracache/serializer/json_serializer.rb +15 -0
  20. data/lib/ultracache/storage/redis.rb +63 -0
  21. data/lib/ultracache/version.rb +3 -0
  22. data/spec/models/admin.rb +13 -0
  23. data/spec/models/customer.rb +7 -0
  24. data/spec/models/order.rb +11 -0
  25. data/spec/models/person.rb +15 -0
  26. data/spec/models/post.rb +9 -0
  27. data/spec/spec_helper.rb +15 -0
  28. data/spec/unit/cached_spec.rb +51 -0
  29. data/spec/unit/configurations_spec.rb +49 -0
  30. data/spec/unit/relationship/belongs_as_cached_queue_spec.rb +18 -0
  31. data/spec/unit/relationship/has_cached_attribute_spec.rb +20 -0
  32. data/spec/unit/relationship/has_cached_queue_spec.rb +20 -0
  33. data/spec/unit/relationship_spec.rb +12 -0
  34. data/spec/unit/relationships_spec.rb +72 -0
  35. data/spec/unit/serializer/json_serializer_spec.rb +24 -0
  36. data/ultracache.gemspec +30 -0
  37. metadata +184 -0
@@ -0,0 +1,11 @@
1
+ class Order
2
+ include Mongoid::Document
3
+ include Ultracache::Cached
4
+
5
+ field :name
6
+
7
+ belongs_to :customer
8
+ cached_queue_in :customer, :as => :cached_orders do |obj|
9
+ obj.to_json
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ class Person
2
+ include Ultracache::Cached
3
+
4
+ has_cached_attribute :cached_name do |person|
5
+ person.name
6
+ end
7
+
8
+ def id
9
+ "1"
10
+ end
11
+
12
+ def name
13
+ 'person'
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ class Post
2
+ include Ultracache::Cached
3
+
4
+ attr_accessor :person_id
5
+
6
+ def id
7
+ "1"
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
3
+
4
+ MODELS = File.join(File.dirname(__FILE__), "models")
5
+ $LOAD_PATH.unshift(MODELS)
6
+
7
+ require "mongoid"
8
+ require "ultracache"
9
+ require "rspec"
10
+
11
+ Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require File.basename(file) }
12
+
13
+ def to_proc(&block)
14
+ block
15
+ end
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+
3
+ describe Ultracache::Cached do
4
+ before do
5
+ Ultracache::Configurations.storage = Ultracache::Storage::Redis.new(:urls => ['localhost:6379'])
6
+ end
7
+
8
+ context "without model hierarchy" do
9
+ let(:post) { Post.new }
10
+
11
+ it "should have a relationships object" do
12
+ Post.relationships.should_not == nil
13
+ end
14
+ end
15
+
16
+ context "with model hierarchy" do
17
+ let(:person) { Person.new }
18
+ let(:admin) { Admin.new }
19
+
20
+ context "for parent models" do
21
+ it "has defined relationships" do
22
+ expect{person.cached_name}.to_not raise_error(NoMethodError)
23
+ end
24
+
25
+ it "should not have relationships declared in child class" do
26
+ expect{person.cached_permissions}.to raise_error(NoMethodError)
27
+ end
28
+
29
+ it "has relationships only in its scope" do
30
+ Person.relationships.keys.should == [:cached_name]
31
+ end
32
+ end
33
+
34
+ context "for child models" do
35
+ it "has relationships different to parent class" do
36
+ Admin.relationships.object_id.should_not == Person.relationships.object_id
37
+ end
38
+ it "has defined relationships" do
39
+ expect{admin.cached_permissions}.to_not raise_error(NoMethodError)
40
+ end
41
+
42
+ it "has relationships declared in parent class" do
43
+ expect{admin.cached_name}.to_not raise_error(NoMethodError)
44
+ end
45
+
46
+ it "has relationships only in its scope" do
47
+ Admin.relationships.keys.map(&:to_s).sort.should == [:cached_name, :cached_permissions].map(&:to_s).sort
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,49 @@
1
+ require "spec_helper"
2
+
3
+ describe Ultracache::Configurations do
4
+ let(:config) do
5
+ Ultracache::Configurations
6
+ end
7
+
8
+ let(:redis_storage) do
9
+ Ultracache::Storage::Redis.new(:urls => ['localhost:6379'])
10
+ end
11
+
12
+ let(:json_serializer) do
13
+ Ultracache::Serializer::JsonSerializer.new
14
+ end
15
+
16
+ it "cannot be initialized" do
17
+ Ultracache::Configurations.new.should raise_error(NoMethodError)
18
+ end
19
+
20
+ describe "#storage=" do
21
+ it "sets storage object for ultracache" do
22
+ config.storage = redis_storage
23
+
24
+ Ultracache::Configurations.storage.should == redis_storage
25
+ end
26
+ end
27
+
28
+ describe "#serializer=" do
29
+ it "sets serializer object for ultracache" do
30
+ config.serializer = json_serializer
31
+
32
+ Ultracache::Configurations.serializer.should == json_serializer
33
+ end
34
+ end
35
+
36
+ describe "#add_relationships" do
37
+ it "adds relationships object for the specified class" do
38
+ config.add_relationships(Post)
39
+ container = config.send :relationships_container
40
+ container[Post].relationships.should == {}
41
+ end
42
+ end
43
+
44
+ describe "#find_relationships" do
45
+ it "finds relationships object associated with the specified class" do
46
+ config.find_relationships(Post).relationships.should == {}
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ describe Ultracache::BelongsAsCachedQueue do
4
+ let(:belongs_as_cached_queue) do
5
+ Ultracache::BelongsAsCachedQueue.new :cached_posts,
6
+ :self_class => Post, :associated_class => Person do |p|
7
+ p.to_json
8
+ end
9
+ end
10
+
11
+ describe "#key" do
12
+ it "has form of [parent_class]:[id]:[name]" do
13
+ p = Post.new
14
+ p.person_id = 1
15
+ belongs_as_cached_queue.key(p).should == "person:1:cached_posts"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ describe Ultracache::HasCachedAttribute do
4
+ let(:person_attribute_block) do
5
+ to_proc do |obj|
6
+ obj.name
7
+ end
8
+ end
9
+
10
+ let(:cached_attribute) do
11
+ Ultracache::HasCachedAttribute.new :cached_name,
12
+ :self_class => Person, :serializer_block => person_attribute_block
13
+ end
14
+
15
+ describe "#key" do
16
+ it "has proper form" do
17
+ cached_attribute.key(Person.new).should == "person:1:cached_name"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ describe Ultracache::HasCachedQueue do
4
+ let(:object_block) do
5
+ to_proc do |obj|
6
+ obj.to_json
7
+ end
8
+ end
9
+
10
+ let(:has_cached_queue) do
11
+ Ultracache::HasCachedQueue.new :cached_objects,
12
+ :self_class => 'Person', :serializer_block => object_block
13
+ end
14
+
15
+ describe "#key" do
16
+ it "has form of [class]:[id]:[name]" do
17
+ has_cached_queue.key(Person.new).should == "person:1:cached_objects"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe Ultracache::Relationship do
4
+ it "is initialized with name and options" do
5
+ relationship = Ultracache::Relationship.new :my,
6
+ :self_class => 'Person', :associated_class => 'Admin'
7
+
8
+ relationship.name.should == :my
9
+ relationship.self_class.should == Person
10
+ relationship.associated_class.should == Admin
11
+ end
12
+ end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+
3
+ describe Ultracache::Relationships do
4
+ let(:relationship_1) { Ultracache::Relationship.new(:attr_1) }
5
+ let(:relationship_2) { Ultracache::Relationship.new(:attr_2) }
6
+ let(:relationships) { Ultracache::Relationships.new(Person) }
7
+
8
+ let(:relationships_admin) { Ultracache::Relationships.new(Admin) }
9
+ let(:relationship_3) { Ultracache::Relationship.new(:attr_3) }
10
+
11
+ it "is initialized with class" do
12
+ rs = Ultracache::Relationships.new(Person)
13
+ rs.klass.should == Person
14
+ end
15
+
16
+ it "is initialized with optional hash" do
17
+ rs = Ultracache::Relationships.new(Person, :attr_1 => relationship_1)
18
+ rs.relationships.should == { :attr_1 => relationship_1 }
19
+ end
20
+
21
+ describe "#add" do
22
+ it "adds relationship objects to self" do
23
+ relationships.add(relationship_1)
24
+ relationships.relationships.should == { :attr_1 => relationship_1 }
25
+ end
26
+ end
27
+
28
+ describe "#keys" do
29
+ it "returns all key values contained in the relationships object" do
30
+ relationships.add(relationship_1)
31
+ relationships.add(relationship_2)
32
+
33
+ relationships.keys.map(&:to_s).sort.should == [:attr_1, :attr_2].map(&:to_s).sort
34
+ end
35
+ end
36
+
37
+ describe "#find" do
38
+ it "finds desired relationship" do
39
+ relationships.add(relationship_1)
40
+ relationships.add(relationship_2)
41
+
42
+ relationships.find(:attr_1).should == relationship_1
43
+ end
44
+ end
45
+
46
+ describe "#merge" do
47
+ before(:each) do
48
+ relationships.add(relationship_1)
49
+ relationships.add(relationship_2)
50
+ relationships_admin.add(relationship_3)
51
+ end
52
+
53
+ it "concatenates two relationships" do
54
+ rs = relationships.merge(relationships_admin)
55
+
56
+ rs.relationships.should == {
57
+ :attr_1 => relationship_1,
58
+ :attr_2 => relationship_2,
59
+ :attr_3 => relationship_3
60
+ }
61
+ end
62
+
63
+ it "makes merged relationships to have child class as its label" do
64
+ rs_1 = relationships.merge(relationships_admin)
65
+ rs_1.klass.should == Admin
66
+
67
+ rs_2 = relationships_admin.merge(relationships)
68
+ rs_2.klass.should == Admin
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ultracache::Serializer::JsonSerializer do
4
+ let(:serializer) { Ultracache::Serializer::JsonSerializer.new }
5
+ let(:obj) { Person.new }
6
+
7
+ describe "#serialize" do
8
+ it "serializes object to JSON" do
9
+ serialized_str = serializer.serialize(obj) do
10
+ { :id => obj.id }
11
+ end
12
+
13
+ serialized_str.should == "{\"id\":\"1\"}"
14
+ end
15
+ end
16
+
17
+ describe "#deserialize" do
18
+ it "deserializes JSON into object hash" do
19
+ obj_hash = serializer.deserialize("{\"id\":1}")
20
+
21
+ obj_hash["id"].should == 1
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require "ultracache/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ultracache"
7
+ s.version = Ultracache::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Inbeom Hwang"]
10
+ s.email = ["inbeom@wafflestudio.com"]
11
+ s.homepage = "http://github.com/inbeom/ultracache"
12
+ s.summary = "Redis based cache for ActiveModel"
13
+ s.description = "Ultracache reduces computational costs occur from dynamic attributes by caching them into Redis"
14
+
15
+ s.add_dependency("activemodel", ["~> 3.0"])
16
+ s.add_dependency("activesupport", ["~> 3.0"])
17
+ s.add_dependency("redis", ["~> 2.2"])
18
+ s.add_dependency("json")
19
+
20
+ s.add_development_dependency("rspec", ["~> 2.6"])
21
+ s.add_development_dependency("mocha")
22
+ s.add_development_dependency("bson_ext")
23
+ s.add_development_dependency("mongoid")
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ["lib"]
29
+ end
30
+
metadata ADDED
@@ -0,0 +1,184 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ultracache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Inbeom Hwang
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemodel
16
+ requirement: &70152863679380 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70152863679380
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70152863677340 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70152863677340
36
+ - !ruby/object:Gem::Dependency
37
+ name: redis
38
+ requirement: &70152863675180 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '2.2'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70152863675180
47
+ - !ruby/object:Gem::Dependency
48
+ name: json
49
+ requirement: &70152863673460 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70152863673460
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70152863669820 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '2.6'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70152863669820
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: &70152863666360 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70152863666360
80
+ - !ruby/object:Gem::Dependency
81
+ name: bson_ext
82
+ requirement: &70152863663540 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70152863663540
91
+ - !ruby/object:Gem::Dependency
92
+ name: mongoid
93
+ requirement: &70152863657880 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70152863657880
102
+ description: Ultracache reduces computational costs occur from dynamic attributes
103
+ by caching them into Redis
104
+ email:
105
+ - inbeom@wafflestudio.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - .gitignore
111
+ - .rvmrc
112
+ - Gemfile
113
+ - Gemfile.lock
114
+ - README.md
115
+ - Rakefile
116
+ - lib/ultracache.rb
117
+ - lib/ultracache/cached.rb
118
+ - lib/ultracache/configurations.rb
119
+ - lib/ultracache/macro.rb
120
+ - lib/ultracache/models/mongoid_extension.rb
121
+ - lib/ultracache/railtie.rb
122
+ - lib/ultracache/relationship.rb
123
+ - lib/ultracache/relationship/belongs_as_cached_queue.rb
124
+ - lib/ultracache/relationship/has_cached_attribute.rb
125
+ - lib/ultracache/relationship/has_cached_queue.rb
126
+ - lib/ultracache/relationships.rb
127
+ - lib/ultracache/serializer/base.rb
128
+ - lib/ultracache/serializer/json_serializer.rb
129
+ - lib/ultracache/storage/redis.rb
130
+ - lib/ultracache/version.rb
131
+ - spec/models/admin.rb
132
+ - spec/models/customer.rb
133
+ - spec/models/order.rb
134
+ - spec/models/person.rb
135
+ - spec/models/post.rb
136
+ - spec/spec_helper.rb
137
+ - spec/unit/cached_spec.rb
138
+ - spec/unit/configurations_spec.rb
139
+ - spec/unit/relationship/belongs_as_cached_queue_spec.rb
140
+ - spec/unit/relationship/has_cached_attribute_spec.rb
141
+ - spec/unit/relationship/has_cached_queue_spec.rb
142
+ - spec/unit/relationship_spec.rb
143
+ - spec/unit/relationships_spec.rb
144
+ - spec/unit/serializer/json_serializer_spec.rb
145
+ - ultracache.gemspec
146
+ homepage: http://github.com/inbeom/ultracache
147
+ licenses: []
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 1.8.10
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: Redis based cache for ActiveModel
170
+ test_files:
171
+ - spec/models/admin.rb
172
+ - spec/models/customer.rb
173
+ - spec/models/order.rb
174
+ - spec/models/person.rb
175
+ - spec/models/post.rb
176
+ - spec/spec_helper.rb
177
+ - spec/unit/cached_spec.rb
178
+ - spec/unit/configurations_spec.rb
179
+ - spec/unit/relationship/belongs_as_cached_queue_spec.rb
180
+ - spec/unit/relationship/has_cached_attribute_spec.rb
181
+ - spec/unit/relationship/has_cached_queue_spec.rb
182
+ - spec/unit/relationship_spec.rb
183
+ - spec/unit/relationships_spec.rb
184
+ - spec/unit/serializer/json_serializer_spec.rb