From 08fe9ab136f02099e0e7cb5b3373bf51b0605692 Mon Sep 17 00:00:00 2001 From: Jon Rowe Date: Sun, 30 May 2010 23:10:02 +0100 Subject: [PATCH] datamapper multi repository --- lib/database_cleaner/data_mapper/base.rb | 124 ++++++++++++++++++ .../data_mapper/transaction.rb | 10 +- .../data_mapper/truncation.rb | 120 +---------------- .../database_cleaner/data_mapper/base_spec.rb | 9 ++ 4 files changed, 144 insertions(+), 119 deletions(-) diff --git a/lib/database_cleaner/data_mapper/base.rb b/lib/database_cleaner/data_mapper/base.rb index d15612b..0d8ec2e 100644 --- a/lib/database_cleaner/data_mapper/base.rb +++ b/lib/database_cleaner/data_mapper/base.rb @@ -1,4 +1,119 @@ require 'database_cleaner/generic/base' + +module DataMapper + module Adapters + + class DataObjectsAdapter + + def storage_names(repository = :default) + raise NotImplementedError + end + + end + + class MysqlAdapter < DataObjectsAdapter + + # taken from http://github.com/godfat/dm-mapping/tree/master + def storage_names(repository = :default) + select 'SHOW TABLES' + end + + def truncate_table(table_name) + execute("TRUNCATE TABLE #{quote_name(table_name)};") + end + + # copied from activerecord + def disable_referential_integrity + old = select("SELECT @@FOREIGN_KEY_CHECKS;") + begin + execute("SET FOREIGN_KEY_CHECKS = 0;") + yield + ensure + execute("SET FOREIGN_KEY_CHECKS = #{old};") + end + end + + end + + class Sqlite3Adapter < DataObjectsAdapter + + # taken from http://github.com/godfat/dm-mapping/tree/master + def storage_names(repository = :default) + # activerecord-2.1.0/lib/active_record/connection_adapters/sqlite_adapter.rb: 177 + sql = <<-SQL.compress_lines + SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL + # activerecord-2.1.0/lib/active_record/connection_adapters/sqlite_adapter.rb: 181 + select sql + end + + def truncate_table(table_name) + execute("DELETE FROM #{quote_name(table_name)};") + end + + # this is a no-op copied from activerecord + # i didn't find out if/how this is possible + # activerecord also doesn't do more here + def disable_referential_integrity + yield + end + + end + + + # FIXME + # i don't know if this works + # i basically just copied activerecord code to get a rough idea what they do. + # i don't have postgres available, so i won't be the one to write this. + # maybe codes below gets some postgres/datamapper user going, though. + class PostgresAdapter < DataObjectsAdapter + + # taken from http://github.com/godfat/dm-mapping/tree/master + def storage_names(repository = :default) + sql = <<-SQL.compress_lines + SELECT table_name FROM "information_schema"."tables" + WHERE table_schema = current_schema() + SQL + select(sql) + end + + def truncate_table(table_name) + execute("TRUNCATE TABLE #{quote_name(table_name)} CASCADE;") + end + + # FIXME + # copied from activerecord + def supports_disable_referential_integrity? + version = select("SHOW server_version")[0][0].split('.') + (version[0].to_i >= 8 && version[1].to_i >= 1) ? true : false + rescue + return false + end + + # FIXME + # copied unchanged from activerecord + def disable_referential_integrity(repository = :default) + if supports_disable_referential_integrity? then + execute(storage_names(repository).collect do |name| + "ALTER TABLE #{quote_name(name)} DISABLE TRIGGER ALL" + end.join(";")) + end + yield + ensure + if supports_disable_referential_integrity? then + execute(storage_names(repository).collect do |name| + "ALTER TABLE #{quote_name(name)} ENABLE TRIGGER ALL" + end.join(";")) + end + end + + end + + end +end + module DatabaseCleaner module DataMapper def self.available_strategies @@ -7,6 +122,15 @@ module DatabaseCleaner module Base include ::DatabaseCleaner::Generic::Base + + def db=(desired_db) + @db = desired_db + end + + def db + @db || :default + end + end end end \ No newline at end of file diff --git a/lib/database_cleaner/data_mapper/transaction.rb b/lib/database_cleaner/data_mapper/transaction.rb index 06e2f74..66553e6 100644 --- a/lib/database_cleaner/data_mapper/transaction.rb +++ b/lib/database_cleaner/data_mapper/transaction.rb @@ -4,16 +4,18 @@ module DatabaseCleaner::DataMapper class Transaction include ::DatabaseCleaner::DataMapper::Base #TODO Figure out repositories, may have to refactor connection_klass to something more sensible - def start(repo = :default) - DataMapper.repository(repo) do |r| + def start(repository = nil) + repository = self.db if repository.nil? + ::DataMapper.repository(repository) do |r| transaction = DataMapper::Transaction.new(r) transaction.begin r.adapter.push_transaction(transaction) end end - def clean(repo = :default) - DataMapper.repository(repo) do |r| + def clean(repository = nil) + repository = self.db if repository.nil? + ::DataMapper.repository(repository) do |r| adapter = r.adapter while adapter.current_transaction adapter.current_transaction.rollback diff --git a/lib/database_cleaner/data_mapper/truncation.rb b/lib/database_cleaner/data_mapper/truncation.rb index 59ca25d..c0bfc8c 100644 --- a/lib/database_cleaner/data_mapper/truncation.rb +++ b/lib/database_cleaner/data_mapper/truncation.rb @@ -1,119 +1,7 @@ require "database_cleaner/generic/truncation" require 'database_cleaner/data_mapper/base' -module DataMapper - module Adapters - class DataObjectsAdapter - - def storage_names(repository = :default) - raise NotImplementedError - end - - end - - class MysqlAdapter < DataObjectsAdapter - - # taken from http://github.com/godfat/dm-mapping/tree/master - def storage_names(repository = :default) - select 'SHOW TABLES' - end - - def truncate_table(table_name) - execute("TRUNCATE TABLE #{quote_name(table_name)};") - end - - # copied from activerecord - def disable_referential_integrity - old = select("SELECT @@FOREIGN_KEY_CHECKS;") - begin - execute("SET FOREIGN_KEY_CHECKS = 0;") - yield - ensure - execute("SET FOREIGN_KEY_CHECKS = #{old};") - end - end - - end - - class Sqlite3Adapter < DataObjectsAdapter - - # taken from http://github.com/godfat/dm-mapping/tree/master - def storage_names(repository = :default) - # activerecord-2.1.0/lib/active_record/connection_adapters/sqlite_adapter.rb: 177 - sql = <<-SQL.compress_lines - SELECT name - FROM sqlite_master - WHERE type = 'table' AND NOT name = 'sqlite_sequence' - SQL - # activerecord-2.1.0/lib/active_record/connection_adapters/sqlite_adapter.rb: 181 - select sql - end - - def truncate_table(table_name) - execute("DELETE FROM #{quote_name(table_name)};") - end - - # this is a no-op copied from activerecord - # i didn't find out if/how this is possible - # activerecord also doesn't do more here - def disable_referential_integrity - yield - end - - end - - - # FIXME - # i don't know if this works - # i basically just copied activerecord code to get a rough idea what they do. - # i don't have postgres available, so i won't be the one to write this. - # maybe codes below gets some postgres/datamapper user going, though. - class PostgresAdapter < DataObjectsAdapter - - # taken from http://github.com/godfat/dm-mapping/tree/master - def storage_names(repository = :default) - sql = <<-SQL.compress_lines - SELECT table_name FROM "information_schema"."tables" - WHERE table_schema = current_schema() - SQL - select(sql) - end - - def truncate_table(table_name) - execute("TRUNCATE TABLE #{quote_name(table_name)} CASCADE;") - end - - # FIXME - # copied from activerecord - def supports_disable_referential_integrity? - version = select("SHOW server_version")[0][0].split('.') - (version[0].to_i >= 8 && version[1].to_i >= 1) ? true : false - rescue - return false - end - - # FIXME - # copied unchanged from activerecord - def disable_referential_integrity(repository = :default) - if supports_disable_referential_integrity? then - execute(storage_names(repository).collect do |name| - "ALTER TABLE #{quote_name(name)} DISABLE TRIGGER ALL" - end.join(";")) - end - yield - ensure - if supports_disable_referential_integrity? then - execute(storage_names(repository).collect do |name| - "ALTER TABLE #{quote_name(name)} ENABLE TRIGGER ALL" - end.join(";")) - end - end - - end - - end -end module DatabaseCleaner @@ -122,10 +10,11 @@ module DatabaseCleaner include ::DatabaseCleaner::DataMapper::Base include ::DatabaseCleaner::Generic::Truncation - def clean(repository = :default) + def clean(repository = nil) + repository = self.db if repository.nil? adapter = ::DataMapper.repository(repository).adapter adapter.disable_referential_integrity do - tables_to_truncate.each do |table_name| + tables_to_truncate(repository).each do |table_name| adapter.truncate_table table_name end end @@ -133,7 +22,8 @@ module DatabaseCleaner private - def tables_to_truncate(repository = :default) + def tables_to_truncate(repository = nil) + repository = self.db if repository.nil? (@only || ::DataMapper.repository(repository).adapter.storage_names(repository)) - @tables_to_exclude end diff --git a/spec/database_cleaner/data_mapper/base_spec.rb b/spec/database_cleaner/data_mapper/base_spec.rb index 2c1461a..e345273 100644 --- a/spec/database_cleaner/data_mapper/base_spec.rb +++ b/spec/database_cleaner/data_mapper/base_spec.rb @@ -16,6 +16,15 @@ module DatabaseCleaner it_should_behave_like "a generic strategy" it { should respond_to :db } it { should respond_to :db= } + + it "should store my desired db" do + subject.db = :my_db + subject.db.should == :my_db + end + + it "should default to :default" do + subject.db.should == :default + end end end end \ No newline at end of file