second_level_cache 1.3.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -17,3 +17,14 @@
17
17
  1.3.2
18
18
  -----
19
19
  * [fix has one assciation issue]
20
+
21
+ 1.4.0
22
+ -----
23
+ * [cache has one assciation]
24
+
25
+ 1.4.1
26
+ -----
27
+ * [fix errors when belongs_to association return nil]
28
+
29
+ 1.5.0
30
+ * [add cache version to quick clear cache for special model]
@@ -22,6 +22,7 @@ module SecondLevelCache
22
22
  @second_level_cache_enabled = true
23
23
  @second_level_cache_options = options
24
24
  @second_level_cache_options[:expires_in] ||= 1.day
25
+ @second_level_cache_options[:version] ||= 0
25
26
  end
26
27
 
27
28
  def second_level_cache_enabled?
@@ -40,8 +41,12 @@ module SecondLevelCache
40
41
  Config.cache_key_prefix
41
42
  end
42
43
 
44
+ def cache_version
45
+ second_level_cache_options[:version]
46
+ end
47
+
43
48
  def second_level_cache_key(id)
44
- "#{cache_key_prefix}/#{name.downcase}/#{id}"
49
+ "#{cache_key_prefix}/#{name.downcase}/#{id}/#{cache_version}"
45
50
  end
46
51
 
47
52
  def read_second_level_cache(id)
@@ -62,7 +67,10 @@ module SecondLevelCache
62
67
  end
63
68
 
64
69
  def write_second_level_cache
65
- SecondLevelCache.cache_store.write(second_level_cache_key, self, self.class.second_level_cache_options) if self.class.second_level_cache_enabled?
70
+ if self.class.second_level_cache_enabled?
71
+ self.clear_association_cache
72
+ SecondLevelCache.cache_store.write(second_level_cache_key, self, :expires_in => self.class.second_level_cache_options[:expires_in])
73
+ end
66
74
  end
67
75
  end
68
76
  end
@@ -1,11 +1,15 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'second_level_cache/active_record/base'
3
+ require 'second_level_cache/active_record/fetch_by_uniq_key'
3
4
  require 'second_level_cache/active_record/finder_methods'
4
5
  require 'second_level_cache/active_record/persistence'
5
6
  require 'second_level_cache/active_record/belongs_to_association'
7
+ require 'second_level_cache/active_record/has_one_association'
6
8
 
7
9
  ActiveRecord::Base.send(:include, SecondLevelCache::Mixin)
8
10
  ActiveRecord::Base.send(:include, SecondLevelCache::ActiveRecord::Base)
11
+ ActiveRecord::Base.send(:extend, SecondLevelCache::ActiveRecord::FetchByUniqKey)
9
12
  ActiveRecord::FinderMethods.send(:include, SecondLevelCache::ActiveRecord::FinderMethods)
10
13
  ActiveRecord::Base.send(:include, SecondLevelCache::ActiveRecord::Persistence)
11
14
  ActiveRecord::Associations::BelongsToAssociation.send(:include, SecondLevelCache::ActiveRecord::Associations::BelongsToAssociation)
15
+ ActiveRecord::Associations::HasOneAssociation.send(:include, SecondLevelCache::ActiveRecord::Associations::HasOneAssociation)
@@ -6,7 +6,7 @@ module SecondLevelCache
6
6
 
7
7
  included do
8
8
  after_destroy :expire_second_level_cache
9
- after_save :write_second_level_cache
9
+ after_save :expire_second_level_cache
10
10
 
11
11
  class << self
12
12
  alias_method_chain :update_counters, :cache
@@ -15,8 +15,11 @@ module SecondLevelCache
15
15
  cache_record = klass.read_second_level_cache(second_level_cache_key)
16
16
  return cache_record.tap{|record| set_inverse_instance(record)} if cache_record
17
17
  record = find_target_without_second_level_cache
18
- record.write_second_level_cache
19
- record
18
+
19
+ record.tap do |r|
20
+ set_inverse_instance(r)
21
+ r.write_second_level_cache
22
+ end if record
20
23
  end
21
24
 
22
25
  private
@@ -0,0 +1,25 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module SecondLevelCache
3
+ module ActiveRecord
4
+ module FetchByUniqKey
5
+ def fetch_by_uniq_key(value, uniq_key_name)
6
+ if iid = SecondLevelCache.cache_store.read(cache_uniq_key(value, uniq_key_name))
7
+ self.find_by_id(iid)
8
+ else
9
+ record = self.where(uniq_key_name => value).first
10
+ record.tap{|record| SecondLevelCache.cache_store.write(cache_uniq_key(value, uniq_key_name), record.id)} if record
11
+ end
12
+ end
13
+
14
+ def fetch_by_uniq_key!(value, uniq_key_name)
15
+ fetch_by_uniq_key(value, uniq_key_name) || raise(::ActiveRecord::RecordNotFound)
16
+ end
17
+
18
+ private
19
+
20
+ def cache_uniq_key(value, uniq_key_name)
21
+ "uniq_key_#{self.name}_#{uniq_key_name}_#{value}"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module SecondLevelCache
3
+ module ActiveRecord
4
+ module Associations
5
+ module HasOneAssociation
6
+ extend ActiveSupport::Concern
7
+ included do
8
+ class_eval do
9
+ alias_method_chain :find_target, :second_level_cache
10
+ end
11
+ end
12
+
13
+ def find_target_with_second_level_cache
14
+ return find_target_without_second_level_cache unless association_class.second_level_cache_enabled?
15
+ cache_record = association_class.fetch_by_uniq_key(owner[reflection.active_record_primary_key], reflection.foreign_key)
16
+ return cache_record.tap{|record| set_inverse_instance(record)} if cache_record
17
+
18
+ record = find_target_without_second_level_cache
19
+
20
+ record.tap do |r|
21
+ set_inverse_instance(r)
22
+ r.write_second_level_cache
23
+ end if record
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module SecondLevelCache
3
- VERSION = "1.3.2"
3
+ VERSION = "1.5.0"
4
4
  end
@@ -6,19 +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_have_cache_when_create
10
- no_connection do
11
- assert_not_nil User.read_second_level_cache(@user.id)
12
- assert_equal @user, User.find(@user.id)
13
- end
14
- end
15
-
16
- def test_should_update_cache_when_update
9
+ def test_should_expire_cache_when_update_attributes
17
10
  @user.update_attributes :name => 'change'
11
+ assert_nil User.read_second_level_cache(@user.id)
12
+ end
18
13
 
19
- no_connection do
20
- assert_equal 'change', User.find(@user.id).name
21
- end
14
+ def test_should_expire_cache_when_update_attribute
15
+ @user.update_attribute :name, 'change'
16
+ assert_nil Post.read_second_level_cache(@user.id)
22
17
  end
23
18
 
24
19
  def test_should_expire_cache_when_destroy
@@ -9,6 +9,8 @@ class ActiveRecord::BelongsToAssociationTest < Test::Unit::TestCase
9
9
  def test_should_get_cache_when_use_belongs_to_association
10
10
  book = @user.books.create
11
11
 
12
+ @user.write_second_level_cache
13
+ book.clear_association_cache
12
14
  no_connection do
13
15
  assert_equal @user, book.user
14
16
  end
@@ -12,12 +12,14 @@ class ActiveRecord::FinderMethodsTest < Test::Unit::TestCase
12
12
  end
13
13
 
14
14
  def test_should_find_with_cache
15
+ @user.write_second_level_cache
15
16
  no_connection do
16
17
  assert_equal @user, User.find(@user.id)
17
18
  end
18
19
  end
19
20
 
20
21
  def test_should_find_with_condition
22
+ @user.write_second_level_cache
21
23
  no_connection do
22
24
  assert_equal @user, User.where(:name => @user.name).find(@user.id)
23
25
  end
@@ -7,7 +7,8 @@ ActiveRecord::Base.connection.create_table(:users, :force => true) do |t|
7
7
  end
8
8
 
9
9
  class User < ActiveRecord::Base
10
- acts_as_cached
10
+ CacheVersion = 3
11
+ acts_as_cached(:version => CacheVersion, :expires_in => 3.day)
11
12
 
12
13
  has_many :books
13
14
  has_many :images, :as => :imagable
@@ -9,6 +9,8 @@ class ActiveRecord::PolymorphicAssociationTest < Test::Unit::TestCase
9
9
  def test_should_get_cache_when_use_polymorphic_association
10
10
  image = @user.images.create
11
11
 
12
+ @user.write_second_level_cache
13
+ image.clear_association_cache
12
14
  no_connection do
13
15
  assert_equal @user, image.imagable
14
16
  end
@@ -7,14 +7,13 @@ class ActiveRecord::SecondLevelCacheTest < Test::Unit::TestCase
7
7
  end
8
8
 
9
9
  def test_should_get_cache_key
10
- assert_equal "slc/user/#{@user.id}", @user.second_level_cache_key
10
+ assert_equal "slc/user/#{@user.id}/#{User::CacheVersion}", @user.second_level_cache_key
11
11
  end
12
12
 
13
13
  def test_should_write_and_read_cache
14
+ @user.write_second_level_cache
14
15
  assert_not_nil User.read_second_level_cache(@user.id)
15
16
  @user.expire_second_level_cache
16
17
  assert_nil User.read_second_level_cache(@user.id)
17
- @user.write_second_level_cache
18
- assert_not_nil User.read_second_level_cache(@user.id)
19
18
  end
20
19
  end
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.3.2
4
+ version: 1.5.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-19 00:00:00.000000000 Z
12
+ date: 2012-08-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -93,7 +93,9 @@ files:
93
93
  - lib/second_level_cache/active_record.rb
94
94
  - lib/second_level_cache/active_record/base.rb
95
95
  - lib/second_level_cache/active_record/belongs_to_association.rb
96
+ - lib/second_level_cache/active_record/fetch_by_uniq_key.rb
96
97
  - lib/second_level_cache/active_record/finder_methods.rb
98
+ - lib/second_level_cache/active_record/has_one_association.rb
97
99
  - lib/second_level_cache/active_record/persistence.rb
98
100
  - lib/second_level_cache/arel/wheres.rb
99
101
  - lib/second_level_cache/config.rb
@@ -125,12 +127,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
127
  - - ! '>='
126
128
  - !ruby/object:Gem::Version
127
129
  version: '0'
130
+ segments:
131
+ - 0
132
+ hash: -453317869
128
133
  required_rubygems_version: !ruby/object:Gem::Requirement
129
134
  none: false
130
135
  requirements:
131
136
  - - ! '>='
132
137
  - !ruby/object:Gem::Version
133
138
  version: '0'
139
+ segments:
140
+ - 0
141
+ hash: -453317869
134
142
  requirements: []
135
143
  rubyforge_project:
136
144
  rubygems_version: 1.8.24