提交 9edeb32a 编写于 作者: R Rafael Mendonça França

Merge pull request #6782 from kennyj/db-rake-structure-dump

Refactor db:structure:dump task.
......@@ -275,21 +275,11 @@ db_namespace = namespace :db do
abcs = ActiveRecord::Base.configurations
filename = ENV['DB_STRUCTURE'] || File.join(Rails.root, "db", "structure.sql")
case abcs[Rails.env]['adapter']
when /mysql/, 'oci', 'oracle'
when /mysql/, /postgresql/, /sqlite/
ActiveRecord::Tasks::DatabaseTasks.structure_dump(abcs[Rails.env], filename)
when 'oci', 'oracle'
ActiveRecord::Base.establish_connection(abcs[Rails.env])
File.open(filename, "w:utf-8") { |f| f << ActiveRecord::Base.connection.structure_dump }
when /postgresql/
set_psql_env(abcs[Rails.env])
search_path = abcs[Rails.env]['schema_search_path']
unless search_path.blank?
search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
end
`pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(abcs[Rails.env]['database'])}`
raise 'Error dumping database' if $?.exitstatus == 1
File.open(filename, "a") { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
when /sqlite/
dbfile = abcs[Rails.env]['database']
`sqlite3 #{dbfile} .schema > #{filename}`
when 'sqlserver'
`smoscript -s #{abcs[Rails.env]['host']} -d #{abcs[Rails.env]['database']} -u #{abcs[Rails.env]['username']} -p #{abcs[Rails.env]['password']} -f #{filename} -A -U`
when "firebird"
......
......@@ -60,6 +60,12 @@ def purge(configuration)
class_for_adapter(configuration['adapter']).new(configuration).purge
end
def structure_dump(*arguments)
configuration = arguments.first
filename = arguments.delete_at 1
class_for_adapter(configuration['adapter']).new(*arguments).structure_dump(filename)
end
private
def class_for_adapter(adapter)
......
......@@ -44,6 +44,11 @@ def charset
connection.charset
end
def structure_dump(filename)
establish_connection configuration
File.open(filename, "w:utf-8") { |f| f << ActiveRecord::Base.connection.structure_dump }
end
private
def configuration
......
require 'shellwords'
module ActiveRecord
module Tasks # :nodoc:
class PostgreSQLDatabaseTasks # :nodoc:
......@@ -33,6 +35,19 @@ def purge
create true
end
def structure_dump(filename)
set_psql_env
search_path = configuration['schema_search_path']
unless search_path.blank?
search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
end
command = "pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(configuration['database'])}"
raise 'Error dumping database' unless Kernel.system(command)
File.open(filename, "a") { |f| f << "SET search_path TO #{ActiveRecord::Base.connection.schema_search_path};\n\n" }
end
private
def configuration
......@@ -49,6 +64,13 @@ def establish_master_connection
'schema_search_path' => 'public'
)
end
def set_psql_env
ENV['PGHOST'] = configuration['host'] if configuration['host']
ENV['PGPORT'] = configuration['port'].to_s if configuration['port']
ENV['PGPASSWORD'] = configuration['password'].to_s if configuration['password']
ENV['PGUSER'] = configuration['username'].to_s if configuration['username']
end
end
end
end
......@@ -31,6 +31,11 @@ def charset
connection.encoding
end
def structure_dump(filename)
dbfile = configuration['database']
`sqlite3 #{dbfile} .schema > #{filename}`
end
private
def configuration
......
......@@ -303,7 +303,7 @@ def setup
returns @postgresql_tasks
ActiveRecord::Tasks::SQLiteDatabaseTasks.stubs(:new).returns @sqlite_tasks
end
def test_mysql_charset
@mysql_tasks.expects(:charset)
......@@ -328,4 +328,38 @@ def test_sqlite_charset
ActiveRecord::Tasks::DatabaseTasks.charset 'adapter' => 'sqlite3'
end
end
class DatabaseTasksStructureDumpTest < ActiveRecord::TestCase
def setup
@mysql_tasks, @postgresql_tasks, @sqlite_tasks = stub, stub, stub
ActiveRecord::Tasks::MySQLDatabaseTasks.stubs(:new).returns @mysql_tasks
ActiveRecord::Tasks::PostgreSQLDatabaseTasks.stubs(:new).
returns @postgresql_tasks
ActiveRecord::Tasks::SQLiteDatabaseTasks.stubs(:new).returns @sqlite_tasks
end
def test_mysql_structure_dump
@mysql_tasks.expects(:structure_dump).with("awesome-file.sql")
ActiveRecord::Tasks::DatabaseTasks.structure_dump({'adapter' => 'mysql'}, "awesome-file.sql")
end
def test_mysql2_structure_dump
@mysql_tasks.expects(:structure_dump).with("awesome-file.sql")
ActiveRecord::Tasks::DatabaseTasks.structure_dump({'adapter' => 'mysql2'}, "awesome-file.sql")
end
def test_postgresql_structure_dump
@postgresql_tasks.expects(:structure_dump).with("awesome-file.sql")
ActiveRecord::Tasks::DatabaseTasks.structure_dump({'adapter' => 'postgresql'}, "awesome-file.sql")
end
def test_sqlite_structure_dump
@sqlite_tasks.expects(:structure_dump).with("awesome-file.sql")
ActiveRecord::Tasks::DatabaseTasks.structure_dump({'adapter' => 'sqlite3'}, "awesome-file.sql")
end
end
end
......@@ -194,4 +194,28 @@ def test_db_retrieves_charset
ActiveRecord::Tasks::DatabaseTasks.charset @configuration
end
end
class MySQLStructureDumpTest < ActiveRecord::TestCase
def setup
@connection = stub(:structure_dump => true)
@configuration = {
'adapter' => 'mysql',
'database' => 'test-db'
}
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).returns(true)
end
def test_structure_dump
filename = "awesome-file.sql"
ActiveRecord::Base.expects(:establish_connection).with(@configuration)
@connection.expects(:structure_dump)
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename)
assert File.exists?(filename)
ensure
FileUtils.rm(filename)
end
end
end
......@@ -150,4 +150,29 @@ def test_db_retrieves_charset
ActiveRecord::Tasks::DatabaseTasks.charset @configuration
end
end
class PostgreSQLStructureDumpTest < ActiveRecord::TestCase
def setup
@connection = stub(:structure_dump => true)
@configuration = {
'adapter' => 'postgresql',
'database' => 'my-app-db'
}
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).returns(true)
Kernel.stubs(:system)
end
def test_structure_dump
filename = "awesome-file.sql"
Kernel.expects(:system).with("pg_dump -i -s -x -O -f #{filename} my-app-db").returns(true)
@connection.expects(:schema_search_path).returns("foo")
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename)
assert File.exists?(filename)
ensure
FileUtils.rm(filename)
end
end
end
......@@ -123,4 +123,26 @@ def test_db_retrieves_charset
ActiveRecord::Tasks::DatabaseTasks.charset @configuration, '/rails/root'
end
end
class SqliteStructureDumpTest < ActiveRecord::TestCase
def setup
@database = "db_create.sqlite3"
@configuration = {
'adapter' => 'sqlite3',
'database' => @database
}
end
def test_structure_dump
dbfile = @database
filename = "awesome-file.sql"
ActiveRecord::Tasks::DatabaseTasks.structure_dump @configuration, filename, '/rails/root'
assert File.exists?(dbfile)
assert File.exists?(filename)
ensure
FileUtils.rm(filename)
FileUtils.rm(dbfile)
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册