cache_back 0.3.4 → 0.4.1

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/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