From f928b6dff8b7718fea61b1afb173804d146a794c Mon Sep 17 00:00:00 2001 From: Marco Otte-Witte Date: Wed, 17 Jul 2013 11:43:00 +0200 Subject: [PATCH 1/2] make caching of tables to be truncated optional --- README.markdown | 4 ++++ .../active_record/truncation.rb | 7 ++++++- lib/database_cleaner/generic/truncation.rb | 5 +++-- .../active_record/truncation_spec.rb | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index ba20e4b..01dce55 100644 --- a/README.markdown +++ b/README.markdown @@ -181,6 +181,10 @@ The following options are available for ActiveRecord's `:truncation` strategy _o * `:pre_count` - When set to `true` this will check each table for existing rows before truncating it. This can speed up test suites when many of the tables to be truncated are never populated. Defaults to `:false`. (Also, see the section on [What strategy is fastest?](#what-strategy-is-fastest)) * `:reset_ids` - This only matters when `:pre_count` is used, and it will make sure that a tables auto-incrementing id is reset even if there are no rows in the table (e.g. records were created in the test but also removed before DatabaseCleaner gets to it). Defaults to `true`. +The following option is available for ActiveRecord's `:truncation` and `:deletion` strategy for any DB. + +* `:cache_tables` - When set to `true` the list of tables to truncate or delete from will only be read from the DB once, otherwise it will be read before each cleanup run. Set this to `false` if you create and drop tables in your tests. Defaults to `true`. + ### RSpec Example diff --git a/lib/database_cleaner/active_record/truncation.rb b/lib/database_cleaner/active_record/truncation.rb index 2ea50f6..3b5756d 100755 --- a/lib/database_cleaner/active_record/truncation.rb +++ b/lib/database_cleaner/active_record/truncation.rb @@ -239,7 +239,8 @@ module DatabaseCleaner::ActiveRecord private def tables_to_truncate(connection) - (@only || connection.database_cleaner_table_cache) - @tables_to_exclude - connection.database_cleaner_view_cache + tables_in_db = cache_tables? ? connection.database_cleaner_table_cache : connection.tables + (@only || tables_in_db) - @tables_to_exclude - connection.database_cleaner_view_cache end # overwritten @@ -247,6 +248,10 @@ module DatabaseCleaner::ActiveRecord [::ActiveRecord::Migrator.schema_migrations_table_name] end + def cache_tables? + !!@cache_tables + end + def pre_count? @pre_count == true end diff --git a/lib/database_cleaner/generic/truncation.rb b/lib/database_cleaner/generic/truncation.rb index dc6a7e5..2d9e33c 100644 --- a/lib/database_cleaner/generic/truncation.rb +++ b/lib/database_cleaner/generic/truncation.rb @@ -2,8 +2,8 @@ module DatabaseCleaner module Generic module Truncation def initialize(opts={}) - if !opts.empty? && !(opts.keys - [:only, :except, :pre_count, :reset_ids]).empty? - raise ArgumentError, "The only valid options are :only, :except, :pre_count or :reset_ids. You specified #{opts.keys.join(',')}." + if !opts.empty? && !(opts.keys - [:only, :except, :pre_count, :reset_ids, :cache_tables]).empty? + raise ArgumentError, "The only valid options are :only, :except, :pre_count, :reset_ids or :cache_tables. You specified #{opts.keys.join(',')}." end if opts.has_key?(:only) && opts.has_key?(:except) raise ArgumentError, "You may only specify either :only or :except. Doing both doesn't really make sense does it?" @@ -14,6 +14,7 @@ module DatabaseCleaner @tables_to_exclude += migration_storage_names @pre_count = opts[:pre_count] @reset_ids = opts[:reset_ids] + @cache_tables = opts.has_key?(:cache_tables) ? !!opts[:cache_tables] : true end def start diff --git a/spec/database_cleaner/active_record/truncation_spec.rb b/spec/database_cleaner/active_record/truncation_spec.rb index 9171360..0bc0a72 100644 --- a/spec/database_cleaner/active_record/truncation_spec.rb +++ b/spec/database_cleaner/active_record/truncation_spec.rb @@ -111,6 +111,24 @@ module DatabaseCleaner subject.clean end end + + context 'when :cache_tables is set to true' do + it 'caches the list of tables to be truncated' do + connection.should_receive(:database_cleaner_table_cache) + + connection.stub!(:truncate_tables) + Truncation.new({ :cache_tables => true }).clean + end + end + + context 'when :cache_tables is set to false' do + it 'does not cache the list of tables to be truncated' do + connection.should_not_receive(:database_cleaner_table_cache) + + connection.stub!(:truncate_tables) + Truncation.new({ :cache_tables => false }).clean + end + end end describe '#pre_count?' do From a9c507396f59c96cc3c86e7dc7f40b4424160ddf Mon Sep 17 00:00:00 2001 From: Marco Otte-Witte Date: Wed, 17 Jul 2013 15:11:47 +0200 Subject: [PATCH 2/2] fixed specs --- spec/database_cleaner/active_record/truncation_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/database_cleaner/active_record/truncation_spec.rb b/spec/database_cleaner/active_record/truncation_spec.rb index 0bc0a72..7d40f35 100644 --- a/spec/database_cleaner/active_record/truncation_spec.rb +++ b/spec/database_cleaner/active_record/truncation_spec.rb @@ -114,7 +114,8 @@ module DatabaseCleaner context 'when :cache_tables is set to true' do it 'caches the list of tables to be truncated' do - connection.should_receive(:database_cleaner_table_cache) + connection.should_receive(:database_cleaner_table_cache).and_return([]) + connection.should_not_receive(:tables) connection.stub!(:truncate_tables) Truncation.new({ :cache_tables => true }).clean @@ -124,6 +125,7 @@ module DatabaseCleaner context 'when :cache_tables is set to false' do it 'does not cache the list of tables to be truncated' do connection.should_not_receive(:database_cleaner_table_cache) + connection.should_receive(:tables).and_return([]) connection.stub!(:truncate_tables) Truncation.new({ :cache_tables => false }).clean