second_level_cache 2.5.2 → 2.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb263a78785d298fbaccbcb46bb71250f021e66d69f0cf5c89f9d1cd97651c50
4
- data.tar.gz: f861c5fc32002720f2e83b30444ad3f2ac368427406a1c832ca4ba0f5620da89
3
+ metadata.gz: 57109a059ebed4c9d448fa28e474f19eef4ebf7b67e4ebbd728f2be852b61480
4
+ data.tar.gz: '049303d75a982adf35dfea344af63577dd9df1c09a28613bb4dec4332ef95de4'
5
5
  SHA512:
6
- metadata.gz: 9cacc9218aed1c33fd4470c8fa6a5bf21a7e89c22da09f522594e6ab5fb4830a168a7c930c0e3b4470086ac0193e1a906ca27f6543d0cba44fe1b2e9c6cc02f5
7
- data.tar.gz: df2b8f074ce143b141d8fb34d4f5799da505c1e72fdda03dbeaa7284cfd10d9074ca87b93481ba2cafe9df7d578ef40fb11e4afa2a172d351cfcdabc77e7efc4
6
+ metadata.gz: 553a34ea48e7b3100ae819282c354ee0eb51e2d609b7c090bf477035b975a0e497158ca6f4b282add76c882fa7e94277fb39486aaf4e45c35c9e98088a2bbb34
7
+ data.tar.gz: 28a7f7ea7f32467e92097824559fbaebaf3d9dd0fe49443d7779e666cce3270f3378c8e77dae91bffbc5248c8fadd10f00a08ebbbe390641fa9e42007b917ba5
@@ -1,3 +1,8 @@
1
+ 2.5.3
2
+ -------
3
+
4
+ - Fix `fetch_by_uniq_keys` method that cache incorrect when A record modified uniq key and B reocrd used old uniq key of A record (#96)
5
+
1
6
  2.5.2
2
7
  -------
3
8
 
@@ -6,19 +6,22 @@ module SecondLevelCache
6
6
  def fetch_by_uniq_keys(where_values)
7
7
  cache_key = cache_uniq_key(where_values)
8
8
  obj_id = SecondLevelCache.cache_store.read(cache_key)
9
+
9
10
  if obj_id
10
- begin
11
- return find(obj_id)
12
- rescue StandardError
13
- return nil
14
- end
11
+ record = begin
12
+ find(obj_id)
13
+ rescue StandardError
14
+ nil
15
+ end
15
16
  end
16
-
17
+ return record if compare_record_attributes_with_where_values(record, where_values)
17
18
  record = where(where_values).first
18
- return nil unless record
19
-
20
- record.tap do |r|
21
- SecondLevelCache.cache_store.write(cache_key, r.id)
19
+ if record
20
+ SecondLevelCache.cache_store.write(cache_key, record.id)
21
+ return record
22
+ else
23
+ SecondLevelCache.cache_store.delete(cache_key)
24
+ return nil
22
25
  end
23
26
  end
24
27
 
@@ -42,13 +45,30 @@ module SecondLevelCache
42
45
 
43
46
  def cache_uniq_key(where_values)
44
47
  keys = where_values.collect do |k, v|
45
- v = Digest::MD5.hexdigest(v) if v && v.size >= 32
48
+ v = Digest::MD5.hexdigest(v) if v.respond_to?(:size) && v.size >= 32
46
49
  [k, v].join("_")
47
50
  end
48
51
 
49
52
  ext_key = keys.join(",")
50
53
  "uniq_key_#{name}_#{ext_key}"
51
54
  end
55
+
56
+ def compare_record_attributes_with_where_values(record, where_values)
57
+ return false unless record
58
+ where_values.all? do |k, v|
59
+ attribute_value = record.read_attribute(k)
60
+ attribute_value == case attribute_value
61
+ when String
62
+ v.to_s
63
+ when Numeric
64
+ v.to_f
65
+ when Date
66
+ v.to_date
67
+ else # Maybe NilClass/?
68
+ v
69
+ end
70
+ end
71
+ end
52
72
  end
53
73
  end
54
74
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecondLevelCache
4
- VERSION = "2.5.2"
4
+ VERSION = "2.5.3"
5
5
  end
@@ -76,6 +76,16 @@ module ActiveRecordTestCaseHelper
76
76
  model.column_names.include?(column_name.to_s)
77
77
  end
78
78
 
79
+ def savepoint
80
+ if ActiveRecord::Base.connection.supports_savepoints?
81
+ ActiveRecord::Base.connection.begin_transaction(joinable: false)
82
+ yield
83
+ ActiveRecord::Base.connection.rollback_transaction
84
+ else
85
+ yield
86
+ end
87
+ end
88
+
79
89
  class SQLCounter
80
90
  class << self
81
91
  attr_accessor :ignored_sql, :log, :log_all
@@ -14,6 +14,18 @@ class FetchByUinqKeyTest < ActiveSupport::TestCase
14
14
  assert_equal User.send(:cache_uniq_key, foo: 1, bar: nil), "uniq_key_User_foo_1,bar_"
15
15
  long_val = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
16
16
  assert_equal User.send(:cache_uniq_key, foo: 1, bar: long_val), "uniq_key_User_foo_1,bar_#{Digest::MD5.hexdigest(long_val)}"
17
+ assert Contribution.send(:cache_uniq_key, user_id: 1, date: Time.current.to_date), "uniq_key_Contribution_user_id_1,date_#{Time.current.to_date}"
18
+ end
19
+
20
+ def test_compare_record_attributes_with_where_values
21
+ book = Book.new(title: "foobar")
22
+ assert Book.send(:compare_record_attributes_with_where_values, book, title: :foobar)
23
+ book.discount_percentage = 60.00
24
+ assert Book.send(:compare_record_attributes_with_where_values, book, discount_percentage: "60")
25
+ book.publish_date = Time.current.to_date
26
+ assert Book.send(:compare_record_attributes_with_where_values, book, publish_date: Time.current.to_date.to_s)
27
+ book.title = nil
28
+ assert Book.send(:compare_record_attributes_with_where_values, book, title: nil)
17
29
  end
18
30
 
19
31
  def test_should_query_from_db_using_primary_key
@@ -51,4 +63,31 @@ class FetchByUinqKeyTest < ActiveSupport::TestCase
51
63
  user = User.fetch_by_uniq_key(@user.name, :name)
52
64
  assert_equal user, @user
53
65
  end
66
+
67
+ def test_should_return_correct_when_destroy_old_record_and_create_same_new_record
68
+ savepoint do
69
+ uniq_key = { email: "#{Time.now.to_i}@foobar.com" }
70
+ old_user = User.create(uniq_key)
71
+ new_user = old_user.deep_dup
72
+ assert_equal old_user, User.fetch_by_uniq_keys(uniq_key)
73
+ old_user.destroy
74
+
75
+ # Dirty id cache should be removed
76
+ assert_queries(2) { assert_nil User.fetch_by_uniq_keys(uniq_key) }
77
+ assert_queries(1) { assert_nil User.fetch_by_uniq_keys(uniq_key) }
78
+
79
+ new_user.save
80
+ assert_equal new_user, User.fetch_by_uniq_keys(uniq_key)
81
+ end
82
+ end
83
+
84
+ def test_should_return_correct_when_old_record_modify_uniq_key_and_new_record_use_same_uniq_key
85
+ savepoint do
86
+ uniq_key = { email: @user.email }
87
+ assert_equal @user, User.fetch_by_uniq_keys(uniq_key)
88
+ @user.update_attribute(:email, "#{Time.now.to_i}@foobar.com")
89
+ new_user = User.create(uniq_key)
90
+ assert_equal new_user, User.fetch_by_uniq_keys(uniq_key)
91
+ end
92
+ end
54
93
  end
@@ -4,7 +4,9 @@ ActiveRecord::Base.connection.create_table(:books, force: true) do |t|
4
4
  t.string :title
5
5
  t.string :body
6
6
  t.integer :user_id
7
+ t.decimal :discount_percentage, precision: 5, scale: 2
7
8
  t.integer :images_count, default: 0
9
+ t.date :publish_date
8
10
  end
9
11
 
10
12
  class Book < ActiveRecord::Base
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActiveRecord::Base.connection.create_table(:contributions, force: true) do |t|
4
+ t.integer :user_id
5
+ t.text :data
6
+ t.date :date
7
+ end
8
+
9
+ class Contribution < ActiveRecord::Base
10
+ second_level_cache
11
+
12
+ validates_uniqueness_of :user_id, scope: :date, if: -> { user_id_changed? || date_changed? }
13
+ belongs_to :user
14
+ end
@@ -25,6 +25,7 @@ require "model/order"
25
25
  require "model/order_item"
26
26
  require "model/account"
27
27
  require "model/animal"
28
+ require "model/contribution"
28
29
 
29
30
  DatabaseCleaner[:active_record].strategy = :truncation
30
31
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: second_level_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.2
4
+ version: 2.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hooopo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-02 00:00:00.000000000 Z
11
+ date: 2020-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -144,6 +144,7 @@ files:
144
144
  - test/model/account.rb
145
145
  - test/model/animal.rb
146
146
  - test/model/book.rb
147
+ - test/model/contribution.rb
147
148
  - test/model/image.rb
148
149
  - test/model/order.rb
149
150
  - test/model/order_item.rb
@@ -201,6 +202,7 @@ test_files:
201
202
  - test/model/image.rb
202
203
  - test/model/account.rb
203
204
  - test/model/order_item.rb
205
+ - test/model/contribution.rb
204
206
  - test/model/book.rb
205
207
  - test/model/topic.rb
206
208
  - test/model/animal.rb