identity_cache 0.2.5 → 0.3.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/.travis.yml +2 -4
- data/CHANGELOG.md +22 -0
- data/Gemfile +2 -0
- data/Gemfile.rails40 +1 -0
- data/Gemfile.rails41 +1 -0
- data/Gemfile.rails42 +1 -0
- data/README.md +7 -0
- data/identity_cache.gemspec +1 -1
- data/lib/identity_cache.rb +5 -2
- data/lib/identity_cache/belongs_to_caching.rb +13 -5
- data/lib/identity_cache/cache_key_generation.rb +12 -19
- data/lib/identity_cache/configuration_dsl.rb +83 -84
- data/lib/identity_cache/parent_model_expiration.rb +4 -3
- data/lib/identity_cache/query_api.rb +93 -91
- data/lib/identity_cache/version.rb +2 -2
- data/test/attribute_cache_test.rb +42 -63
- data/test/deeply_nested_associated_record_test.rb +1 -0
- data/test/denormalized_has_many_test.rb +18 -0
- data/test/denormalized_has_one_test.rb +15 -5
- data/test/fetch_multi_test.rb +25 -3
- data/test/fetch_test.rb +20 -7
- data/test/fixtures/serialized_record.mysql2 +0 -0
- data/test/fixtures/serialized_record.postgresql +0 -0
- data/test/helpers/active_record_objects.rb +10 -0
- data/test/helpers/database_connection.rb +6 -1
- data/test/helpers/serialization_format.rb +1 -1
- data/test/index_cache_test.rb +50 -25
- data/test/normalized_belongs_to_test.rb +21 -6
- data/test/normalized_has_many_test.rb +44 -0
- data/test/{fetch_multi_with_batched_associations_test.rb → prefetch_normalized_associations_test.rb} +41 -3
- data/test/save_test.rb +14 -14
- data/test/schema_change_test.rb +2 -0
- data/test/test_helper.rb +4 -4
- metadata +11 -10
- data/Gemfile.rails32 +0 -5
- data/test/fixtures/serialized_record +0 -0
data/test/{fetch_multi_with_batched_associations_test.rb → prefetch_normalized_associations_test.rb}
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
|
-
class
|
3
|
+
class PrefetchNormalizedAssociationsTest < IdentityCache::TestCase
|
4
4
|
NAMESPACE = IdentityCache.cache_namespace
|
5
5
|
|
6
6
|
def setup
|
@@ -14,7 +14,19 @@ class FetchMultiWithBatchedAssociationsTest < IdentityCache::TestCase
|
|
14
14
|
@tenth_blob_key = "#{NAMESPACE}blob:Item:#{cache_hash("created_at:datetime,id:integer,item_id:integer,title:string,updated_at:datetime")}:10"
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def test_fetch_with_includes_option
|
18
|
+
Item.send(:cache_belongs_to, :item)
|
19
|
+
john = Item.create!(title: 'john')
|
20
|
+
@bob.update_column(:item_id, john)
|
21
|
+
|
22
|
+
spy = Spy.on(Item, :fetch_multi).and_call_through
|
23
|
+
|
24
|
+
assert_equal @bob, Item.fetch(@bob.id, includes: :item)
|
25
|
+
|
26
|
+
assert spy.calls.one?{ |call| call.args == [[john.id]] }
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_fetch_multi_with_includes_option
|
18
30
|
Item.send(:cache_belongs_to, :item)
|
19
31
|
john = Item.create!(:title => 'john')
|
20
32
|
jim = Item.create!(:title => 'jim')
|
@@ -23,7 +35,7 @@ class FetchMultiWithBatchedAssociationsTest < IdentityCache::TestCase
|
|
23
35
|
|
24
36
|
spy = Spy.on(Item, :fetch_multi).and_call_through
|
25
37
|
|
26
|
-
|
38
|
+
assert_equal [@bob, @joe, @fred], Item.fetch_multi(@bob.id, @joe.id, @fred.id, :includes => :item)
|
27
39
|
|
28
40
|
assert spy.calls.one?{ |call| call.args == [[john.id, jim.id]] }
|
29
41
|
end
|
@@ -184,6 +196,32 @@ class FetchMultiWithBatchedAssociationsTest < IdentityCache::TestCase
|
|
184
196
|
Item.send(:find_batch, [@bob, @joe, @fred].map(&:id).map(&:to_s))
|
185
197
|
end
|
186
198
|
|
199
|
+
def test_fetch_by_index_with_includes_option
|
200
|
+
Item.send(:cache_belongs_to, :item)
|
201
|
+
Item.cache_index :title
|
202
|
+
john = Item.create!(title: 'john')
|
203
|
+
@bob.update_column(:item_id, john)
|
204
|
+
|
205
|
+
spy = Spy.on(Item, :fetch_multi).and_call_through
|
206
|
+
|
207
|
+
assert_equal [@bob], Item.fetch_by_title('bob', includes: :item)
|
208
|
+
|
209
|
+
assert spy.calls.one?{ |call| call.args == [[john.id]] }
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_fetch_by_unique_index_with_includes_option
|
213
|
+
Item.send(:cache_belongs_to, :item)
|
214
|
+
Item.cache_index :title, :unique => true
|
215
|
+
john = Item.create!(title: 'john')
|
216
|
+
@bob.update_column(:item_id, john)
|
217
|
+
|
218
|
+
spy = Spy.on(Item, :fetch_multi).and_call_through
|
219
|
+
|
220
|
+
assert_equal @bob, Item.fetch_by_title('bob', includes: :item)
|
221
|
+
|
222
|
+
assert spy.calls.one?{ |call| call.args == [[john.id]] }
|
223
|
+
end
|
224
|
+
|
187
225
|
private
|
188
226
|
|
189
227
|
def setup_has_many_children_and_grandchildren(*parents)
|
data/test/save_test.rb
CHANGED
@@ -16,21 +16,21 @@ class SaveTest < IdentityCache::TestCase
|
|
16
16
|
@record = Item.new
|
17
17
|
@record.title = 'bob'
|
18
18
|
|
19
|
-
expect_cache_delete("#{NAMESPACE}
|
20
|
-
expect_cache_delete("#{NAMESPACE}
|
19
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:id/title:#{cache_hash('2/bob')}")
|
20
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:title:#{cache_hash('bob')}")
|
21
21
|
expect_cache_delete("#{NAMESPACE}blob:Item:#{cache_hash("created_at:datetime,id:integer,item_id:integer,title:string,updated_at:datetime")}:2").once
|
22
22
|
@record.save
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_update
|
26
26
|
# Regular flow, write index id, write index id/tile, delete data blob since Record has changed
|
27
|
-
expect_cache_delete("#{NAMESPACE}
|
28
|
-
expect_cache_delete("#{NAMESPACE}
|
27
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:id/title:#{cache_hash('1/fred')}")
|
28
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:title:#{cache_hash('fred')}")
|
29
29
|
expect_cache_delete(@blob_key)
|
30
30
|
|
31
31
|
# Delete index id, delete index id/title
|
32
|
-
expect_cache_delete("#{NAMESPACE}
|
33
|
-
expect_cache_delete("#{NAMESPACE}
|
32
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:id/title:#{cache_hash('1/bob')}")
|
33
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:title:#{cache_hash('bob')}")
|
34
34
|
|
35
35
|
@record.title = 'fred'
|
36
36
|
@record.save
|
@@ -38,8 +38,8 @@ class SaveTest < IdentityCache::TestCase
|
|
38
38
|
|
39
39
|
def test_destroy
|
40
40
|
# Regular flow: delete data blob, delete index id, delete index id/tile
|
41
|
-
expect_cache_delete("#{NAMESPACE}
|
42
|
-
expect_cache_delete("#{NAMESPACE}
|
41
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:id/title:#{cache_hash('1/bob')}")
|
42
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:title:#{cache_hash('bob')}")
|
43
43
|
expect_cache_delete(@blob_key)
|
44
44
|
|
45
45
|
@record.destroy
|
@@ -47,8 +47,8 @@ class SaveTest < IdentityCache::TestCase
|
|
47
47
|
|
48
48
|
def test_destroy_with_changed_attributes
|
49
49
|
# Make sure to delete the old cache index key, since the new title never ended up in an index
|
50
|
-
expect_cache_delete("#{NAMESPACE}
|
51
|
-
expect_cache_delete("#{NAMESPACE}
|
50
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:id/title:#{cache_hash('1/bob')}")
|
51
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:title:#{cache_hash('bob')}")
|
52
52
|
expect_cache_delete(@blob_key)
|
53
53
|
|
54
54
|
@record.title = 'fred'
|
@@ -57,16 +57,16 @@ class SaveTest < IdentityCache::TestCase
|
|
57
57
|
|
58
58
|
def test_touch_will_expire_the_caches
|
59
59
|
# Regular flow: delete data blob, delete index id, delete index id/tile
|
60
|
-
expect_cache_delete("#{NAMESPACE}
|
61
|
-
expect_cache_delete("#{NAMESPACE}
|
60
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:id/title:#{cache_hash('1/bob')}")
|
61
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:title:#{cache_hash('bob')}")
|
62
62
|
expect_cache_delete(@blob_key)
|
63
63
|
|
64
64
|
@record.touch
|
65
65
|
end
|
66
66
|
|
67
67
|
def test_expire_cache_works_in_a_transaction
|
68
|
-
expect_cache_delete("#{NAMESPACE}
|
69
|
-
expect_cache_delete("#{NAMESPACE}
|
68
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:id/title:#{cache_hash('1/bob')}")
|
69
|
+
expect_cache_delete("#{NAMESPACE}attr:Item:id:title:#{cache_hash('bob')}")
|
70
70
|
expect_cache_delete(@blob_key)
|
71
71
|
|
72
72
|
ActiveRecord::Base.transaction do
|
data/test/schema_change_test.rb
CHANGED
@@ -83,6 +83,7 @@ class SchemaChangeTest < IdentityCache::TestCase
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def test_embed_existing_cache_has_many
|
86
|
+
PolymorphicRecord.include(IdentityCache)
|
86
87
|
Item.cache_has_many :polymorphic_records, :inverse_name => :owner, :embed => :ids
|
87
88
|
read_new_schema
|
88
89
|
|
@@ -96,6 +97,7 @@ class SchemaChangeTest < IdentityCache::TestCase
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def test_add_non_embedded_cache_has_many
|
100
|
+
PolymorphicRecord.include(IdentityCache)
|
99
101
|
record = Item.fetch(@record.id)
|
100
102
|
|
101
103
|
Item.cache_has_many :polymorphic_records, :inverse_name => :owner, :embed => :ids
|
data/test/test_helper.rb
CHANGED
@@ -59,7 +59,7 @@ class IdentityCache::TestCase < Minitest::Test
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def assert_not_nil(*args)
|
62
|
-
assert
|
62
|
+
assert(*args)
|
63
63
|
end
|
64
64
|
|
65
65
|
def assert_queries(num = 1)
|
@@ -67,7 +67,7 @@ class IdentityCache::TestCase < Minitest::Test
|
|
67
67
|
subscriber = ActiveSupport::Notifications.subscribe('sql.active_record', counter)
|
68
68
|
exception = false
|
69
69
|
yield
|
70
|
-
rescue
|
70
|
+
rescue
|
71
71
|
exception = true
|
72
72
|
raise
|
73
73
|
ensure
|
@@ -80,7 +80,7 @@ class IdentityCache::TestCase < Minitest::Test
|
|
80
80
|
subscriber = ActiveSupport::Notifications.subscribe(/cache_.*\.active_support/, counter)
|
81
81
|
exception = false
|
82
82
|
yield
|
83
|
-
rescue
|
83
|
+
rescue
|
84
84
|
exception = true
|
85
85
|
raise
|
86
86
|
ensure
|
@@ -101,7 +101,7 @@ end
|
|
101
101
|
|
102
102
|
class SQLCounter
|
103
103
|
cattr_accessor :ignored_sql
|
104
|
-
self.ignored_sql = [/^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]
|
104
|
+
self.ignored_sql = [/^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/, /^SHOW /]
|
105
105
|
|
106
106
|
# FIXME: this needs to be refactored so specific database can add their own
|
107
107
|
# ignored SQL. This ignored SQL is for Oracle.
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Camilo Lopez
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date:
|
17
|
+
date: 2016-01-20 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: ar_transaction_changes
|
@@ -36,14 +36,14 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
39
|
+
version: 4.0.4
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
46
|
+
version: 4.0.4
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: memcached
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -197,7 +197,6 @@ files:
|
|
197
197
|
- CHANGELOG.md
|
198
198
|
- CONTRIBUTING.md
|
199
199
|
- Gemfile
|
200
|
-
- Gemfile.rails32
|
201
200
|
- Gemfile.rails40
|
202
201
|
- Gemfile.rails41
|
203
202
|
- Gemfile.rails42
|
@@ -230,9 +229,9 @@ files:
|
|
230
229
|
- test/denormalized_has_many_test.rb
|
231
230
|
- test/denormalized_has_one_test.rb
|
232
231
|
- test/fetch_multi_test.rb
|
233
|
-
- test/fetch_multi_with_batched_associations_test.rb
|
234
232
|
- test/fetch_test.rb
|
235
|
-
- test/fixtures/serialized_record
|
233
|
+
- test/fixtures/serialized_record.mysql2
|
234
|
+
- test/fixtures/serialized_record.postgresql
|
236
235
|
- test/helpers/active_record_objects.rb
|
237
236
|
- test/helpers/database_connection.rb
|
238
237
|
- test/helpers/serialization_format.rb
|
@@ -243,6 +242,7 @@ files:
|
|
243
242
|
- test/normalized_belongs_to_test.rb
|
244
243
|
- test/normalized_has_many_test.rb
|
245
244
|
- test/normalized_has_one_test.rb
|
245
|
+
- test/prefetch_normalized_associations_test.rb
|
246
246
|
- test/readonly_test.rb
|
247
247
|
- test/recursive_denormalized_has_many_test.rb
|
248
248
|
- test/save_test.rb
|
@@ -268,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
268
268
|
version: '0'
|
269
269
|
requirements: []
|
270
270
|
rubyforge_project:
|
271
|
-
rubygems_version: 2.2.
|
271
|
+
rubygems_version: 2.2.0
|
272
272
|
signing_key:
|
273
273
|
specification_version: 4
|
274
274
|
summary: IdentityCache lets you specify how you want to cache your model objects,
|
@@ -284,9 +284,9 @@ test_files:
|
|
284
284
|
- test/denormalized_has_many_test.rb
|
285
285
|
- test/denormalized_has_one_test.rb
|
286
286
|
- test/fetch_multi_test.rb
|
287
|
-
- test/fetch_multi_with_batched_associations_test.rb
|
288
287
|
- test/fetch_test.rb
|
289
|
-
- test/fixtures/serialized_record
|
288
|
+
- test/fixtures/serialized_record.mysql2
|
289
|
+
- test/fixtures/serialized_record.postgresql
|
290
290
|
- test/helpers/active_record_objects.rb
|
291
291
|
- test/helpers/database_connection.rb
|
292
292
|
- test/helpers/serialization_format.rb
|
@@ -297,6 +297,7 @@ test_files:
|
|
297
297
|
- test/normalized_belongs_to_test.rb
|
298
298
|
- test/normalized_has_many_test.rb
|
299
299
|
- test/normalized_has_one_test.rb
|
300
|
+
- test/prefetch_normalized_associations_test.rb
|
300
301
|
- test/readonly_test.rb
|
301
302
|
- test/recursive_denormalized_has_many_test.rb
|
302
303
|
- test/save_test.rb
|
data/Gemfile.rails32
DELETED
Binary file
|