second_level_cache 1.5.1 → 1.6.0

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