second_level_cache 2.1.0.rc2 → 2.1.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.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -2
  3. data/README.md +1 -1
  4. data/lib/second_level_cache/active_record.rb +1 -1
  5. data/lib/second_level_cache/active_record/has_one_association.rb +5 -1
  6. data/lib/second_level_cache/active_record/persistence.rb +2 -1
  7. data/lib/second_level_cache/active_record/preloader.rb +5 -7
  8. data/lib/second_level_cache/version.rb +1 -1
  9. data/second_level_cache.gemspec +1 -1
  10. data/test/active_record_test_case_helper.rb +120 -0
  11. data/test/{active_record/base_test.rb → base_test.rb} +2 -2
  12. data/test/{active_record/belongs_to_association_test.rb → belongs_to_association_test.rb} +3 -3
  13. data/test/{active_record/fetch_by_uniq_key_test.rb → fetch_by_uniq_key_test.rb} +9 -9
  14. data/test/{active_record/finder_methods_test.rb → finder_methods_test.rb} +4 -4
  15. data/test/{active_record/has_one_association_test.rb → has_one_association_test.rb} +3 -3
  16. data/test/{active_record/model → model}/account.rb +0 -0
  17. data/test/{active_record/model → model}/book.rb +0 -0
  18. data/test/{active_record/model → model}/image.rb +0 -0
  19. data/test/{active_record/model → model}/post.rb +0 -0
  20. data/test/{active_record/model → model}/topic.rb +0 -0
  21. data/test/{active_record/model → model}/user.rb +0 -0
  22. data/test/{active_record/persistence_test.rb → persistence_test.rb} +7 -2
  23. data/test/{active_record/polymorphic_association_test.rb → polymorphic_association_test.rb} +3 -4
  24. data/test/preloader_test.rb +55 -0
  25. data/test/record_marshal_test.rb +2 -2
  26. data/test/require_test.rb +2 -2
  27. data/test/{active_record/second_level_cache_test.rb → second_level_cache_test.rb} +2 -2
  28. data/test/test_helper.rb +29 -4
  29. metadata +63 -75
  30. data/test/active_record/preloader_test.rb +0 -28
  31. data/test/active_record/test_helper.rb +0 -55
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 06b57d2d883c83e10d5b5b927b1666e92a84c6b1
4
+ data.tar.gz: 80c99a97b2b2753f98b886a6f4d50de61e6352ba
5
+ SHA512:
6
+ metadata.gz: eec1e049ea36e70c0d9c707efdb1aeda373c327b6b2be1082076619373c5d6b9bc782797dedd2cec2d4c52e947363282d4f1d3f3a43d12de7f2e2b96aff418f3
7
+ data.tar.gz: 9dd02f79e8312da7af052282a89ddca1328209ffe5b6b68f2815fd394bd6cbd9820fc6c4d862d89009324e5ccf2c748bdbc362726cabeb304daa9c0000ccc0ac
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in second_level_cache.gemspec
4
3
  gemspec
5
- gem 'rails', '4.1.0.rc1'
4
+
5
+ gem 'rails', '~> 4.0'
data/README.md CHANGED
@@ -17,7 +17,7 @@ Write-Through: As objects are created, updated, and deleted, all of the caches a
17
17
  In your gem file:
18
18
 
19
19
  ```ruby
20
- gem "second_level_cache", "~> 2.0.0.rc1"
20
+ gem "second_level_cache", "~> 2.1.0"
21
21
  ```
22
22
 
23
23
  For ActiveRecord 3:
@@ -14,4 +14,4 @@ ActiveRecord::Base.send(:extend, SecondLevelCache::ActiveRecord::FetchByUniqKey)
14
14
  ActiveRecord::Base.send(:include, SecondLevelCache::ActiveRecord::Persistence)
15
15
  ActiveRecord::Associations::BelongsToAssociation.send(:include, SecondLevelCache::ActiveRecord::Associations::BelongsToAssociation)
16
16
  ActiveRecord::Associations::HasOneAssociation.send(:include, SecondLevelCache::ActiveRecord::Associations::HasOneAssociation)
17
- ActiveRecord::Associations::Preloader::Association.send(:include, SecondLevelCache::ActiveRecord::Associations::Preloader::Association)
17
+ ActiveRecord::Associations::Preloader::BelongsTo.send(:include, SecondLevelCache::ActiveRecord::Associations::Preloader::BelongsTo)
@@ -12,7 +12,11 @@ module SecondLevelCache
12
12
 
13
13
  def find_target_with_second_level_cache
14
14
  return find_target_without_second_level_cache unless klass.second_level_cache_enabled?
15
- cache_record = klass.fetch_by_uniq_key(owner[reflection.active_record_primary_key], reflection.foreign_key)
15
+ if reflection.options[:as]
16
+ cache_record = klass.fetch_by_uniq_keys({reflection.foreign_key => owner[reflection.active_record_primary_key], reflection.type => owner.class.base_class.name})
17
+ else
18
+ cache_record = klass.fetch_by_uniq_key(owner[reflection.active_record_primary_key], reflection.foreign_key)
19
+ end
16
20
  return cache_record.tap{|record| set_inverse_instance(record)} if cache_record
17
21
 
18
22
  record = find_target_without_second_level_cache
@@ -17,7 +17,8 @@ module SecondLevelCache
17
17
  end
18
18
 
19
19
  def reload_with_second_level_cache(options = nil)
20
- reload_without_second_level_cache(options).tap{expire_second_level_cache}
20
+ expire_second_level_cache
21
+ reload_without_second_level_cache(options)
21
22
  end
22
23
 
23
24
  def touch_with_second_level_cache(name = nil)
@@ -3,13 +3,11 @@ module SecondLevelCache
3
3
  module ActiveRecord
4
4
  module Associations
5
5
  class Preloader
6
- module Association
6
+ module BelongsTo
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- class_eval do
11
- alias_method_chain :records_for, :second_level_cache
12
- end
10
+ alias_method_chain :records_for, :second_level_cache
13
11
  end
14
12
 
15
13
  def records_for_with_second_level_cache(ids)
@@ -17,9 +15,9 @@ module SecondLevelCache
17
15
 
18
16
  map_cache_keys = ids.map{|id| klass.second_level_cache_key(id)}
19
17
  records_from_cache = ::SecondLevelCache.cache_store.read_multi(*map_cache_keys)
20
- # NOTICE
18
+ # NOTICE
21
19
  # Rails.cache.read_multi return hash that has keys only hitted.
22
- # eg. Rails.cache.read_multi(1,2,3) => {2 => hit_value, 3 => hit_value}
20
+ # eg. Rails.cache.read_multi(1,2,3) => {2 => hit_value, 3 => hit_value}
23
21
  hitted_ids = records_from_cache.map{|key, _| key.split("/")[2].to_i}
24
22
  missed_ids = ids.map{|x| x.to_i} - hitted_ids
25
23
 
@@ -40,6 +38,6 @@ module SecondLevelCache
40
38
  end
41
39
  end
42
40
  end
43
- end
41
+ end
44
42
  end
45
43
  end
@@ -1,4 +1,4 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  module SecondLevelCache
3
- VERSION = "2.1.0.rc2"
3
+ VERSION = "2.1.0"
4
4
  end
@@ -35,5 +35,5 @@ Gem::Specification.new do |gem|
35
35
  gem.add_runtime_dependency "activerecord", ["> 4.0.0", "< 5.0"]
36
36
  gem.add_development_dependency "sqlite3"
37
37
  gem.add_development_dependency "rake"
38
- gem.add_development_dependency "database_cleaner", "~> 1.2.0"
38
+ gem.add_development_dependency "database_cleaner", "~> 1.3.0"
39
39
  end
@@ -0,0 +1,120 @@
1
+ require 'active_support/test_case'
2
+
3
+ module ActiveRecordTestCaseHelper
4
+ def teardown
5
+ SQLCounter.clear_log
6
+ end
7
+
8
+ def assert_date_from_db(expected, actual, message = nil)
9
+ assert_equal expected.to_s, actual.to_s, message
10
+ end
11
+
12
+ def capture(stream)
13
+ stream = stream.to_s
14
+ captured_stream = Tempfile.new(stream)
15
+ stream_io = eval("$#{stream}")
16
+ origin_stream = stream_io.dup
17
+ stream_io.reopen(captured_stream)
18
+
19
+ yield
20
+
21
+ stream_io.rewind
22
+ return captured_stream.read
23
+ ensure
24
+ captured_stream.close
25
+ captured_stream.unlink
26
+ stream_io.reopen(origin_stream)
27
+ end
28
+
29
+ def capture_sql
30
+ SQLCounter.clear_log
31
+ yield
32
+ SQLCounter.log_all.dup
33
+ end
34
+
35
+ def assert_sql(*patterns_to_match)
36
+ capture_sql { yield }
37
+ ensure
38
+ failed_patterns = []
39
+ patterns_to_match.each do |pattern|
40
+ failed_patterns << pattern unless SQLCounter.log_all.any?{ |sql| pattern === sql }
41
+ end
42
+ assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map{ |p| p.inspect }.join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}"
43
+ end
44
+
45
+ def assert_queries(num = 1, options = {})
46
+ ignore_none = options.fetch(:ignore_none) { num == :any }
47
+ SQLCounter.clear_log
48
+ x = yield
49
+ the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
50
+ if num == :any
51
+ assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
52
+ else
53
+ mesg = "#{the_log.size} instead of #{num} queries were executed.#{the_log.size == 0 ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
54
+ assert_equal num, the_log.size, mesg
55
+ end
56
+ x
57
+ end
58
+
59
+ def assert_no_queries(options = {}, &block)
60
+ options.reverse_merge! ignore_none: true
61
+ assert_queries(0, options, &block)
62
+ end
63
+
64
+ def assert_column(model, column_name, msg=nil)
65
+ assert has_column?(model, column_name), msg
66
+ end
67
+
68
+ def assert_no_column(model, column_name, msg=nil)
69
+ assert_not has_column?(model, column_name), msg
70
+ end
71
+
72
+ def has_column?(model, column_name)
73
+ model.reset_column_information
74
+ model.column_names.include?(column_name.to_s)
75
+ end
76
+
77
+ class SQLCounter
78
+ class << self
79
+ attr_accessor :ignored_sql, :log, :log_all
80
+ def clear_log; self.log = []; self.log_all = []; end
81
+ end
82
+
83
+ self.clear_log
84
+
85
+ self.ignored_sql = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/]
86
+
87
+ # FIXME: this needs to be refactored so specific database can add their own
88
+ # ignored SQL, or better yet, use a different notification for the queries
89
+ # instead examining the SQL content.
90
+ oracle_ignored = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im, /^\s*select .* from all_constraints/im, /^\s*select .* from all_tab_cols/im]
91
+ mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i, /^SHOW VARIABLES /]
92
+ postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select tablename\b.*from pg_tables\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
93
+ sqlite3_ignored = [/^\s*SELECT name\b.*\bFROM sqlite_master/im]
94
+
95
+ [oracle_ignored, mysql_ignored, postgresql_ignored, sqlite3_ignored].each do |db_ignored_sql|
96
+ ignored_sql.concat db_ignored_sql
97
+ end
98
+
99
+ attr_reader :ignore
100
+
101
+ def initialize(ignore = Regexp.union(self.class.ignored_sql))
102
+ @ignore = ignore
103
+ end
104
+
105
+ def call(name, start, finish, message_id, values)
106
+ sql = values[:sql]
107
+
108
+ # FIXME: this seems bad. we should probably have a better way to indicate
109
+ # the query was cached
110
+ return if 'CACHE' == values[:name]
111
+
112
+ self.class.log_all << sql
113
+ self.class.log << sql unless ignore =~ sql
114
+ end
115
+
116
+ ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new)
117
+ end
118
+ end
119
+
120
+ ActiveSupport::TestCase.send(:include, ActiveRecordTestCaseHelper)
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::BaseTest < Minitest::Test
4
+ class BaseTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  end
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::BelongsToAssociationTest < Minitest::Test
4
+ class BelongsToAssociationTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  end
@@ -11,7 +11,7 @@ class ActiveRecord::BelongsToAssociationTest < Minitest::Test
11
11
 
12
12
  @user.write_second_level_cache
13
13
  book.clear_association_cache
14
- no_connection do
14
+ assert_no_queries do
15
15
  assert_equal @user, book.user
16
16
  end
17
17
  end
@@ -1,9 +1,8 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::FetchByUinqKeyTest < Minitest::Test
4
+ class FetchByUinqKeyTest < ActiveSupport::TestCase
5
5
  def setup
6
- DatabaseCleaner[:active_record].start
7
6
  @user = User.create :name => 'hooopo', :email => 'hoooopo@gmail.com'
8
7
  @post = Post.create :slug => "foobar", :topic_id => 2
9
8
  end
@@ -17,15 +16,16 @@ class ActiveRecord::FetchByUinqKeyTest < Minitest::Test
17
16
 
18
17
  def test_should_query_from_db_using_primary_key
19
18
  Post.fetch_by_uniq_keys(:topic_id => 2, :slug => "foobar")
20
- $sql_logger = nil
21
- Post.fetch_by_uniq_keys(:topic_id => 2, :slug => "foobar")
22
- assert_equal $sql_logger.strip, 'SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1'
19
+ @post.expire_second_level_cache
20
+ assert_sql 'SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1' do
21
+ Post.fetch_by_uniq_keys(:topic_id => 2, :slug => "foobar")
22
+ end
23
23
  end
24
24
 
25
25
  def test_should_not_hit_db_using_fetch_by_uniq_key_twice
26
26
  post = Post.fetch_by_uniq_keys(:topic_id => 2, :slug => "foobar")
27
27
  assert_equal post, @post
28
- no_connection do
28
+ assert_no_queries do
29
29
  Post.fetch_by_uniq_keys(:topic_id => 2, :slug => "foobar")
30
30
  end
31
31
  end
@@ -34,12 +34,12 @@ class ActiveRecord::FetchByUinqKeyTest < Minitest::Test
34
34
  assert_raises(ActiveRecord::RecordNotFound) do
35
35
  Post.fetch_by_uniq_keys!(:topic_id => 2, :slug => "foobar1")
36
36
  end
37
-
37
+
38
38
  assert_raises(ActiveRecord::RecordNotFound) do
39
39
  User.fetch_by_uniq_key!("xxxxx", :name)
40
40
  end
41
41
  end
42
-
42
+
43
43
  def test_should_work_with_fetch_by_uniq_key
44
44
  user = User.fetch_by_uniq_key(@user.name, :name)
45
45
  assert_equal user, @user
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::FinderMethodsTest < Minitest::Test
4
+ class FinderMethodsTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  end
@@ -13,14 +13,14 @@ class ActiveRecord::FinderMethodsTest < Minitest::Test
13
13
 
14
14
  def test_should_find_with_cache
15
15
  @user.write_second_level_cache
16
- no_connection do
16
+ assert_no_queries do
17
17
  assert_equal @user, User.find(@user.id)
18
18
  end
19
19
  end
20
20
 
21
21
  def test_should_find_with_condition
22
22
  @user.write_second_level_cache
23
- no_connection do
23
+ assert_no_queries do
24
24
  assert_equal @user, User.where(:name => @user.name).find(@user.id)
25
25
  end
26
26
  end
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::HasOneAssociationTest < Minitest::Test
4
+ class HasOneAssociationTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'hooopo', :email => 'hoooopo@gmail.com'
7
7
  @account = @user.create_account
@@ -9,7 +9,7 @@ class ActiveRecord::HasOneAssociationTest < Minitest::Test
9
9
 
10
10
  def test_should_fetch_account_from_cache
11
11
  clean_user = @user.reload
12
- no_connection do
12
+ assert_no_queries do
13
13
  clean_user.account
14
14
  end
15
15
  end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,13 +1,18 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::PersistenceTest < Minitest::Test
4
+ class PersistenceTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  @topic = Topic.create :title => "csdn"
8
8
  end
9
9
 
10
10
  def test_should_reload_object
11
+ User.where(id: @user.id).update_all(email: 'different@csdn.com')
12
+ assert_equal 'different@csdn.com', @user.reload.email
13
+ end
14
+
15
+ def test_should_reload_object_associations
11
16
  User.increment_counter :books_count, @user.id
12
17
  assert_equal 0, @user.books_count
13
18
  assert_equal 1, @user.reload.books_count
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::PolymorphicAssociationTest < Minitest::Test
4
+ class PolymorphicAssociationTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  end
@@ -10,7 +10,7 @@ class ActiveRecord::PolymorphicAssociationTest < Minitest::Test
10
10
  image = @user.images.create
11
11
 
12
12
  @user.write_second_level_cache
13
- no_connection do
13
+ assert_no_queries do
14
14
  assert_equal @user, image.imagable
15
15
  end
16
16
  end
@@ -21,4 +21,3 @@ class ActiveRecord::PolymorphicAssociationTest < Minitest::Test
21
21
  assert_equal @user, image.imagable
22
22
  end
23
23
  end
24
-
@@ -0,0 +1,55 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'test_helper'
3
+
4
+ class PreloaderTest < ActiveSupport::TestCase
5
+ def test_belongs_to_preload_caches_includes
6
+ topics = [
7
+ Topic.create(title: 'title1', body: 'body1'),
8
+ Topic.create(title: 'title2', body: 'body2'),
9
+ Topic.create(title: 'title3', body: 'body3')
10
+ ]
11
+ topics.each { |topic| topic.posts.create(body: "post#{topic.id}") }
12
+
13
+ results = nil
14
+ assert_queries(1) do
15
+ results = Post.includes(:topic).order('id ASC').to_a
16
+ end
17
+ assert_equal topics, results.map(&:topic)
18
+ end
19
+
20
+ def test_belongs_to_when_read_multi_missed_from_cache_AR_will_fetch_missed_records_from_db
21
+ topics = [
22
+ Topic.create(title: 'title1', body: 'body1'),
23
+ Topic.create(title: 'title2', body: 'body2'),
24
+ Topic.create(title: 'title3', body: 'body3')
25
+ ]
26
+ topics.each { |topic| topic.posts.create(body: "post#{topic.id}") }
27
+ expired_topic = topics.first
28
+ expired_topic.expire_second_level_cache
29
+
30
+ results = nil
31
+ assert_queries(2) do
32
+ assert_sql(/IN\s+\(#{expired_topic.id}\)/m) do
33
+ results = Post.includes(:topic).order('id ASC').to_a
34
+ end
35
+ end
36
+
37
+ assert_equal topics, results.map(&:topic)
38
+ end
39
+
40
+ def test_has_many_preloader_returns_correct_results
41
+ topic = Topic.create(id: 1)
42
+ Post.create(id: 1)
43
+ post = topic.posts.create
44
+
45
+ assert_equal [post], Topic.includes(:posts).find(1).posts
46
+ end
47
+
48
+ def test_has_one_preloader_returns_correct_results
49
+ user = User.create(id: 1)
50
+ Account.create(id: 1)
51
+ account = user.create_account
52
+
53
+ assert_equal account, User.includes(:account).find(1).account
54
+ end
55
+ end
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class RecordMarshalTest < Minitest::Test
4
+ class RecordMarshalTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  end
data/test/require_test.rb CHANGED
@@ -2,10 +2,10 @@
2
2
  require 'test_helper'
3
3
  require 'active_record'
4
4
 
5
- class RequireTest < Minitest::Test
5
+ class RequireTest < ActiveSupport::TestCase
6
6
  def setup
7
7
  ActiveRecord::Relation
8
- require 'active_record/test_helper'
8
+ require 'test_helper'
9
9
  @user = User.create :name => 'Dingding Ye', :email => 'yedingding@gmail.com'
10
10
  end
11
11
 
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
2
+ require 'test_helper'
3
3
 
4
- class ActiveRecord::SecondLevelCacheTest < Minitest::Test
4
+ class SecondLevelCacheTest < ActiveSupport::TestCase
5
5
  def setup
6
6
  @user = User.create :name => 'csdn', :email => 'test@csdn.com'
7
7
  end
data/test/test_helper.rb CHANGED
@@ -1,14 +1,39 @@
1
1
  # -*- encoding : utf-8 -*-
2
- require 'rubygems'
3
2
  require 'bundler/setup'
4
- require 'second_level_cache'
5
3
  require 'minitest/autorun'
4
+ require 'active_support/test_case'
5
+ require 'active_record_test_case_helper'
6
6
  require 'database_cleaner'
7
7
 
8
- DatabaseCleaner[:active_record].strategy = :transaction
8
+ require 'active_record'
9
+ require 'second_level_cache'
10
+
11
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
12
+
13
+ require 'model/user'
14
+ require 'model/book'
15
+ require 'model/image'
16
+ require 'model/topic'
17
+ require 'model/post'
18
+ require 'model/account'
19
+
20
+ DatabaseCleaner[:active_record].strategy = :truncation
9
21
 
10
22
  SecondLevelCache.configure do |config|
11
23
  config.cache_store = ActiveSupport::Cache::MemoryStore.new
12
24
  end
13
25
 
14
- SecondLevelCache.logger.level = Logger::INFO
26
+ SecondLevelCache.logger.level = Logger::ERROR
27
+ ActiveSupport::Cache::MemoryStore.logger = SecondLevelCache::Config.logger
28
+ ActiveRecord::Base.logger = SecondLevelCache::Config.logger
29
+
30
+ class ActiveSupport::TestCase
31
+ setup do
32
+ SecondLevelCache.cache_store.clear
33
+ DatabaseCleaner.start
34
+ end
35
+
36
+ teardown do
37
+ DatabaseCleaner.clean
38
+ end
39
+ end
metadata CHANGED
@@ -1,108 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: second_level_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0.rc2
5
- prerelease: 6
4
+ version: 2.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Hooopo
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-02-28 00:00:00.000000000 Z
11
+ date: 2014-09-23 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>'
17
+ - - ">"
20
18
  - !ruby/object:Gem::Version
21
19
  version: 4.0.0
22
- - - <
20
+ - - "<"
23
21
  - !ruby/object:Gem::Version
24
22
  version: '5.0'
25
23
  type: :runtime
26
24
  prerelease: false
27
25
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
26
  requirements:
30
- - - ! '>'
27
+ - - ">"
31
28
  - !ruby/object:Gem::Version
32
29
  version: 4.0.0
33
- - - <
30
+ - - "<"
34
31
  - !ruby/object:Gem::Version
35
32
  version: '5.0'
36
33
  - !ruby/object:Gem::Dependency
37
34
  name: activerecord
38
35
  requirement: !ruby/object:Gem::Requirement
39
- none: false
40
36
  requirements:
41
- - - ! '>'
37
+ - - ">"
42
38
  - !ruby/object:Gem::Version
43
39
  version: 4.0.0
44
- - - <
40
+ - - "<"
45
41
  - !ruby/object:Gem::Version
46
42
  version: '5.0'
47
43
  type: :runtime
48
44
  prerelease: false
49
45
  version_requirements: !ruby/object:Gem::Requirement
50
- none: false
51
46
  requirements:
52
- - - ! '>'
47
+ - - ">"
53
48
  - !ruby/object:Gem::Version
54
49
  version: 4.0.0
55
- - - <
50
+ - - "<"
56
51
  - !ruby/object:Gem::Version
57
52
  version: '5.0'
58
53
  - !ruby/object:Gem::Dependency
59
54
  name: sqlite3
60
55
  requirement: !ruby/object:Gem::Requirement
61
- none: false
62
56
  requirements:
63
- - - ! '>='
57
+ - - ">="
64
58
  - !ruby/object:Gem::Version
65
59
  version: '0'
66
60
  type: :development
67
61
  prerelease: false
68
62
  version_requirements: !ruby/object:Gem::Requirement
69
- none: false
70
63
  requirements:
71
- - - ! '>='
64
+ - - ">="
72
65
  - !ruby/object:Gem::Version
73
66
  version: '0'
74
67
  - !ruby/object:Gem::Dependency
75
68
  name: rake
76
69
  requirement: !ruby/object:Gem::Requirement
77
- none: false
78
70
  requirements:
79
- - - ! '>='
71
+ - - ">="
80
72
  - !ruby/object:Gem::Version
81
73
  version: '0'
82
74
  type: :development
83
75
  prerelease: false
84
76
  version_requirements: !ruby/object:Gem::Requirement
85
- none: false
86
77
  requirements:
87
- - - ! '>='
78
+ - - ">="
88
79
  - !ruby/object:Gem::Version
89
80
  version: '0'
90
81
  - !ruby/object:Gem::Dependency
91
82
  name: database_cleaner
92
83
  requirement: !ruby/object:Gem::Requirement
93
- none: false
94
84
  requirements:
95
- - - ~>
85
+ - - "~>"
96
86
  - !ruby/object:Gem::Version
97
- version: 1.2.0
87
+ version: 1.3.0
98
88
  type: :development
99
89
  prerelease: false
100
90
  version_requirements: !ruby/object:Gem::Requirement
101
- none: false
102
91
  requirements:
103
- - - ~>
92
+ - - "~>"
104
93
  - !ruby/object:Gem::Version
105
- version: 1.2.0
94
+ version: 1.3.0
106
95
  description: Write Through and Read Through caching library inspired by CacheMoney
107
96
  and cache_fu, support ActiveRecord 4.
108
97
  email:
@@ -111,6 +100,12 @@ executables: []
111
100
  extensions: []
112
101
  extra_rdoc_files: []
113
102
  files:
103
+ - CHANGELOG.md
104
+ - Gemfile
105
+ - README.md
106
+ - Rakefile
107
+ - lib/second_level_cache.rb
108
+ - lib/second_level_cache/active_record.rb
114
109
  - lib/second_level_cache/active_record/base.rb
115
110
  - lib/second_level_cache/active_record/belongs_to_association.rb
116
111
  - lib/second_level_cache/active_record/fetch_by_uniq_key.rb
@@ -118,82 +113,75 @@ files:
118
113
  - lib/second_level_cache/active_record/has_one_association.rb
119
114
  - lib/second_level_cache/active_record/persistence.rb
120
115
  - lib/second_level_cache/active_record/preloader.rb
121
- - lib/second_level_cache/active_record.rb
122
116
  - lib/second_level_cache/arel/wheres.rb
123
117
  - lib/second_level_cache/config.rb
124
118
  - lib/second_level_cache/record_marshal.rb
125
119
  - lib/second_level_cache/version.rb
126
- - lib/second_level_cache.rb
127
- - README.md
128
- - Rakefile
129
- - Gemfile
130
- - CHANGELOG.md
131
120
  - second_level_cache.gemspec
132
- - test/active_record/base_test.rb
133
- - test/active_record/belongs_to_association_test.rb
134
- - test/active_record/fetch_by_uniq_key_test.rb
135
- - test/active_record/finder_methods_test.rb
136
- - test/active_record/has_one_association_test.rb
137
- - test/active_record/model/account.rb
138
- - test/active_record/model/book.rb
139
- - test/active_record/model/image.rb
140
- - test/active_record/model/post.rb
141
- - test/active_record/model/topic.rb
142
- - test/active_record/model/user.rb
143
- - test/active_record/persistence_test.rb
144
- - test/active_record/polymorphic_association_test.rb
145
- - test/active_record/preloader_test.rb
146
- - test/active_record/second_level_cache_test.rb
147
- - test/active_record/test_helper.rb
121
+ - test/active_record_test_case_helper.rb
122
+ - test/base_test.rb
123
+ - test/belongs_to_association_test.rb
124
+ - test/fetch_by_uniq_key_test.rb
125
+ - test/finder_methods_test.rb
126
+ - test/has_one_association_test.rb
127
+ - test/model/account.rb
128
+ - test/model/book.rb
129
+ - test/model/image.rb
130
+ - test/model/post.rb
131
+ - test/model/topic.rb
132
+ - test/model/user.rb
133
+ - test/persistence_test.rb
134
+ - test/polymorphic_association_test.rb
135
+ - test/preloader_test.rb
148
136
  - test/record_marshal_test.rb
149
137
  - test/require_test.rb
138
+ - test/second_level_cache_test.rb
150
139
  - test/test_helper.rb
151
140
  homepage: https://github.com/csdn-dev/second_level_cache
152
141
  licenses: []
142
+ metadata: {}
153
143
  post_install_message:
154
144
  rdoc_options: []
155
145
  require_paths:
156
146
  - lib
157
147
  required_ruby_version: !ruby/object:Gem::Requirement
158
- none: false
159
148
  requirements:
160
- - - ! '>='
149
+ - - ">="
161
150
  - !ruby/object:Gem::Version
162
151
  version: '0'
163
152
  required_rubygems_version: !ruby/object:Gem::Requirement
164
- none: false
165
153
  requirements:
166
- - - ! '>'
154
+ - - ">="
167
155
  - !ruby/object:Gem::Version
168
- version: 1.3.1
156
+ version: '0'
169
157
  requirements: []
170
158
  rubyforge_project:
171
- rubygems_version: 1.8.23
159
+ rubygems_version: 2.2.2
172
160
  signing_key:
173
- specification_version: 3
174
- summary: ! 'SecondLevelCache is a write-through and read-through caching library inspired
161
+ specification_version: 4
162
+ summary: 'SecondLevelCache is a write-through and read-through caching library inspired
175
163
  by Cache Money and cache_fu, support only Rails3 and ActiveRecord. Read-Through:
176
164
  Queries by ID, like current_user.articles.find(params[:id]), will first look in
177
165
  cache store and then look in the database for the results of that query. If there
178
166
  is a cache miss, it will populate the cache. Write-Through: As objects are created,
179
167
  updated, and deleted, all of the caches are automatically kept up-to-date and coherent.'
180
168
  test_files:
181
- - test/active_record/base_test.rb
182
- - test/active_record/belongs_to_association_test.rb
183
- - test/active_record/fetch_by_uniq_key_test.rb
184
- - test/active_record/finder_methods_test.rb
185
- - test/active_record/has_one_association_test.rb
186
- - test/active_record/model/account.rb
187
- - test/active_record/model/book.rb
188
- - test/active_record/model/image.rb
189
- - test/active_record/model/post.rb
190
- - test/active_record/model/topic.rb
191
- - test/active_record/model/user.rb
192
- - test/active_record/persistence_test.rb
193
- - test/active_record/polymorphic_association_test.rb
194
- - test/active_record/preloader_test.rb
195
- - test/active_record/second_level_cache_test.rb
196
- - test/active_record/test_helper.rb
169
+ - test/active_record_test_case_helper.rb
170
+ - test/base_test.rb
171
+ - test/belongs_to_association_test.rb
172
+ - test/fetch_by_uniq_key_test.rb
173
+ - test/finder_methods_test.rb
174
+ - test/has_one_association_test.rb
175
+ - test/model/account.rb
176
+ - test/model/book.rb
177
+ - test/model/image.rb
178
+ - test/model/post.rb
179
+ - test/model/topic.rb
180
+ - test/model/user.rb
181
+ - test/persistence_test.rb
182
+ - test/polymorphic_association_test.rb
183
+ - test/preloader_test.rb
197
184
  - test/record_marshal_test.rb
198
185
  - test/require_test.rb
186
+ - test/second_level_cache_test.rb
199
187
  - test/test_helper.rb
@@ -1,28 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'active_record/test_helper'
3
-
4
- class ActiveRecord::PreloaderTest < Minitest::Test
5
- def setup
6
- DatabaseCleaner[:active_record].start
7
- @topic1 = Topic.create :title => "title1", :body => "body1"
8
- @topic2 = Topic.create :title => "title2", :body => "body2"
9
- @topic3 = Topic.create :title => "title3", :body => "body3"
10
- @post1 = @topic1.posts.create :body => "post1"
11
- @post2 = @topic2.posts.create :body => "post2"
12
- @post3 = @topic3.posts.create :body => "post3"
13
- end
14
-
15
- def test_preload_work_properly
16
- results = Post.includes(:topic).order("id ASC").to_a
17
- assert_equal results.size, 3
18
- assert_equal results.first.topic, @topic1
19
- end
20
-
21
- def test_when_read_multi_missed_from_cache_AR_will_fetch_missed_records_from_db
22
- @topic1.expire_second_level_cache
23
- results = Post.includes(:topic).order("id ASC").to_a
24
- assert_equal results.size, 3
25
- assert_equal results.first.topic, @topic1
26
- assert_match /IN\s+\(#{@topic1.id}\)/m, $sql_logger
27
- end
28
- end
@@ -1,55 +0,0 @@
1
- # -*- encoding : utf-8 -*-
2
- require 'test_helper'
3
- require 'active_record'
4
- require 'second_level_cache/active_record'
5
-
6
- def open_test_db_connect
7
- ActiveRecord::Base.establish_connection(
8
- :adapter => 'sqlite3',
9
- :database => 'test/test.sqlite3'
10
- )
11
- end
12
- open_test_db_connect
13
-
14
- def close_test_db_connect
15
- ActiveRecord::Base.connection.disconnect!
16
- end
17
-
18
- class Minitest::Test
19
- def no_connection
20
- close_test_db_connect
21
- assert_nothing_raised { yield }
22
- ensure
23
- open_test_db_connect
24
- end
25
-
26
-
27
- def assert_nothing_raised(*)
28
- yield
29
- end
30
-
31
- def teardown
32
- $sql_logger = nil
33
- SecondLevelCache.cache_store.clear
34
- DatabaseCleaner[:active_record].clean
35
- end
36
- end
37
-
38
- module ActiveRecord
39
- module Querying
40
- def find_by_sql_with_test(sql, binds = [])
41
- $sql_logger ||= ""
42
- $sql_logger << sql.to_sql
43
- $sql_logger << "\n"
44
- find_by_sql_without_test(sql, binds)
45
- end
46
- alias_method_chain :find_by_sql, :test
47
- end
48
- end
49
-
50
- require 'active_record/model/user'
51
- require 'active_record/model/book'
52
- require 'active_record/model/image'
53
- require 'active_record/model/topic'
54
- require 'active_record/model/post'
55
- require 'active_record/model/account'