active_record_cache 1.0.3
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/License.txt +674 -0
- data/README.rdoc +57 -0
- data/Rakefile +37 -0
- data/lib/active_record_cache/defaults_handler.rb +15 -0
- data/lib/active_record_cache/record_cache.rb +80 -0
- data/lib/active_record_cache/relation_extension.rb +104 -0
- data/lib/active_record_cache.rb +75 -0
- data/spec/active_record_cache_spec.rb +274 -0
- data/spec/defaults_handler_spec.rb +13 -0
- data/spec/record_cache_spec.rb +53 -0
- data/spec/relation_extension_spec.rb +60 -0
- data/spec/spec_helper.rb +118 -0
- metadata +109 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveRecordCache::RecordCache do
|
4
|
+
let(:cache){ ActiveSupport::Cache::MemoryStore.new(:expires_in => 60) }
|
5
|
+
let(:record_cache){ ActiveRecordCache::RecordCache.new(ActiveRecordCache::Tester, :cache => cache, :expires_in => 120) }
|
6
|
+
let(:tester_1){ ActiveRecordCache::Tester.create!(:name => "tester_1") }
|
7
|
+
let(:tester_2){ ActiveRecordCache::Tester.create!(:name => "tester_2") }
|
8
|
+
let(:tester_3){ ActiveRecordCache::Tester.create!(:name => "tester_3") }
|
9
|
+
|
10
|
+
before :each do
|
11
|
+
Rails.cache.clear
|
12
|
+
ActiveRecordCache::Tester.destroy_all
|
13
|
+
tester_1
|
14
|
+
tester_2
|
15
|
+
tester_3
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have an underlying cache" do
|
19
|
+
record_cache.cache.should == cache
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have an expires_in time" do
|
23
|
+
record_cache.expires_in.should == 120
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should default the expires_in time to the cache's default" do
|
27
|
+
record_cache = ActiveRecordCache::RecordCache.new(ActiveRecordCache::Tester, :cache => cache)
|
28
|
+
record_cache.expires_in.should == 60
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should read a single value" do
|
32
|
+
record_cache[tester_1.id].should == tester_1
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should read a single value using the read method" do
|
36
|
+
record_cache.read(tester_1.id).should == [tester_1]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should read multiple values" do
|
40
|
+
record_cache.read([tester_1.id, tester_2.id]).sort_by_field(:name).should == [tester_1, tester_2]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should get a cache key for a record id" do
|
44
|
+
record_cache.cache_key(1).should == "active_record_cache/testers/1"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should expire an id from the cache" do
|
48
|
+
record_cache[tester_1.id]
|
49
|
+
cache.size.should == 1
|
50
|
+
record_cache.expire(tester_1.id)
|
51
|
+
cache.should be_empty
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveRecordCache::RelationExtension do
|
4
|
+
context "forcing database queries" do
|
5
|
+
let(:relation){ ActiveRecordCache::Tester.unscoped }
|
6
|
+
|
7
|
+
it "should add an attribute indicating if the relation should always be read from the database" do
|
8
|
+
relation.query_from_cache_value.should == nil
|
9
|
+
relation.from_database.query_from_cache_value.should == false
|
10
|
+
relation.from_cache.query_from_cache_value.should == true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should merge the force database read value when merging with another relation" do
|
14
|
+
relation.from_database.where(:id => 1).query_from_cache_value.should == false
|
15
|
+
relation.where(:id => 1).from_cache.query_from_cache_value.should == true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "using the cache" do
|
20
|
+
let(:tester_1){ ActiveRecordCache::Tester.create!(:name => "tester_1") }
|
21
|
+
|
22
|
+
before :each do
|
23
|
+
tester_1
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should not use the cache if the relation is already loaded" do
|
27
|
+
relation = ActiveRecordCache::Tester.where(:id => tester_1.id)
|
28
|
+
relation.to_a
|
29
|
+
relation.loaded?.should == true
|
30
|
+
Rails.cache.size.should == 1
|
31
|
+
Rails.cache.clear
|
32
|
+
relation.to_a
|
33
|
+
Rails.cache.should be_empty
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should not get records from the cache when the class does not support caching" do
|
37
|
+
relation = ActiveRecordCache::NoCacheTester.scoped
|
38
|
+
relation.to_a
|
39
|
+
Rails.cache.should be_empty
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should not get records from the cache when it is not a cacheable query" do
|
43
|
+
relation = ActiveRecordCache::Tester.where(:id => tester_1.id, :name => tester_1.name)
|
44
|
+
relation.to_a
|
45
|
+
Rails.cache.should be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not get records from the cache when the query is forcing a database read" do
|
49
|
+
relation = ActiveRecordCache::Tester.where(:id => tester_1.id).from_database
|
50
|
+
relation.to_a
|
51
|
+
Rails.cache.should be_empty
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should get records from the cache when the class supports caching, it is a cacheable query, and the query is not forcing a database read" do
|
55
|
+
relation = ActiveRecordCache::Tester.where(:id => tester_1.id)
|
56
|
+
relation.to_a
|
57
|
+
Rails.cache.size.should == 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sqlite3'
|
3
|
+
|
4
|
+
active_record_version = ENV['ACTIVE_RECORD_VERSION'] || "~>3.0.0"
|
5
|
+
gem 'activerecord', active_record_version
|
6
|
+
gem 'activesupport', active_record_version
|
7
|
+
require 'active_record'
|
8
|
+
puts "Testing against #{ActiveRecord::VERSION::STRING}"
|
9
|
+
|
10
|
+
begin
|
11
|
+
require 'simplecov'
|
12
|
+
SimpleCov.start do
|
13
|
+
add_filter "/spec/"
|
14
|
+
end
|
15
|
+
rescue LoadError
|
16
|
+
# simplecov not installed
|
17
|
+
end
|
18
|
+
|
19
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'active_record_cache'))
|
20
|
+
|
21
|
+
MY_CACHE = ActiveSupport::Cache::MemoryStore.new
|
22
|
+
|
23
|
+
module Rails
|
24
|
+
def self.cache
|
25
|
+
unless defined?(@cache)
|
26
|
+
@cache = ActiveSupport::Cache::MemoryStore.new
|
27
|
+
end
|
28
|
+
@cache
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
module ActiveRecordCache
|
38
|
+
class Tester < ActiveRecord::Base
|
39
|
+
include ActiveRecordCache
|
40
|
+
use_record_cache :preload => :no_cache_testers, :default => true
|
41
|
+
|
42
|
+
belongs_to :test
|
43
|
+
has_many :no_cache_testers
|
44
|
+
|
45
|
+
def self.create_table
|
46
|
+
connection.create_table(table_name) do |t|
|
47
|
+
t.string :name
|
48
|
+
t.integer :test_id
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_association_loaded?
|
53
|
+
if respond_to?(:association)
|
54
|
+
association(:test).loaded?
|
55
|
+
else
|
56
|
+
self.loaded_test?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Test < ActiveRecord::Base
|
62
|
+
include ActiveRecordCache
|
63
|
+
use_record_cache :cache => MY_CACHE, :expires_in => 30, :default => true
|
64
|
+
|
65
|
+
def self.create_table
|
66
|
+
connection.create_table(table_name) do |t|
|
67
|
+
t.string :name
|
68
|
+
t.string :type
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class SubTest < Test
|
74
|
+
end
|
75
|
+
|
76
|
+
class TesterNoCacheDefault < ActiveRecord::Base
|
77
|
+
include ActiveRecordCache
|
78
|
+
use_record_cache :preload => :no_cache_testers
|
79
|
+
|
80
|
+
def self.create_table
|
81
|
+
connection.create_table(table_name) do |t|
|
82
|
+
t.string :name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class NoCacheTester < ActiveRecord::Base
|
88
|
+
|
89
|
+
def self.create_table
|
90
|
+
connection.create_table(table_name) do |t|
|
91
|
+
t.string :name
|
92
|
+
t.integer :tester_id
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Used for testing with MemoryStore.
|
98
|
+
module CachePeek
|
99
|
+
def size
|
100
|
+
@data.size
|
101
|
+
end
|
102
|
+
|
103
|
+
def empty?
|
104
|
+
size == 0
|
105
|
+
end
|
106
|
+
|
107
|
+
def [](key)
|
108
|
+
@data[key]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
ActiveSupport::Cache::MemoryStore.send(:include, CachePeek)
|
113
|
+
end
|
114
|
+
|
115
|
+
ActiveRecordCache::Tester.create_table
|
116
|
+
ActiveRecordCache::Test.create_table
|
117
|
+
ActiveRecordCache::NoCacheTester.create_table
|
118
|
+
ActiveRecordCache::TesterNoCacheDefault.create_table
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_record_cache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brian Durand
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: &70234670478240 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.5
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70234670478240
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: tribune-sort_by_field
|
27
|
+
requirement: &70234670476760 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.1
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70234670476760
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70234670475540 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.0.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70234670475540
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: sqlite3
|
49
|
+
requirement: &70234670474060 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70234670474060
|
58
|
+
description: This gem adds a caching layer to ActiveRecord models when finding them
|
59
|
+
by a numeric primary key.
|
60
|
+
email:
|
61
|
+
- mdobrota@tribune.com
|
62
|
+
- ddpr@tribune.com
|
63
|
+
executables: []
|
64
|
+
extensions: []
|
65
|
+
extra_rdoc_files:
|
66
|
+
- README.rdoc
|
67
|
+
files:
|
68
|
+
- License.txt
|
69
|
+
- Rakefile
|
70
|
+
- lib/active_record_cache.rb
|
71
|
+
- lib/active_record_cache/defaults_handler.rb
|
72
|
+
- lib/active_record_cache/record_cache.rb
|
73
|
+
- lib/active_record_cache/relation_extension.rb
|
74
|
+
- spec/active_record_cache_spec.rb
|
75
|
+
- spec/defaults_handler_spec.rb
|
76
|
+
- spec/record_cache_spec.rb
|
77
|
+
- spec/relation_extension_spec.rb
|
78
|
+
- spec/spec_helper.rb
|
79
|
+
- README.rdoc
|
80
|
+
homepage:
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options:
|
84
|
+
- --line-numbers
|
85
|
+
- --inline-source
|
86
|
+
- --main
|
87
|
+
- README.rdoc
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.8.10
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: This gem adds a caching layer to ActiveRecord models when finding them by
|
108
|
+
a numeric primary key.
|
109
|
+
test_files: []
|