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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +3 -2
  4. data/CHANGELOG +13 -1
  5. data/Gemfile +2 -2
  6. data/{Gemfile.rails4 → Gemfile.rails41} +2 -2
  7. data/Gemfile32 +7 -0
  8. data/README.md +3 -4
  9. data/identity_cache.gemspec +3 -2
  10. data/lib/identity_cache/belongs_to_caching.rb +1 -1
  11. data/lib/identity_cache/cache_hash.rb +2 -2
  12. data/lib/identity_cache/cache_invalidation.rb +26 -0
  13. data/lib/identity_cache/cache_key_generation.rb +3 -2
  14. data/lib/identity_cache/configuration_dsl.rb +38 -32
  15. data/lib/identity_cache/query_api.rb +52 -52
  16. data/lib/identity_cache/version.rb +1 -1
  17. data/lib/identity_cache.rb +20 -8
  18. data/performance/cache_runner.rb +7 -4
  19. data/performance/profile.rb +13 -3
  20. data/test/attribute_cache_test.rb +13 -4
  21. data/test/cache_fetch_includes_test.rb +1 -44
  22. data/test/cache_invalidation_test.rb +52 -0
  23. data/test/denormalized_has_many_test.rb +4 -4
  24. data/test/fetch_multi_test.rb +54 -0
  25. data/test/fetch_multi_with_batched_associations_test.rb +13 -35
  26. data/test/fetch_test.rb +20 -6
  27. data/test/fixtures/serialized_record +0 -0
  28. data/test/helpers/active_record_objects.rb +8 -2
  29. data/test/helpers/database_connection.rb +8 -5
  30. data/test/helpers/serialization_format.rb +9 -5
  31. data/test/helpers/update_serialization_format.rb +1 -0
  32. data/test/index_cache_test.rb +21 -1
  33. data/test/memoized_cache_proxy_test.rb +9 -17
  34. data/test/normalized_belongs_to_test.rb +2 -0
  35. data/test/normalized_has_many_test.rb +4 -4
  36. data/test/recursive_denormalized_has_many_test.rb +1 -1
  37. data/test/schema_change_test.rb +2 -2
  38. data/test/test_helper.rb +7 -3
  39. metadata +26 -17
  40. data/test/helpers/cache.rb +0 -15
@@ -1,6 +1,6 @@
1
1
  require "test_helper"
2
2
 
3
- class ExpirationTest < IdentityCache::TestCase
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
- IdentityCache.cache_backend = Rails.cache
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
- Rails.cache.expects(:read).never
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
- Rails.cache.expects(:read).never
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
- Rails.cache.expects(:read).with('foo').returns('bar')
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
- Rails.cache.expects(:read).never
45
- Rails.cache.expects(:write).with('foo', 'bar')
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
- Rails.cache.write('fooz', 'baz')
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
- Rails.cache.expects(:read_multi).never
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 => false
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.item_id = @new_record.id
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 test_touching_a_child_record_should_expire_only_itself
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.touch
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 => false
97
+ Item.cache_has_many :associated_records, :embed => :ids
98
98
 
99
99
  @record = Item.new(:title => 'foo')
100
100
  @record.save
@@ -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 => false
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 => false
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.7
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-03-05 00:00:00.000000000 Z
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: 0.0.3
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: 0.0.3
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.rails4
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.0
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:
@@ -1,15 +0,0 @@
1
- require 'logger'
2
-
3
- module Rails
4
-
5
- class Cache < ActiveSupport::Cache::MemcachedStore
6
- end
7
-
8
- def self.cache
9
- @@cache ||= Cache.new("localhost:#{$memcached_port}")
10
- end
11
-
12
- def self.logger
13
- @logger ||= Logger.new(nil)
14
- end
15
- end