cache_back 0.3.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.4
1
+ 0.4.1
@@ -8,6 +8,27 @@ module CacheBack
8
8
  @local_cache[args[0]] ||= Rails.cache.read(*args)
9
9
  end
10
10
 
11
+ def get_multi(keys)
12
+ map = Hash[keys.zip(keys.map { |key| @local_cache[key] })]
13
+ missing_keys = map.select { |key, value| value.nil? }.map(&:first)
14
+
15
+ unless missing_keys.empty?
16
+ if Rails.cache.respond_to?(:read_multi)
17
+ missing_map = Rails.cache.read_multi(missing_keys)
18
+ missing_map.each do |key, value|
19
+ @local_cache[key] = value
20
+ end
21
+ map.merge!(missing_map)
22
+ else
23
+ missing_keys.each do |key|
24
+ map[key] = read(key)
25
+ end
26
+ end
27
+ end
28
+
29
+ map
30
+ end
31
+
11
32
  def write(*args)
12
33
  @local_cache[args[0]] = args[1]
13
34
  Rails.cache.write(*args)
@@ -22,4 +43,4 @@ module CacheBack
22
43
  @local_cache = {}
23
44
  end
24
45
  end
25
- end
46
+ end
@@ -4,18 +4,41 @@ module CacheBack
4
4
  def self.extended(model_class)
5
5
  class << model_class
6
6
  alias_method_chain :find_one, :cache_back
7
+ alias_method_chain :find_some, :cache_back
7
8
  end
8
9
  end
9
10
 
10
11
  def find_one_with_cache_back(id, options)
11
- record = cache_safe?(options) ? CacheBack.cache.read(cache_back_key_for(id)) : nil
12
+ if cache_safe?(options)
13
+ unless record = CacheBack.cache.read(cache_back_key_for(id))
14
+ record = find_one_without_cache_back(id, options)
15
+ record.store_in_cache_back if record
16
+ end
12
17
 
13
- if record.nil?
14
- record = find_one_without_cache_back(id, options)
15
- record.store_in_cache_back if record
18
+ record
19
+ else
20
+ find_one_without_cache_back(id, options)
16
21
  end
22
+ end
23
+
24
+ def find_some_with_cache_back(ids, options)
25
+ if cache_safe?(options)
26
+ id_to_key_map = Hash[ids.uniq.map { |id| [id, cache_back_key_for(id)] }]
27
+ cached_record_map = CacheBack.cache.get_multi(id_to_key_map.values)
28
+
29
+ missing_keys = Hash[cached_record_map.select { |key, record| record.nil? }].keys
30
+
31
+ return cached_record_map.values if missing_keys.empty?
17
32
 
18
- record
33
+ missing_ids = Hash[id_to_key_map.invert.select { |key, id| missing_keys.include?(key) }].values
34
+
35
+ db_records = find_some_without_cache_back(missing_ids, options)
36
+ db_records.each { |record| record.store_in_cache_back if record }
37
+
38
+ (cached_record_map.values + db_records).compact.uniq.sort { |x, y| x.id <=> y.id}
39
+ else
40
+ find_some_without_cache_back(ids, options)
41
+ end
19
42
  end
20
43
 
21
44
  private
@@ -8,10 +8,10 @@ class FindOneTest < ActiveSupport::TestCase
8
8
  should "cache find(id) calls" do
9
9
  post = Post.first
10
10
  assert_nil(Rails.cache.read(post.cache_back_key))
11
- Post.find(post.id)
11
+ assert_equal(post, Post.find(post.id))
12
12
  assert(Rails.cache.read(post.cache_back_key))
13
13
  Post.connection.expects(:select_all).never
14
- Post.find(post.id)
14
+ assert_equal(post, Post.find(post.id))
15
15
  end
16
16
 
17
17
  should "not use cache when using the :select option" do
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class FindSomeTest < ActiveSupport::TestCase
4
+ fixtures :blogs, :posts
5
+
6
+ Post.has_cache_back
7
+
8
+ should "cache find(id, id) calls" do
9
+ post1 = Post.first
10
+ post2 = Post.last
11
+
12
+ assert_nil(Rails.cache.read(post1.cache_back_key))
13
+ assert_nil(Rails.cache.read(post2.cache_back_key))
14
+
15
+ Post.find(post1.id, post2.id)
16
+
17
+ assert(Rails.cache.read(post1.cache_back_key))
18
+ assert(Rails.cache.read(post2.cache_back_key))
19
+
20
+ Post.connection.expects(:select_all).never
21
+ Post.find(post1.id, post2.id)
22
+ end
23
+
24
+ should "only lookup the records that are not in the cache" do
25
+ post1 = Post.first
26
+ post2 = Post.last
27
+ assert_equal(post1, Post.find(post1.id))
28
+ assert(Rails.cache.read(post1.cache_back_key))
29
+ assert_nil(Rails.cache.read(post2.cache_back_key))
30
+
31
+ Post.expects(:find_some_without_cache_back).with([post2.id], {}).returns([post2])
32
+ found_posts = Post.find(post1.id, post2.id)
33
+ assert_equal([post1, post2].map(&:id).sort, found_posts.map(&:id).sort)
34
+
35
+ Post.expects(:find_some_without_cache_back).never
36
+ found_posts = Post.find(post1.id, post2.id)
37
+ assert_equal([post1, post2].map(&:id).sort, found_posts.map(&:id).sort)
38
+ end
39
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache_back
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mick Staugaard
@@ -58,6 +58,7 @@ files:
58
58
  - test/database.yml
59
59
  - test/dirty_test.rb
60
60
  - test/find_one_test.rb
61
+ - test/find_some_test.rb
61
62
  - test/fixtures/blogs.yml
62
63
  - test/fixtures/comments.yml
63
64
  - test/fixtures/posts.yml
@@ -94,5 +95,6 @@ summary: A write back caching layer on active record
94
95
  test_files:
95
96
  - test/dirty_test.rb
96
97
  - test/find_one_test.rb
98
+ - test/find_some_test.rb
97
99
  - test/helper.rb
98
100
  - test/schema.rb