second_level_cache 2.2.6 → 2.3.0.beta

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
  SHA1:
3
- metadata.gz: 9040d6157f9c761c4b806764f7007b44f6c9c483
4
- data.tar.gz: bd364513a045cd7817b4fa7b9b86d5a0e2a6e93c
3
+ metadata.gz: 98025234cd167d1057980109b910f6988747877b
4
+ data.tar.gz: 40f729aac59034003e7f6404321f47bfd8f67a55
5
5
  SHA512:
6
- metadata.gz: 1e1970b11a1dcb57cba266b95f71680f01bafafab459f91feb950ccee18a628eeb40563867f8c9f6bbf6a898fe7ad089186dabde46f4779c3989dda1b0d7b301
7
- data.tar.gz: 7894b59c9ecfcd52b5cb03bdbff19f9d6a088c490d34453a6170793a03171e703233e2f5a543d4037279726e80f8a4ac6699b62822c0e07ea8c59cfb0e145476
6
+ metadata.gz: fb1d412af6f56f3e20938b4744f0a48b3d18abc4a556847001edf4a1fa13aaabb9ece974fa9d11720177f011970c3f085d0fd984e920bf21b4b9018dac47b01e
7
+ data.tar.gz: dcec779ee5c1733a03b8058a3a7dc243ce33698af648e583d4ce118a879032f36f1da961da1a61c096edded58ccbdddb77bc44c812557f57fa3898460a919353
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ 2.2.7
2
+ -----
3
+
4
+ * Use `second_level_cache` instead of `acts_as_cached` method to setup in model. (#56)
5
+
6
+ 2.2.6
7
+ -----
8
+
9
+ * Fix warning in Ruby 2.4.0. (#54)
10
+
1
11
  2.2.5
2
12
  -----
3
13
 
data/README.md CHANGED
@@ -40,7 +40,7 @@ For example, cache User objects:
40
40
 
41
41
  ```ruby
42
42
  class User < ActiveRecord::Base
43
- acts_as_cached(version: 1, expires_in: 1.week)
43
+ second_level_cache expires_in: 1.week
44
44
  end
45
45
  ```
46
46
 
@@ -67,7 +67,9 @@ Expires cache:
67
67
  user = User.find(1)
68
68
  user.expire_second_level_cache
69
69
  ```
70
+
70
71
  or expires cache using class method:
72
+
71
73
  ```ruby
72
74
  User.expire_second_level_cache(1)
73
75
  ```
@@ -97,15 +99,15 @@ User.select("id, name").find(1)
97
99
  ```ruby
98
100
  # user and account's write_second_level_cache operation will invoke after the logger.
99
101
  ActiveRecord::Base.transaction do
100
- user.save
101
- account.save
102
- Rails.logger.info "info"
102
+ user.save
103
+ account.save
104
+ Rails.logger.info "info"
103
105
  end # <- Cache write
104
106
 
105
107
  # if you want to do something after user and account's write_second_level_cache operation, do this way:
106
108
  ActiveRecord::Base.transaction do
107
- user.save
108
- account.save
109
+ user.save
110
+ account.save
109
111
  end # <- Cache write
110
112
  Rails.logger.info "info"
111
113
  ```
@@ -119,8 +121,9 @@ DatabaseCleaner.strategy = :truncation
119
121
  ## Configure
120
122
 
121
123
  In production env, we recommend to use [Dalli](https://github.com/mperham/dalli) as Rails cache store.
124
+
122
125
  ```ruby
123
- config.cache_store = [:dalli_store, APP_CONFIG["memcached_host"], { namespace: "ns", compress: true }]
126
+ config.cache_store = [:dalli_store, APP_CONFIG["memcached_host"], { namespace: "ns", compress: true }]
124
127
  ```
125
128
 
126
129
  ## Tips:
@@ -131,15 +134,17 @@ you can only change the `cache_key_prefix`:
131
134
  ```ruby
132
135
  SecondLevelCache.configure.cache_key_prefix = "slc1"
133
136
  ```
134
- * When schema of your model changed, just change the `version` of the speical model, avoding clear all the cache.
137
+
138
+ * SecondLevelCache was added model schema digest as cache version, this means when you add/remove/change columns, the caches of this Model will expires.
139
+ * When your want change the model cache version by manualy, just add the `version` option like this:
135
140
 
136
141
  ```ruby
137
142
  class User < ActiveRecord::Base
138
- acts_as_cached(version: 2, expires_in: 1.week)
143
+ second_level_cache version: 2, expires_in: 1.week
139
144
  end
140
145
  ```
141
146
 
142
- * It provides a great feature, not hits db when fetching record via unique key(not primary key).
147
+ * It provides a great feature, not hits db when fetching record via unique key (not primary key).
143
148
 
144
149
  ```ruby
145
150
  # this will fetch from cache
@@ -156,6 +161,7 @@ user = User.fetch_by_uniq_keys!(nick_name: "hooopo") # this will raise `ActiveRe
156
161
  Answer.includes(:question).limit(10).order("id DESC").each{|answer| answer.question.title}
157
162
  Answer Load (0.2ms) SELECT `answers`.* FROM `answers` ORDER BY id DESC LIMIT 10 # Only one SQL query and one Rails.cache.read_multi fetching operation.
158
163
  ```
164
+
159
165
  [Details for read_multi feature](http://hooopo.writings.io/articles/a9cae5e0).
160
166
 
161
167
  ## Contributors
@@ -21,7 +21,7 @@ module SecondLevelCache
21
21
  end
22
22
 
23
23
  def fetch_by_uniq_keys!(where_values)
24
- fetch_by_uniq_keys(where_values) || fail(::ActiveRecord::RecordNotFound)
24
+ fetch_by_uniq_keys(where_values) || raise(::ActiveRecord::RecordNotFound)
25
25
  end
26
26
 
27
27
  def fetch_by_uniq_key(value, uniq_key_name)
@@ -33,7 +33,7 @@ module SecondLevelCache
33
33
  def fetch_by_uniq_key!(value, uniq_key_name)
34
34
  # puts "[Deprecated] will remove in the future,
35
35
  # use fetch_by_uniq_keys! method instead."
36
- fetch_by_uniq_key(value, uniq_key_name) || fail(::ActiveRecord::RecordNotFound)
36
+ fetch_by_uniq_key(value, uniq_key_name) || raise(::ActiveRecord::RecordNotFound)
37
37
  end
38
38
 
39
39
  private
@@ -31,6 +31,9 @@ module RecordMarshal
31
31
  next if attributes[name].nil? || attributes[name].is_a?(String)
32
32
  if coder.is_a?(::ActiveRecord::Coders::YAMLColumn)
33
33
  attributes[name] = coder.dump(attributes[name]) if attributes[name].is_a?(coder.object_class)
34
+ elsif coder.is_a?(::ActiveRecord::Store::IndifferentCoder)
35
+ # https://github.com/rails/rails/blob/5b14129/activerecord/lib/active_record/store.rb#L179
36
+ attributes[name] = coder.dump(attributes[name])
34
37
  elsif coder == ::ActiveRecord::Coders::JSON
35
38
  attributes[name] = attributes[name].to_json
36
39
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module SecondLevelCache
3
- VERSION = '2.2.6'.freeze
3
+ VERSION = '2.3.0.beta'.freeze
4
4
  end
@@ -20,11 +20,11 @@ module SecondLevelCache
20
20
 
21
21
  delegate :logger, :cache_store, :cache_key_prefix, to: SecondLevelCache
22
22
 
23
- def acts_as_cached(options = {})
23
+ def second_level_cache(options = {})
24
24
  @second_level_cache_enabled = true
25
25
  @second_level_cache_options = options
26
- @second_level_cache_options[:expires_in] ||= 1.week
27
26
  @second_level_cache_options[:version] ||= 0
27
+ @second_level_cache_options[:expires_in] ||= 1.week
28
28
  relation.class.send :prepend, SecondLevelCache::ActiveRecord::FinderMethods
29
29
  prepend SecondLevelCache::ActiveRecord::Core
30
30
  end
@@ -46,8 +46,15 @@ module SecondLevelCache
46
46
  @second_level_cache_enabled = old
47
47
  end
48
48
 
49
+ # Get MD5 digest of this Model schema
50
+ # http://api.rubyonrails.org/classes/ActiveRecord/Core/ClassMethods.html#method-i-inspect
49
51
  def cache_version
50
- second_level_cache_options[:version]
52
+ return @cache_version if defined? @cache_version
53
+ # This line is copy from:
54
+ # https://github.com/rails/rails/blob/f9a5f48/activerecord/lib/active_record/core.rb#L236
55
+ attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ', '
56
+ model_schema_digest = Digest::MD5.hexdigest(attr_list)
57
+ @cache_version = "#{second_level_cache_options[:version]}/#{model_schema_digest}"
51
58
  end
52
59
 
53
60
  def second_level_cache_key(id)
@@ -37,5 +37,5 @@ Gem::Specification.new do |gem|
37
37
  gem.add_development_dependency 'rake'
38
38
  gem.add_development_dependency 'pry'
39
39
  gem.add_development_dependency 'database_cleaner', '~> 1.3.0'
40
- gem.add_development_dependency 'rubocop', '~> 0.36.0'
40
+ gem.add_development_dependency 'rubocop'
41
41
  end
@@ -6,6 +6,6 @@ ActiveRecord::Base.connection.create_table(:accounts, force: true) do |t|
6
6
  end
7
7
 
8
8
  class Account < ActiveRecord::Base
9
- acts_as_cached expires_in: 3.days
9
+ second_level_cache expires_in: 3.days
10
10
  belongs_to :user
11
11
  end
data/test/model/animal.rb CHANGED
@@ -5,9 +5,9 @@ ActiveRecord::Base.connection.create_table(:animals, force: true) do |t|
5
5
  end
6
6
 
7
7
  class Animal < ActiveRecord::Base
8
- acts_as_cached
8
+ second_level_cache
9
9
  end
10
10
 
11
11
  class Dog < Animal
12
- acts_as_cached
12
+ second_level_cache
13
13
  end
data/test/model/book.rb CHANGED
@@ -6,7 +6,7 @@ ActiveRecord::Base.connection.create_table(:books, force: true) do |t|
6
6
  end
7
7
 
8
8
  class Book < ActiveRecord::Base
9
- acts_as_cached
9
+ second_level_cache
10
10
 
11
11
  belongs_to :user, counter_cache: true
12
12
  has_many :images, as: :imagable
data/test/model/image.rb CHANGED
@@ -5,7 +5,7 @@ ActiveRecord::Base.connection.create_table(:images, force: true) do |t|
5
5
  end
6
6
 
7
7
  class Image < ActiveRecord::Base
8
- acts_as_cached
8
+ second_level_cache
9
9
 
10
10
  belongs_to :imagable, polymorphic: true, counter_cache: true
11
11
  end
data/test/model/post.rb CHANGED
@@ -5,6 +5,6 @@ ActiveRecord::Base.connection.create_table(:posts, force: true) do |t|
5
5
  end
6
6
 
7
7
  class Post < ActiveRecord::Base
8
- acts_as_cached
8
+ second_level_cache
9
9
  belongs_to :topic, touch: true
10
10
  end
data/test/model/topic.rb CHANGED
@@ -6,7 +6,7 @@ ActiveRecord::Base.connection.create_table(:topics, force: true) do |t|
6
6
  end
7
7
 
8
8
  class Topic < ActiveRecord::Base
9
- acts_as_cached
9
+ second_level_cache
10
10
 
11
11
  has_many :posts
12
12
  end
data/test/model/user.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  ActiveRecord::Base.connection.create_table(:users, force: true) do |t|
2
2
  t.text :options
3
3
  t.text :json_options
4
+ t.text :extras
4
5
  t.string :name, unique: true
5
6
  t.string :email
6
7
  t.integer :status, default: 0
@@ -24,9 +25,12 @@ end
24
25
 
25
26
  class User < ActiveRecord::Base
26
27
  CACHE_VERSION = 3
28
+ second_level_cache(version: CACHE_VERSION, expires_in: 3.days)
29
+
27
30
  serialize :options, Array
28
31
  serialize :json_options, JSON if ::ActiveRecord::VERSION::STRING >= '4.1.0'
29
- acts_as_cached(version: CACHE_VERSION, expires_in: 3.days)
32
+ store :extras, accessors: [:tagline, :gender]
33
+
30
34
  has_one :account
31
35
  has_one :forked_user_link, foreign_key: 'forked_to_user_id'
32
36
  has_one :forked_from_user, through: :forked_user_link
@@ -39,7 +43,7 @@ class User < ActiveRecord::Base
39
43
  end
40
44
 
41
45
  class Namespace < ActiveRecord::Base
42
- acts_as_cached version: 1, expires_in: 3.days
46
+ second_level_cache version: 1, expires_in: 3.days
43
47
 
44
48
  belongs_to :user
45
49
  end
@@ -4,14 +4,17 @@ class RecordMarshalTest < ActiveSupport::TestCase
4
4
  def setup
5
5
  if ::ActiveRecord::VERSION::STRING >= '4.1.0'
6
6
  @json_options = { 'name' => 'Test', 'age' => 18, 'hash' => { 'name' => 'dup' } }
7
+ @extras = { 'tagline' => 'Hello world', 'gender' => 1 }
7
8
  @user = User.create name: 'csdn',
8
9
  email: 'test@csdn.com',
9
10
  options: [1, 2],
11
+ extras: @extras,
10
12
  json_options: @json_options,
11
13
  status: :active
12
14
  else
13
15
  @user = User.create name: 'csdn',
14
16
  email: 'test@csdn.com',
17
+ extras: @extras,
15
18
  options: [1, 2]
16
19
  end
17
20
  end
@@ -30,6 +33,9 @@ class RecordMarshalTest < ActiveSupport::TestCase
30
33
  assert_equal Array, User.read_second_level_cache(@user.id).reload.options.class
31
34
  assert_equal User.read_second_level_cache(@user.id).changed?, false
32
35
  assert_equal [1, 2], User.read_second_level_cache(@user.id).options
36
+ assert_equal @extras, User.read_second_level_cache(@user.id).extras
37
+ assert_equal 'Hello world', User.read_second_level_cache(@user.id).tagline
38
+ assert_equal 1, User.read_second_level_cache(@user.id).gender
33
39
  if ::ActiveRecord::VERSION::STRING >= '4.1.0'
34
40
  result = User.read_second_level_cache(@user.id)
35
41
  assert_equal @json_options['name'], result.json_options['name']
@@ -6,7 +6,10 @@ class SecondLevelCacheTest < ActiveSupport::TestCase
6
6
  end
7
7
 
8
8
  def test_should_get_cache_key
9
- assert_equal "slc/users/#{@user.id}/#{User::CACHE_VERSION}", @user.second_level_cache_key
9
+ attr_list = User.attribute_types.map { |name, type| "#{name}: #{type.type}" } * ', '
10
+ table_digest = Digest::MD5.hexdigest(attr_list)
11
+ refute_nil table_digest
12
+ assert_equal "slc/users/#{@user.id}/#{User::CACHE_VERSION}/#{table_digest}", @user.second_level_cache_key
10
13
  end
11
14
 
12
15
  def test_should_write_and_read_cache
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.2.6
4
+ version: 2.3.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hooopo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-27 00:00:00.000000000 Z
11
+ date: 2017-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -110,16 +110,16 @@ dependencies:
110
110
  name: rubocop
111
111
  requirement: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - "~>"
113
+ - - ">="
114
114
  - !ruby/object:Gem::Version
115
- version: 0.36.0
115
+ version: '0'
116
116
  type: :development
117
117
  prerelease: false
118
118
  version_requirements: !ruby/object:Gem::Requirement
119
119
  requirements:
120
- - - "~>"
120
+ - - ">="
121
121
  - !ruby/object:Gem::Version
122
- version: 0.36.0
122
+ version: '0'
123
123
  description: Write Through and Read Through caching library inspired by CacheMoney
124
124
  and cache_fu, support ActiveRecord 4.
125
125
  email:
@@ -184,9 +184,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
184
184
  version: '0'
185
185
  required_rubygems_version: !ruby/object:Gem::Requirement
186
186
  requirements:
187
- - - ">="
187
+ - - ">"
188
188
  - !ruby/object:Gem::Version
189
- version: '0'
189
+ version: 1.3.1
190
190
  requirements: []
191
191
  rubyforge_project:
192
192
  rubygems_version: 2.5.1