identity_cache 0.0.7 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +3 -2
- data/CHANGELOG +13 -1
- data/Gemfile +2 -2
- data/{Gemfile.rails4 → Gemfile.rails41} +2 -2
- data/Gemfile32 +7 -0
- data/README.md +3 -4
- data/identity_cache.gemspec +3 -2
- data/lib/identity_cache/belongs_to_caching.rb +1 -1
- data/lib/identity_cache/cache_hash.rb +2 -2
- data/lib/identity_cache/cache_invalidation.rb +26 -0
- data/lib/identity_cache/cache_key_generation.rb +3 -2
- data/lib/identity_cache/configuration_dsl.rb +38 -32
- data/lib/identity_cache/query_api.rb +52 -52
- data/lib/identity_cache/version.rb +1 -1
- data/lib/identity_cache.rb +20 -8
- data/performance/cache_runner.rb +7 -4
- data/performance/profile.rb +13 -3
- data/test/attribute_cache_test.rb +13 -4
- data/test/cache_fetch_includes_test.rb +1 -44
- data/test/cache_invalidation_test.rb +52 -0
- data/test/denormalized_has_many_test.rb +4 -4
- data/test/fetch_multi_test.rb +54 -0
- data/test/fetch_multi_with_batched_associations_test.rb +13 -35
- data/test/fetch_test.rb +20 -6
- data/test/fixtures/serialized_record +0 -0
- data/test/helpers/active_record_objects.rb +8 -2
- data/test/helpers/database_connection.rb +8 -5
- data/test/helpers/serialization_format.rb +9 -5
- data/test/helpers/update_serialization_format.rb +1 -0
- data/test/index_cache_test.rb +21 -1
- data/test/memoized_cache_proxy_test.rb +9 -17
- data/test/normalized_belongs_to_test.rb +2 -0
- data/test/normalized_has_many_test.rb +4 -4
- data/test/recursive_denormalized_has_many_test.rb +1 -1
- data/test/schema_change_test.rb +2 -2
- data/test/test_helper.rb +7 -3
- metadata +26 -17
- data/test/helpers/cache.rb +0 -15
data/test/index_cache_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
|
-
class
|
3
|
+
class IndexCacheTest < IdentityCache::TestCase
|
4
4
|
NAMESPACE = IdentityCache::CacheKeyGeneration::DEFAULT_NAMESPACE
|
5
5
|
|
6
6
|
def setup
|
@@ -11,6 +11,26 @@ class ExpirationTest < IdentityCache::TestCase
|
|
11
11
|
@cache_key = "#{NAMESPACE}index:Item:title:#{cache_hash(@record.title)}"
|
12
12
|
end
|
13
13
|
|
14
|
+
def test_fetch_with_garbage_input_should_use_properly_typed_sql
|
15
|
+
Item.cache_index :title, :id
|
16
|
+
|
17
|
+
Item.connection.expects(:exec_query)
|
18
|
+
.with(regexp_matches(/ WHERE `items`\.`title` = 'garbage' AND `items`\.`id` = 0\z/i), anything)
|
19
|
+
.returns(ActiveRecord::Result.new([], []))
|
20
|
+
|
21
|
+
assert_equal [], Item.fetch_by_title_and_id('garbage', 'garbage')
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_fetch_with_unique_adds_limit_clause
|
25
|
+
Item.cache_index :title, :id, :unique => true
|
26
|
+
|
27
|
+
Item.connection.expects(:exec_query)
|
28
|
+
.with(regexp_matches(/ LIMIT 1\Z/i), anything)
|
29
|
+
.returns(ActiveRecord::Result.new([], []))
|
30
|
+
|
31
|
+
assert_equal nil, Item.fetch_by_title_and_id('title', '2')
|
32
|
+
end
|
33
|
+
|
14
34
|
def test_unique_index_caches_nil
|
15
35
|
Item.cache_index :title, :unique => true
|
16
36
|
assert_equal nil, Item.fetch_by_title('bob')
|
@@ -3,7 +3,7 @@ require "test_helper"
|
|
3
3
|
class MemoizedCacheProxyTest < IdentityCache::TestCase
|
4
4
|
def setup
|
5
5
|
super
|
6
|
-
|
6
|
+
@backend = IdentityCache.cache.cache_backend
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_changing_default_cache
|
@@ -13,7 +13,7 @@ class MemoizedCacheProxyTest < IdentityCache::TestCase
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_read_should_short_circuit_on_memoized_values
|
16
|
-
|
16
|
+
@backend.expects(:read).never
|
17
17
|
|
18
18
|
IdentityCache.cache.with_memoization do
|
19
19
|
IdentityCache.cache.write('foo', 'bar')
|
@@ -22,7 +22,7 @@ class MemoizedCacheProxyTest < IdentityCache::TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_read_should_short_circuit_on_falsy_memoized_values
|
25
|
-
|
25
|
+
@backend.expects(:read).never
|
26
26
|
|
27
27
|
IdentityCache.cache.with_memoization do
|
28
28
|
IdentityCache.cache.write('foo', nil)
|
@@ -33,7 +33,7 @@ class MemoizedCacheProxyTest < IdentityCache::TestCase
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_read_should_try_memcached_on_not_memoized_values
|
36
|
-
|
36
|
+
@backend.expects(:read).with('foo').returns('bar')
|
37
37
|
|
38
38
|
IdentityCache.cache.with_memoization do
|
39
39
|
assert_equal 'bar', IdentityCache.cache.read('foo')
|
@@ -41,9 +41,8 @@ class MemoizedCacheProxyTest < IdentityCache::TestCase
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_write_should_memoize_values
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
@backend.expects(:read).never
|
45
|
+
@backend.expects(:write).with('foo', 'bar')
|
47
46
|
|
48
47
|
IdentityCache.cache.with_memoization do
|
49
48
|
IdentityCache.cache.write('foo', 'bar')
|
@@ -76,7 +75,7 @@ class MemoizedCacheProxyTest < IdentityCache::TestCase
|
|
76
75
|
|
77
76
|
def test_read_multi_with_partially_memoized_should_read_missing_keys_from_memcache
|
78
77
|
IdentityCache.cache.write('foo', 'bar')
|
79
|
-
|
78
|
+
@backend.write('fooz', 'baz')
|
80
79
|
|
81
80
|
IdentityCache.cache.with_memoization do
|
82
81
|
assert_equal({'foo' => 'bar', 'fooz' => 'baz'}, IdentityCache.cache.read_multi('foo', 'fooz'))
|
@@ -84,7 +83,7 @@ class MemoizedCacheProxyTest < IdentityCache::TestCase
|
|
84
83
|
end
|
85
84
|
|
86
85
|
def test_read_multi_with_blank_values_should_not_hit_the_cache_engine
|
87
|
-
|
86
|
+
@backend.expects(:read_multi).never
|
88
87
|
|
89
88
|
IdentityCache.cache.with_memoization do
|
90
89
|
IdentityCache.cache.write('foo', [])
|
@@ -98,13 +97,6 @@ class MemoizedCacheProxyTest < IdentityCache::TestCase
|
|
98
97
|
IdentityCache.cache.with_memoization do
|
99
98
|
IdentityCache.cache.write('foo', 'bar')
|
100
99
|
end
|
101
|
-
|
102
|
-
assert_equal 'bar', Rails.cache.read('foo')
|
103
|
-
end
|
104
|
-
|
105
|
-
def test_set_backend_should_not_touch_rails
|
106
|
-
Rails.expects(:cache).never
|
107
|
-
IdentityCache.instance_variable_set(:@cache, nil)
|
108
|
-
IdentityCache.cache_backend = Rails::Cache.new
|
100
|
+
assert_equal 'bar', @backend.read('foo')
|
109
101
|
end
|
110
102
|
end
|
@@ -10,6 +10,8 @@ class NormalizedBelongsToTest < IdentityCache::TestCase
|
|
10
10
|
@parent_record.save
|
11
11
|
@parent_record.reload
|
12
12
|
@record = @parent_record.associated_records.first
|
13
|
+
# Reset association cache, so we remove the inverse of in memory reference
|
14
|
+
@record.association(:item).reset
|
13
15
|
end
|
14
16
|
|
15
17
|
def test_fetching_the_association_should_delegate_to_the_normal_association_fetcher_if_any_transactions_are_open
|
@@ -3,7 +3,7 @@ require "test_helper"
|
|
3
3
|
class NormalizedHasManyTest < IdentityCache::TestCase
|
4
4
|
def setup
|
5
5
|
super
|
6
|
-
Item.cache_has_many :associated_records, :embed =>
|
6
|
+
Item.cache_has_many :associated_records, :embed => :ids
|
7
7
|
|
8
8
|
@record = Item.new(:title => 'foo')
|
9
9
|
@record.not_cached_records << NotCachedRecord.new(:name => 'NoCache')
|
@@ -99,7 +99,7 @@ class NormalizedHasManyTest < IdentityCache::TestCase
|
|
99
99
|
|
100
100
|
def test_saving_a_child_record_should_expire_the_new_and_old_parents_cache_blob
|
101
101
|
@new_record = Item.create
|
102
|
-
@baz.
|
102
|
+
@baz.item = @new_record
|
103
103
|
|
104
104
|
IdentityCache.cache.expects(:delete).with(@record.primary_cache_index_key).once
|
105
105
|
IdentityCache.cache.expects(:delete).with(@new_record.primary_cache_index_key).once
|
@@ -135,9 +135,9 @@ class NormalizedHasManyTest < IdentityCache::TestCase
|
|
135
135
|
assert_equal [@bar], @record.reload.fetch_associated_records
|
136
136
|
end
|
137
137
|
|
138
|
-
def
|
138
|
+
def test_saving_a_child_record_should_expire_only_itself
|
139
139
|
IdentityCache.cache.expects(:delete).with(@baz.primary_cache_index_key).once
|
140
|
-
@baz.
|
140
|
+
@baz.save!
|
141
141
|
end
|
142
142
|
|
143
143
|
def test_touching_child_with_touch_true_on_parent_expires_parent
|
@@ -94,7 +94,7 @@ class RecursiveNormalizedHasManyTest < IdentityCache::TestCase
|
|
94
94
|
def setup
|
95
95
|
super
|
96
96
|
AssociatedRecord.cache_has_many :deeply_associated_records, :embed => true
|
97
|
-
Item.cache_has_many :associated_records, :embed =>
|
97
|
+
Item.cache_has_many :associated_records, :embed => :ids
|
98
98
|
|
99
99
|
@record = Item.new(:title => 'foo')
|
100
100
|
@record.save
|
data/test/schema_change_test.rb
CHANGED
@@ -83,7 +83,7 @@ class SchemaChangeTest < IdentityCache::TestCase
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def test_embed_existing_cache_has_many
|
86
|
-
Item.cache_has_many :polymorphic_records, :inverse_name => :owner, :embed =>
|
86
|
+
Item.cache_has_many :polymorphic_records, :inverse_name => :owner, :embed => :ids
|
87
87
|
read_new_schema
|
88
88
|
|
89
89
|
record = Item.fetch(@record.id)
|
@@ -98,7 +98,7 @@ class SchemaChangeTest < IdentityCache::TestCase
|
|
98
98
|
def test_add_non_embedded_cache_has_many
|
99
99
|
record = Item.fetch(@record.id)
|
100
100
|
|
101
|
-
Item.cache_has_many :polymorphic_records, :inverse_name => :owner, :embed =>
|
101
|
+
Item.cache_has_many :polymorphic_records, :inverse_name => :owner, :embed => :ids
|
102
102
|
read_new_schema
|
103
103
|
|
104
104
|
Item.expects(:resolve_cache_miss).returns(@record)
|
data/test/test_helper.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
require 'logger'
|
1
2
|
require 'minitest/autorun'
|
2
3
|
require 'mocha/setup'
|
3
4
|
require 'active_record'
|
4
|
-
require 'memcached_store'
|
5
|
-
require 'active_support/cache/memcached_store'
|
6
|
-
require 'helpers/cache'
|
7
5
|
require 'helpers/database_connection'
|
8
6
|
require 'helpers/active_record_objects'
|
7
|
+
require 'spy'
|
8
|
+
require 'memcached_store'
|
9
|
+
require 'active_support/cache/memcached_store'
|
9
10
|
|
10
11
|
require File.dirname(__FILE__) + '/../lib/identity_cache'
|
11
12
|
|
@@ -38,6 +39,9 @@ class IdentityCache::TestCase < MiniTest::Unit::TestCase
|
|
38
39
|
DatabaseConnection.drop_tables
|
39
40
|
DatabaseConnection.create_tables
|
40
41
|
|
42
|
+
IdentityCache.logger = Logger.new(nil)
|
43
|
+
IdentityCache.cache_backend = ActiveSupport::Cache::MemcachedStore.new("localhost:#{$memcached_port}")
|
44
|
+
|
41
45
|
setup_models
|
42
46
|
end
|
43
47
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: identity_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Camilo Lopez
|
@@ -13,22 +13,22 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2014-
|
16
|
+
date: 2014-05-08 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: ar_transaction_changes
|
20
20
|
requirement: !ruby/object:Gem::Requirement
|
21
21
|
requirements:
|
22
|
-
- -
|
22
|
+
- - "~>"
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version:
|
24
|
+
version: '1.0'
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
|
-
- -
|
29
|
+
- - "~>"
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version:
|
31
|
+
version: '1.0'
|
32
32
|
- !ruby/object:Gem::Dependency
|
33
33
|
name: activerecord
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
@@ -36,9 +36,6 @@ dependencies:
|
|
36
36
|
- - ">="
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: '3.2'
|
39
|
-
- - "<"
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: '4.1'
|
42
39
|
type: :runtime
|
43
40
|
prerelease: false
|
44
41
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -46,9 +43,6 @@ dependencies:
|
|
46
43
|
- - ">="
|
47
44
|
- !ruby/object:Gem::Version
|
48
45
|
version: '3.2'
|
49
|
-
- - "<"
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
version: '4.1'
|
52
46
|
- !ruby/object:Gem::Dependency
|
53
47
|
name: memcached_store
|
54
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,6 +85,20 @@ dependencies:
|
|
91
85
|
- - '='
|
92
86
|
- !ruby/object:Gem::Version
|
93
87
|
version: 0.14.0
|
88
|
+
- !ruby/object:Gem::Dependency
|
89
|
+
name: spy
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
type: :development
|
96
|
+
prerelease: false
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
94
102
|
- !ruby/object:Gem::Dependency
|
95
103
|
name: cityhash
|
96
104
|
requirement: !ruby/object:Gem::Requirement
|
@@ -145,7 +153,8 @@ files:
|
|
145
153
|
- ".travis.yml"
|
146
154
|
- CHANGELOG
|
147
155
|
- Gemfile
|
148
|
-
- Gemfile.
|
156
|
+
- Gemfile.rails41
|
157
|
+
- Gemfile32
|
149
158
|
- LICENSE
|
150
159
|
- README.md
|
151
160
|
- Rakefile
|
@@ -153,6 +162,7 @@ files:
|
|
153
162
|
- lib/identity_cache.rb
|
154
163
|
- lib/identity_cache/belongs_to_caching.rb
|
155
164
|
- lib/identity_cache/cache_hash.rb
|
165
|
+
- lib/identity_cache/cache_invalidation.rb
|
156
166
|
- lib/identity_cache/cache_key_generation.rb
|
157
167
|
- lib/identity_cache/configuration_dsl.rb
|
158
168
|
- lib/identity_cache/memoized_cache_proxy.rb
|
@@ -166,6 +176,7 @@ files:
|
|
166
176
|
- test/attribute_cache_test.rb
|
167
177
|
- test/cache_fetch_includes_test.rb
|
168
178
|
- test/cache_hash_test.rb
|
179
|
+
- test/cache_invalidation_test.rb
|
169
180
|
- test/denormalized_has_many_test.rb
|
170
181
|
- test/denormalized_has_one_test.rb
|
171
182
|
- test/fetch_multi_test.rb
|
@@ -173,7 +184,6 @@ files:
|
|
173
184
|
- test/fetch_test.rb
|
174
185
|
- test/fixtures/serialized_record
|
175
186
|
- test/helpers/active_record_objects.rb
|
176
|
-
- test/helpers/cache.rb
|
177
187
|
- test/helpers/database_connection.rb
|
178
188
|
- test/helpers/serialization_format.rb
|
179
189
|
- test/helpers/update_serialization_format.rb
|
@@ -207,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
217
|
version: '0'
|
208
218
|
requirements: []
|
209
219
|
rubyforge_project:
|
210
|
-
rubygems_version: 2.2.
|
220
|
+
rubygems_version: 2.2.2
|
211
221
|
signing_key:
|
212
222
|
specification_version: 4
|
213
223
|
summary: IdentityCache lets you specify how you want to cache your model objects,
|
@@ -218,6 +228,7 @@ test_files:
|
|
218
228
|
- test/attribute_cache_test.rb
|
219
229
|
- test/cache_fetch_includes_test.rb
|
220
230
|
- test/cache_hash_test.rb
|
231
|
+
- test/cache_invalidation_test.rb
|
221
232
|
- test/denormalized_has_many_test.rb
|
222
233
|
- test/denormalized_has_one_test.rb
|
223
234
|
- test/fetch_multi_test.rb
|
@@ -225,7 +236,6 @@ test_files:
|
|
225
236
|
- test/fetch_test.rb
|
226
237
|
- test/fixtures/serialized_record
|
227
238
|
- test/helpers/active_record_objects.rb
|
228
|
-
- test/helpers/cache.rb
|
229
239
|
- test/helpers/database_connection.rb
|
230
240
|
- test/helpers/serialization_format.rb
|
231
241
|
- test/helpers/update_serialization_format.rb
|
@@ -240,4 +250,3 @@ test_files:
|
|
240
250
|
- test/schema_change_test.rb
|
241
251
|
- test/serialization_format_change_test.rb
|
242
252
|
- test/test_helper.rb
|
243
|
-
has_rdoc:
|
data/test/helpers/cache.rb
DELETED