identity_cache 0.0.7 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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