datamapper multi repository
This commit is contained in:
parent
b0669ffcab
commit
08fe9ab136
|
@ -1,4 +1,119 @@
|
||||||
require 'database_cleaner/generic/base'
|
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 DatabaseCleaner
|
||||||
module DataMapper
|
module DataMapper
|
||||||
def self.available_strategies
|
def self.available_strategies
|
||||||
|
@ -7,6 +122,15 @@ module DatabaseCleaner
|
||||||
|
|
||||||
module Base
|
module Base
|
||||||
include ::DatabaseCleaner::Generic::Base
|
include ::DatabaseCleaner::Generic::Base
|
||||||
|
|
||||||
|
def db=(desired_db)
|
||||||
|
@db = desired_db
|
||||||
|
end
|
||||||
|
|
||||||
|
def db
|
||||||
|
@db || :default
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -4,16 +4,18 @@ module DatabaseCleaner::DataMapper
|
||||||
class Transaction
|
class Transaction
|
||||||
include ::DatabaseCleaner::DataMapper::Base
|
include ::DatabaseCleaner::DataMapper::Base
|
||||||
#TODO Figure out repositories, may have to refactor connection_klass to something more sensible
|
#TODO Figure out repositories, may have to refactor connection_klass to something more sensible
|
||||||
def start(repo = :default)
|
def start(repository = nil)
|
||||||
DataMapper.repository(repo) do |r|
|
repository = self.db if repository.nil?
|
||||||
|
::DataMapper.repository(repository) do |r|
|
||||||
transaction = DataMapper::Transaction.new(r)
|
transaction = DataMapper::Transaction.new(r)
|
||||||
transaction.begin
|
transaction.begin
|
||||||
r.adapter.push_transaction(transaction)
|
r.adapter.push_transaction(transaction)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def clean(repo = :default)
|
def clean(repository = nil)
|
||||||
DataMapper.repository(repo) do |r|
|
repository = self.db if repository.nil?
|
||||||
|
::DataMapper.repository(repository) do |r|
|
||||||
adapter = r.adapter
|
adapter = r.adapter
|
||||||
while adapter.current_transaction
|
while adapter.current_transaction
|
||||||
adapter.current_transaction.rollback
|
adapter.current_transaction.rollback
|
||||||
|
|
|
@ -1,119 +1,7 @@
|
||||||
require "database_cleaner/generic/truncation"
|
require "database_cleaner/generic/truncation"
|
||||||
require 'database_cleaner/data_mapper/base'
|
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
|
module DatabaseCleaner
|
||||||
|
@ -122,10 +10,11 @@ module DatabaseCleaner
|
||||||
include ::DatabaseCleaner::DataMapper::Base
|
include ::DatabaseCleaner::DataMapper::Base
|
||||||
include ::DatabaseCleaner::Generic::Truncation
|
include ::DatabaseCleaner::Generic::Truncation
|
||||||
|
|
||||||
def clean(repository = :default)
|
def clean(repository = nil)
|
||||||
|
repository = self.db if repository.nil?
|
||||||
adapter = ::DataMapper.repository(repository).adapter
|
adapter = ::DataMapper.repository(repository).adapter
|
||||||
adapter.disable_referential_integrity do
|
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
|
adapter.truncate_table table_name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -133,7 +22,8 @@ module DatabaseCleaner
|
||||||
|
|
||||||
private
|
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
|
(@only || ::DataMapper.repository(repository).adapter.storage_names(repository)) - @tables_to_exclude
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,15 @@ module DatabaseCleaner
|
||||||
it_should_behave_like "a generic strategy"
|
it_should_behave_like "a generic strategy"
|
||||||
it { should respond_to :db }
|
it { should respond_to :db }
|
||||||
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
|
end
|
||||||
end
|
end
|
Loading…
Reference in New Issue