second_level_cache 2.2.6 → 2.3.0.beta

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