datamapper multi repository
This commit is contained in:
parent
b0669ffcab
commit
08fe9ab136
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue