arid_cache 1.3.4 → 1.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.rdoc +47 -2
- data/VERSION +1 -1
- data/arid_cache.gemspec +2 -2
- data/lib/arid_cache/cache_proxy/result_processor.rb +7 -2
- data/spec/arid_cache/cache_proxy_spec.rb +59 -41
- data/spec/arid_cache/helpers_spec.rb +2 -1
- metadata +4 -4
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -8,7 +8,8 @@ AridCache simplifies caching by supporting auto-expiring cache keys - as well as
|
|
8
8
|
|
9
9
|
== Changes
|
10
10
|
|
11
|
-
* v1.3.
|
11
|
+
* v1.3.5: Backwards-compatibility fix for caching an empty array with <tt>:raw => true</tt>
|
12
|
+
* v1.3.4: Inherited cache configurations: Cache options and cache blocks are inherited from superclasses
|
12
13
|
* v1.3.2: <tt>AridCache.raw_with_options</tt> configuration for better <tt>:raw</tt> handling on cached ActiveRecord collections
|
13
14
|
* v1.3.1: Proxy support which allow you to control how your objects get serialized and unserialized
|
14
15
|
* v1.3.0: Support limits, ordering and pagination on cached Enumerables
|
@@ -52,7 +53,7 @@ Then
|
|
52
53
|
* <b>Preserves ordering</b> of your cached ActiveRecord collections
|
53
54
|
* <b>Optimized</b> to make as few cache and database accesses as absolutely neccessary
|
54
55
|
* Define your own <b>cache proxy</b> to serialize your objects as they go to and from the cache
|
55
|
-
* <b>Inherited
|
56
|
+
* <b>Inherited cache configurations</b> - subclasses inherit cache options and cache blocks from superclasses.
|
56
57
|
|
57
58
|
== Introduction
|
58
59
|
|
@@ -454,6 +455,50 @@ All of the above calls work with <tt>raw => true</tt>. With that option the res
|
|
454
455
|
|
455
456
|
In practice you probably want to define your proxy method on <tt>ActiveRecord::Base</tt> so that it is available to all your models. In future AridCache will probably have some built-in proxies that you can make use of.
|
456
457
|
|
458
|
+
== Inherited Cache Options
|
459
|
+
|
460
|
+
Subclasses automatically inherit cache definitions from their superclasses. The options for a particular cache are merged, with options from subclasses overriding the superclass. If a superclass defines a block for that cache, the one from the closest ancestor is used.
|
461
|
+
|
462
|
+
Here is a simple example:
|
463
|
+
|
464
|
+
class Abc
|
465
|
+
include AridCache
|
466
|
+
instance_caches do
|
467
|
+
name(:limit => 2) { 'abc' }
|
468
|
+
actual_name(:limit => 2)
|
469
|
+
end
|
470
|
+
|
471
|
+
def actual_name
|
472
|
+
'abc'
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
class Def < Abc
|
477
|
+
instance_caches do
|
478
|
+
name(:limit => 1)
|
479
|
+
actual_name(:limit => 1)
|
480
|
+
end
|
481
|
+
|
482
|
+
def actual_name
|
483
|
+
'def'
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
> a, d = Abc.new, Def.new
|
488
|
+
> a.cached_name
|
489
|
+
"ab"
|
490
|
+
> a.cached_actual_name
|
491
|
+
"ab"
|
492
|
+
> d.cached_name
|
493
|
+
"a"
|
494
|
+
|
495
|
+
So here +cached_name+ is using its own <tt>:limit => 1</tt> with the block from +Abc+. So it's returning the first character of 'abc'.
|
496
|
+
|
497
|
+
> d.cached_actual_name
|
498
|
+
"d"
|
499
|
+
|
500
|
+
Here +cached_actual_name+ is using its own <tt>:limit => 1</tt> but since no ancestor class defines a block on the cache, it uses the method from the instance. So it's returning the first character of 'def'.
|
501
|
+
|
457
502
|
== Efficiency
|
458
503
|
|
459
504
|
* AridCache intercepts calls to <tt>cached_</tt> methods using <tt>method_missing</tt> then defines those methods on your models as they are called, so they bypass method missing on subsequent calls.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.5
|
data/arid_cache.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{arid_cache}
|
8
|
-
s.version = "1.3.
|
8
|
+
s.version = "1.3.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Karl Varga"]
|
12
|
-
s.date = %q{2011-04-
|
12
|
+
s.date = %q{2011-04-14}
|
13
13
|
s.description = %q{AridCache makes caching easy and effective. AridCache supports caching on all your model named scopes, class methods and instance methods right out of the box. AridCache prevents caching logic from cluttering your models and clarifies your logic by making explicit calls to cached result sets.
|
14
14
|
AridCache is designed for handling large, expensive ActiveRecord collections but is equally useful for caching anything else as well.
|
15
15
|
}
|
@@ -18,9 +18,9 @@ module AridCache
|
|
18
18
|
@options = opts.is_a?(AridCache::CacheProxy::Options) ? opts : AridCache::CacheProxy::Options.new(opts)
|
19
19
|
end
|
20
20
|
|
21
|
-
# Return true if the result is an
|
21
|
+
# Return true if the result is an array and it is empty.
|
22
22
|
def is_empty?
|
23
|
-
|
23
|
+
@result.is_a?(Array) && @result.empty?
|
24
24
|
end
|
25
25
|
|
26
26
|
# Return true if the result is an enumerable.
|
@@ -79,6 +79,11 @@ module AridCache
|
|
79
79
|
lazy_cache.count = @result.size
|
80
80
|
lazy_cache.klass = @result.first.class
|
81
81
|
lazy_cache
|
82
|
+
elsif is_empty? && !AridCache.raw_with_options # deprecated behaviour
|
83
|
+
lazy_cache.ids = @result
|
84
|
+
lazy_cache.count = 0
|
85
|
+
lazy_cache.klass = result_klass
|
86
|
+
lazy_cache
|
82
87
|
elsif @result.nil? # so we can distinguish a cached nil vs an empty cache
|
83
88
|
lazy_cache.klass = NilClass
|
84
89
|
lazy_cache
|
@@ -11,62 +11,61 @@ describe AridCache::CacheProxy do
|
|
11
11
|
@user.companies << Company.make
|
12
12
|
@user.companies << Company.make
|
13
13
|
@user.clear_instance_caches
|
14
|
+
AridCache.raw_with_options = true
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
after :all do
|
22
|
-
AridCache.raw_with_options = false
|
23
|
-
end
|
17
|
+
after :all do
|
18
|
+
AridCache.raw_with_options = false
|
19
|
+
end
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
it "should use the new raw handling" do
|
22
|
+
AridCache.raw_with_options.should be_true
|
23
|
+
end
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
it "should return raw results" do
|
26
|
+
@user.cached_companies(:raw => true).should == @user.companies.collect(&:id)
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
it "result should have the same ids as the normal result" do
|
30
|
+
@user.cached_companies(:raw => true).should == @user.cached_companies.collect(&:id)
|
31
|
+
end
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
it "should ignore :raw => false" do
|
34
|
+
@user.cached_companies(:raw => false).should == @user.cached_companies
|
35
|
+
end
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
37
|
+
it "should only query once to seed the cache, ignoring all other options" do
|
38
|
+
lambda { @user.cached_companies(:raw => true, :limit => 0, :order => 'nonexistent_column desc') }.should query(1)
|
39
|
+
end
|
44
40
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
41
|
+
it "should apply options even if the cache has already been seeded" do
|
42
|
+
lambda {
|
43
|
+
companies = @user.cached_companies
|
44
|
+
@user.cached_companies(:raw => true, :limit => 1).should == companies.collect(&:id)[0,1]
|
45
|
+
}.should query(1)
|
46
|
+
end
|
51
47
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
it "should not use the raw option when reading from the cache" do
|
49
|
+
mock.proxy(Rails.cache).read(@user.arid_cache_key(:companies), {})
|
50
|
+
@user.cached_companies(:raw => true)
|
51
|
+
end
|
56
52
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
@user.cached_bogus_count(:raw => true).should == 10
|
53
|
+
it "should work for calls to a method that ends with _count" do
|
54
|
+
@user.cached_bogus_count do
|
55
|
+
10
|
62
56
|
end
|
57
|
+
@user.cached_bogus_count(:raw => true).should == 10
|
58
|
+
end
|
63
59
|
|
64
|
-
|
65
|
-
|
66
|
-
end
|
60
|
+
it "should work for calls to a method that ends with _count" do
|
61
|
+
@user.cached_companies_count(:raw => true).should == @user.cached_companies_count
|
67
62
|
end
|
68
63
|
|
69
64
|
describe "deprecated" do
|
65
|
+
before :each do
|
66
|
+
AridCache.raw_with_options = false
|
67
|
+
end
|
68
|
+
|
70
69
|
it "should use the deprecated handling" do
|
71
70
|
AridCache.raw_with_options.should be_false
|
72
71
|
end
|
@@ -109,6 +108,25 @@ describe AridCache::CacheProxy do
|
|
109
108
|
it "should work for calls to a method that ends with _count" do
|
110
109
|
@user.cached_companies_count(:raw => true).should == @user.cached_companies_count
|
111
110
|
end
|
111
|
+
|
112
|
+
describe "empty array" do
|
113
|
+
before :each do
|
114
|
+
@user.cached_empty_array { [] }
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should be stored as a CachedResult" do
|
118
|
+
@user.cached_empty_array(:raw => true).should be_a(AridCache::CacheProxy::CachedResult)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should have the class of the receiver" do
|
122
|
+
@user.cached_empty_array(:raw => true).klass.should be(User)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should return a CachedResult when the cache is empty" do
|
126
|
+
@user.cached_empty_array(:clear => true)
|
127
|
+
@user.cached_empty_array(:raw => true).should be_a(AridCache::CacheProxy::CachedResult)
|
128
|
+
end
|
129
|
+
end
|
112
130
|
end
|
113
131
|
end
|
114
132
|
|
@@ -9,7 +9,8 @@ describe AridCache::Helpers do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should description" do
|
12
|
-
AridCache.subclasses_of(Aa).should
|
12
|
+
AridCache.subclasses_of(Aa).should include(Cc)
|
13
|
+
AridCache.subclasses_of(Aa).should include(Bb)
|
13
14
|
AridCache.subclasses_of(Bb).should == [Cc]
|
14
15
|
end
|
15
16
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arid_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 5
|
10
|
+
version: 1.3.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Karl Varga
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-14 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|