nkallen-cache-money 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/TODO CHANGED
@@ -1,14 +1,12 @@
1
1
  TOP PRIORITY
2
2
 
3
3
  REFACTOR
4
- * Reorganize transactional spec
5
4
  * Clarify terminology around cache/key/index, etc.
6
5
 
7
6
  INFRASTRUCTURE
8
7
 
9
8
  NEW FEATURES
10
9
  * transactional get multi isn't really multi
11
- * add on "not stored" should yield
12
10
 
13
11
  BUGS
14
12
  * Handle append strategy (using add rather than set?) to avoid race condition
@@ -38,7 +38,9 @@ module Cash
38
38
  end
39
39
 
40
40
  def add(key, value, options = {})
41
- repository.add(cache_key(key), value, options[:ttl] || 0, options[:raw])
41
+ if repository.add(cache_key(key), value, options[:ttl] || 0, options[:raw]) == "NOT_STORED\r\n"
42
+ yield
43
+ end
42
44
  end
43
45
 
44
46
  def set(key, value, options = {})
@@ -46,15 +48,15 @@ module Cash
46
48
  end
47
49
 
48
50
  def incr(key, delta = 1, ttl = 0)
49
- repository.incr(cache_key(key), delta) || begin
50
- repository.add(cache_key(key), (result = yield).to_s, ttl, true)
51
+ repository.incr(cache_key = cache_key(key), delta) || begin
52
+ repository.add(cache_key, (result = yield).to_s, ttl, true) { repository.incr(cache_key) }
51
53
  result
52
54
  end
53
55
  end
54
56
 
55
57
  def decr(key, delta = 1, ttl = 0)
56
- repository.decr(cache_key(key), delta) || begin
57
- repository.add(cache_key(key), (result = yield).to_s, ttl, true)
58
+ repository.decr(cache_key = cache_key(key), delta) || begin
59
+ repository.add(cache_key, (result = yield).to_s, ttl, true) { repository.decr(cache_key) }
58
60
  result
59
61
  end
60
62
  end
@@ -64,7 +66,7 @@ module Cash
64
66
  end
65
67
 
66
68
  def cache_key(key)
67
- "#{name}/#{key.to_s.gsub(' ', '+')}"
69
+ "#{name}:#{cache_config.version}/#{key.to_s.gsub(' ', '+')}"
68
70
  end
69
71
  end
70
72
 
@@ -72,7 +74,6 @@ module Cash
72
74
  def expire
73
75
  self.class.expire(id)
74
76
  end
75
- alias_method :expire_cache, :expire
76
77
  end
77
78
  end
78
79
  end
@@ -9,11 +9,10 @@ module Cash
9
9
 
10
10
  module ClassMethods
11
11
  def self.extended(a_class)
12
- a_class.class_eval do
13
- class << self
14
- delegate :repository, :indices, :to => :@cache_config
15
- alias_method_chain :inherited, :cache_config
16
- end
12
+ class << a_class
13
+ attr_reader :cache_config
14
+ delegate :repository, :indices, :to => :@cache_config
15
+ alias_method_chain :inherited, :cache_config
17
16
  end
18
17
  end
19
18
 
@@ -27,6 +26,10 @@ module Cash
27
26
  (@cache_config.indices.unshift(Index.new(@cache_config, self, attributes, options))).uniq!
28
27
  end
29
28
 
29
+ def version(number)
30
+ @cache_config.options[:version] = number
31
+ end
32
+
30
33
  def cache_config=(config)
31
34
  @cache_config = config
32
35
  end
@@ -52,6 +55,10 @@ module Cash
52
55
  @options[:ttl]
53
56
  end
54
57
 
58
+ def version
59
+ @options[:version] || 1
60
+ end
61
+
55
62
  def indices
56
63
  @indices ||= active_record == ActiveRecord::Base ? [] : [Index.new(self, active_record, active_record.primary_key)]
57
64
  end
@@ -8,17 +8,15 @@ module Cash
8
8
 
9
9
  module ClassMethods
10
10
  def self.extended(active_record_class)
11
- active_record_class.class_eval do
12
- class << self
13
- alias_method_chain :find_every, :cache
14
- alias_method_chain :find_from_ids, :cache
15
- alias_method_chain :calculate, :cache
16
- end
11
+ class << active_record_class
12
+ alias_method_chain :find_every, :cache
13
+ alias_method_chain :find_from_ids, :cache
14
+ alias_method_chain :calculate, :cache
17
15
  end
18
16
  end
19
17
 
20
18
  def without_cache(&block)
21
- User.with_scope(:find => {:readonly => true}, &block)
19
+ with_scope(:find => {:readonly => true}, &block)
22
20
  end
23
21
 
24
22
  # User.find(:first, ...), User.find_by_foo(...), User.find(:all, ...), User.find_all_by_foo(...)
@@ -22,8 +22,8 @@ module Cash
22
22
  describe 'when there is a total cache miss' do
23
23
  it 'yields the keys to the block' do
24
24
  Story.fetch(["yabba", "dabba"]) { |*missing_ids| ["doo", "doo"] }.should == {
25
- "Story/yabba" => "doo",
26
- "Story/dabba" => "doo"
25
+ "Story:1/yabba" => "doo",
26
+ "Story:1/dabba" => "doo"
27
27
  }
28
28
  end
29
29
  end
@@ -32,8 +32,8 @@ module Cash
32
32
  it 'yields just the missing ids to the block' do
33
33
  Story.set("yabba", "dabba")
34
34
  Story.fetch(["yabba", "dabba"]) { |*missing_ids| "doo" }.should == {
35
- "Story/yabba" => "dabba",
36
- "Story/dabba" => "doo"
35
+ "Story:1/yabba" => "dabba",
36
+ "Story:1/dabba" => "doo"
37
37
  }
38
38
  end
39
39
  end
@@ -102,6 +102,22 @@ module Cash
102
102
  end
103
103
  end
104
104
 
105
+ describe '#add' do
106
+ describe 'when the value already exists' do
107
+ it 'yields to the block' do
108
+ Story.set("count", 1)
109
+ Story.add("count", 1) { "yield me" }.should == "yield me"
110
+ end
111
+ end
112
+
113
+ describe 'when the value does not already exist' do
114
+ it 'adds the key to the cache' do
115
+ Story.add("count", 1)
116
+ Story.get("count").should == 1
117
+ end
118
+ end
119
+ end
120
+
105
121
  describe '#decr' do
106
122
  describe 'when there is a cache hit' do
107
123
  before do
@@ -129,5 +145,15 @@ module Cash
129
145
  end
130
146
  end
131
147
  end
148
+
149
+ describe '#cache_key' do
150
+ it 'uses the version number' do
151
+ Story.version 1
152
+ Story.cache_key("foo").should == "Story:1/foo"
153
+
154
+ Story.version 2
155
+ Story.cache_key("foo").should == "Story:2/foo"
156
+ end
157
+ end
132
158
  end
133
159
  end
@@ -294,6 +294,18 @@ module Cash
294
294
  end
295
295
  end
296
296
  end
297
+
298
+ describe '#without_cache' do
299
+ describe 'when finders are called within the provided block' do
300
+ it 'uses the database not the cache' do
301
+ story = Story.create!
302
+ mock(Story).get.never
303
+ Story.without_cache do
304
+ Story.find(story.id).should == story
305
+ end
306
+ end
307
+ end
308
+ end
297
309
  end
298
310
 
299
311
  describe 'when the cache is not populated' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nkallen-cache-money
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Kallen
@@ -17,7 +17,7 @@ dependencies:
17
17
  version_requirement:
18
18
  version_requirements: !ruby/object:Gem::Requirement
19
19
  requirements:
20
- - - ">"
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
22
  version: 2.2.0
23
23
  version:
@@ -26,10 +26,19 @@ dependencies:
26
26
  version_requirement:
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
- - - ">"
29
+ - - ">="
30
30
  - !ruby/object:Gem::Version
31
31
  version: 2.2.0
32
32
  version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: memcache-client
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.5.0
41
+ version:
33
42
  description: Cache utilities.
34
43
  email: nick@twitter.com
35
44
  executables: []