second_level_cache 1.5.1 → 1.6.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.
data/CHANGELOG.md CHANGED
@@ -34,3 +34,8 @@
34
34
  -----
35
35
  * [use new marshal machanism to avoid clear assocation cache manually]
36
36
 
37
+ 1.6.0
38
+ -----
39
+ * [write through cache]
40
+ * [disable SecondLevelCache for spicial model]
41
+ * [only cache `SELECT *` query]
data/README.md CHANGED
@@ -15,7 +15,7 @@ SecondLevelCache is not fully test and verify in production enviroment right now
15
15
  In your gem file:
16
16
 
17
17
  ```ruby
18
- gem "second_level_cache", :git => "git://github.com/csdn-dev/second_level_cache.git"
18
+ gem "second_level_cache", "~> 1.5"
19
19
  ```
20
20
 
21
21
  ## Usage
@@ -24,7 +24,7 @@ For example, cache User objects:
24
24
 
25
25
  ```ruby
26
26
  class User < ActiveRecord::Base
27
- acts_as_cached
27
+ acts_as_cached(:version => 1, :expires_in => 1.week)
28
28
  end
29
29
  ```
30
30
 
@@ -37,7 +37,8 @@ User.find_by_id!(1)
37
37
  User.find_by_id_and_name(1, "Hooopo")
38
38
  User.where(:status => 1).find_by_id(1)
39
39
  user.articles.find_by_id(1)
40
- user.articles.find(1), user.where(:status => 1).find(1)
40
+ user.articles.find(1)
41
+ User.where(:status => 1).find(1)
41
42
  article.user
42
43
  ```
43
44
 
@@ -45,7 +46,23 @@ Cache key:
45
46
 
46
47
  ```ruby
47
48
  user = User.find 1
48
- user.second_level_cache_key # We will get the key looks like "slc/user/1"
49
+ user.second_level_cache_key # We will get the key looks like "slc/user/1/0"
50
+ ```
51
+
52
+ Disable SecondLevelCache:
53
+
54
+ ```ruby
55
+ User.without_second_level_cache do
56
+ user = User.find 1
57
+ # ...
58
+ end
59
+ ```
60
+
61
+ Only `SELECT *` query will be cached:
62
+
63
+ ```ruby
64
+ # this query will NOT be cached
65
+ User.select("id, name").find(1)
49
66
  ```
50
67
 
51
68
  Notice:
@@ -5,8 +5,9 @@ module SecondLevelCache
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- after_destroy :expire_second_level_cache
9
- after_save :expire_second_level_cache
8
+ after_commit :expire_second_level_cache, :on => :destroy
9
+ after_commit :update_second_level_cache, :on => :update
10
+ after_commit :write_second_level_cache, :on => :create
10
11
 
11
12
  class << self
12
13
  alias_method_chain :update_counters, :cache
@@ -16,8 +17,9 @@ module SecondLevelCache
16
17
 
17
18
  module ClassMethods
18
19
  def update_counters_with_cache(id, counters)
19
- Array(id).each{|i| expire_second_level_cache(i)}
20
- update_counters_without_cache(id, counters)
20
+ update_counters_without_cache(id, counters).tap do
21
+ Array(id).each{|i| expire_second_level_cache(i)}
22
+ end
21
23
  end
22
24
  end
23
25
  end
@@ -27,6 +27,7 @@ module SecondLevelCache
27
27
  # Article.where("user_id = 1 AND ...").find(params[:id])
28
28
  def find_one_with_second_level_cache(id)
29
29
  return find_one_without_second_level_cache(id) unless second_level_cache_enabled?
30
+ return find_one_without_second_level_cache(id) unless select_all_column?
30
31
 
31
32
  id = id.id if ActiveRecord::Base === id
32
33
  if ::ActiveRecord::IdentityMap.enabled? && cachable? && record = from_identity_map(id)
@@ -51,6 +52,7 @@ module SecondLevelCache
51
52
  # TODO cache find_or_create_by_id
52
53
  def find_by_attributes_with_second_level_cache(match, attributes, *args)
53
54
  return find_by_attributes_without_second_level_cache(match, attributes, *args) unless second_level_cache_enabled?
55
+ return find_by_attributes_without_second_level_cache(match, attributes, *args) unless select_all_column?
54
56
 
55
57
  conditions = Hash[attributes.map {|a| [a, args[attributes.index(a)]]}]
56
58
 
@@ -101,6 +103,10 @@ module SecondLevelCache
101
103
  limit_value.blank? || limit_value == 1
102
104
  end
103
105
 
106
+ def select_all_column?
107
+ select_values.blank?
108
+ end
109
+
104
110
  def from_identity_map(id)
105
111
  ::ActiveRecord::IdentityMap.get(@klass, id)
106
112
  end
@@ -13,18 +13,15 @@ module SecondLevelCache
13
13
  end
14
14
 
15
15
  def update_column_with_second_level_cache(name, value)
16
- expire_second_level_cache
17
- update_column_without_second_level_cache(name, value)
16
+ update_column_without_second_level_cache(name, value).tap{update_second_level_cache}
18
17
  end
19
18
 
20
19
  def reload_with_second_level_cache(options = nil)
21
- expire_second_level_cache
22
- reload_without_second_level_cache(options)
20
+ reload_without_second_level_cache(options).tap{expire_second_level_cache}
23
21
  end
24
22
 
25
23
  def touch_with_second_level_cache(name = nil)
26
- expire_second_level_cache
27
- touch_without_second_level_cache(name)
24
+ touch_without_second_level_cache(name).tap{update_second_level_cache}
28
25
  end
29
26
  end
30
27
  end
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module SecondLevelCache
3
- VERSION = "1.5.1"
3
+ VERSION = "1.6.0"
4
4
  end
@@ -29,6 +29,14 @@ module SecondLevelCache
29
29
  !!@second_level_cache_enabled
30
30
  end
31
31
 
32
+ def without_second_level_cache
33
+ old, @second_level_cache_enabled = @second_level_cache_enabled, false
34
+
35
+ yield if block_given?
36
+ ensure
37
+ @second_level_cache_enabled = old
38
+ end
39
+
32
40
  def cache_store
33
41
  Config.cache_store
34
42
  end
@@ -71,6 +79,8 @@ module SecondLevelCache
71
79
  SecondLevelCache.cache_store.write(second_level_cache_key, RecordMarshal.dump(self), :expires_in => self.class.second_level_cache_options[:expires_in])
72
80
  end
73
81
  end
82
+
83
+ alias update_second_level_cache write_second_level_cache
74
84
  end
75
85
  end
76
86
 
@@ -6,14 +6,14 @@ class ActiveRecord::BaseTest < Test::Unit::TestCase
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  end
8
8
 
9
- def test_should_expire_cache_when_update_attributes
9
+ def test_should_update_cache_when_update_attributes
10
10
  @user.update_attributes :name => 'change'
11
- assert_nil User.read_second_level_cache(@user.id)
11
+ assert_equal @user.name, User.read_second_level_cache(@user.id).name
12
12
  end
13
13
 
14
- def test_should_expire_cache_when_update_attribute
14
+ def test_should_update_cache_when_update_attribute
15
15
  @user.update_attribute :name, 'change'
16
- assert_nil Post.read_second_level_cache(@user.id)
16
+ assert_equal @user.name, User.read_second_level_cache(@user.id).name
17
17
  end
18
18
 
19
19
  def test_should_expire_cache_when_destroy
@@ -24,4 +24,21 @@ class ActiveRecord::FinderMethodsTest < Test::Unit::TestCase
24
24
  assert_equal @user, User.where(:name => @user.name).find(@user.id)
25
25
  end
26
26
  end
27
+
28
+ def test_should_NOT_find_from_cache_when_select_speical_columns
29
+ @user.write_second_level_cache
30
+ only_id_user = User.select("id").find(@user.id)
31
+ assert_raise(ActiveModel::MissingAttributeError) do
32
+ only_id_user.name
33
+ end
34
+ end
35
+
36
+ def test_without_second_level_cache
37
+ @user.name = "NewName"
38
+ @user.write_second_level_cache
39
+ User.without_second_level_cache do
40
+ @from_db = User.find(@user.id)
41
+ end
42
+ assert_not_equal @user.name, @from_db.name
43
+ end
27
44
  end
@@ -4,6 +4,7 @@ ActiveRecord::Base.connection.create_table(:users, :force => true) do |t|
4
4
  t.string :email
5
5
  t.integer :books_count, :default => 0
6
6
  t.integer :images_count, :default => 0
7
+ t.timestamps
7
8
  end
8
9
 
9
10
  class User < ActiveRecord::Base
@@ -13,12 +13,18 @@ class ActiveRecord::PersistenceTest < Test::Unit::TestCase
13
13
  assert_equal 1, @user.reload.books_count
14
14
  end
15
15
 
16
- def test_should_clean_cache_after_touch
17
- post = @topic.posts.create
18
- post.body = "body"
19
- post.save
20
- new_topic = Topic.find @topic.id
21
- assert !(new_topic.updated_at == @topic.updated_at)
16
+ def test_should_update_cache_after_touch
17
+ old_updated_time = @user.updated_at
18
+ @user.touch
19
+ assert !(old_updated_time == @user.updated_at)
20
+ new_user = User.find @user.id
21
+ assert_equal new_user, @user
22
+ end
23
+
24
+ def test_should_update_cache_after_update_column
25
+ @user.update_column :name, "new_name"
26
+ new_user = User.find @user.id
27
+ assert_equal new_user, @user
22
28
  end
23
29
 
24
30
  def test_should_return_true_if_touch_ok
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: second_level_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-30 00:00:00.000000000 Z
12
+ date: 2012-10-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport