nkallen-cache-money 0.2.4 → 0.2.5

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/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: []