mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #27437 from kirs/structure-load-dump-flags
Make ActiveRecord structure load/dump configurable
This commit is contained in:
commit
261e94b8ee
7 changed files with 109 additions and 15 deletions
|
@ -35,6 +35,16 @@ module ActiveRecord
|
||||||
#
|
#
|
||||||
# DatabaseTasks.create_current('production')
|
# DatabaseTasks.create_current('production')
|
||||||
module DatabaseTasks
|
module DatabaseTasks
|
||||||
|
##
|
||||||
|
# :singleton-method:
|
||||||
|
# Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:structure:dump
|
||||||
|
mattr_accessor :structure_dump_flags, instance_accessor: false
|
||||||
|
|
||||||
|
##
|
||||||
|
# :singleton-method:
|
||||||
|
# Extra flags passed to database CLI tool when calling db:structure:load
|
||||||
|
mattr_accessor :structure_load_flags, instance_accessor: false
|
||||||
|
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
|
attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
|
||||||
|
@ -204,13 +214,13 @@ module ActiveRecord
|
||||||
def structure_dump(*arguments)
|
def structure_dump(*arguments)
|
||||||
configuration = arguments.first
|
configuration = arguments.first
|
||||||
filename = arguments.delete_at 1
|
filename = arguments.delete_at 1
|
||||||
class_for_adapter(configuration["adapter"]).new(*arguments).structure_dump(filename)
|
class_for_adapter(configuration["adapter"]).new(*arguments).structure_dump(filename, structure_dump_flags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_load(*arguments)
|
def structure_load(*arguments)
|
||||||
configuration = arguments.first
|
configuration = arguments.first
|
||||||
filename = arguments.delete_at 1
|
filename = arguments.delete_at 1
|
||||||
class_for_adapter(configuration["adapter"]).new(*arguments).structure_load(filename)
|
class_for_adapter(configuration["adapter"]).new(*arguments).structure_load(filename, structure_load_flags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
|
def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
|
||||||
|
|
|
@ -53,21 +53,23 @@ module ActiveRecord
|
||||||
connection.collation
|
connection.collation
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_dump(filename)
|
def structure_dump(filename, extra_flags)
|
||||||
args = prepare_command_options
|
args = prepare_command_options
|
||||||
args.concat(["--result-file", "#{filename}"])
|
args.concat(["--result-file", "#{filename}"])
|
||||||
args.concat(["--no-data"])
|
args.concat(["--no-data"])
|
||||||
args.concat(["--routines"])
|
args.concat(["--routines"])
|
||||||
args.concat(["--skip-comments"])
|
args.concat(["--skip-comments"])
|
||||||
|
args.concat(Array(extra_flags)) if extra_flags
|
||||||
args.concat(["#{configuration['database']}"])
|
args.concat(["#{configuration['database']}"])
|
||||||
|
|
||||||
run_cmd("mysqldump", args, "dumping")
|
run_cmd("mysqldump", args, "dumping")
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_load(filename)
|
def structure_load(filename, extra_flags)
|
||||||
args = prepare_command_options
|
args = prepare_command_options
|
||||||
args.concat(["--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
|
args.concat(["--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
|
||||||
args.concat(["--database", "#{configuration['database']}"])
|
args.concat(["--database", "#{configuration['database']}"])
|
||||||
|
args.concat(Array(extra_flags)) if extra_flags
|
||||||
|
|
||||||
run_cmd("mysql", args, "loading")
|
run_cmd("mysql", args, "loading")
|
||||||
end
|
end
|
||||||
|
|
|
@ -43,7 +43,7 @@ module ActiveRecord
|
||||||
create true
|
create true
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_dump(filename)
|
def structure_dump(filename, extra_flags)
|
||||||
set_psql_env
|
set_psql_env
|
||||||
|
|
||||||
search_path = \
|
search_path = \
|
||||||
|
@ -57,6 +57,7 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
args = ["-s", "-x", "-O", "-f", filename]
|
args = ["-s", "-x", "-O", "-f", filename]
|
||||||
|
args.concat(Array(extra_flags)) if extra_flags
|
||||||
unless search_path.blank?
|
unless search_path.blank?
|
||||||
args += search_path.split(",").map do |part|
|
args += search_path.split(",").map do |part|
|
||||||
"--schema=#{part.strip}"
|
"--schema=#{part.strip}"
|
||||||
|
@ -67,9 +68,11 @@ module ActiveRecord
|
||||||
File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
|
File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_load(filename)
|
def structure_load(filename, extra_flags)
|
||||||
set_psql_env
|
set_psql_env
|
||||||
args = [ "-v", ON_ERROR_STOP_1, "-q", "-f", filename, configuration["database"] ]
|
args = ["-v", ON_ERROR_STOP_1, "-q", "-f", filename]
|
||||||
|
args.concat(Array(extra_flags)) if extra_flags
|
||||||
|
args << configuration["database"]
|
||||||
run_cmd("psql", args, "loading")
|
run_cmd("psql", args, "loading")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -35,14 +35,16 @@ module ActiveRecord
|
||||||
connection.encoding
|
connection.encoding
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_dump(filename)
|
def structure_dump(filename, extra_flags)
|
||||||
dbfile = configuration["database"]
|
dbfile = configuration["database"]
|
||||||
`sqlite3 #{dbfile} .schema > #{filename}`
|
flags = extra_flags.try!(:join, " ")
|
||||||
|
`sqlite3 #{flags} #{dbfile} .schema > #{filename}`
|
||||||
end
|
end
|
||||||
|
|
||||||
def structure_load(filename)
|
def structure_load(filename, extra_flags)
|
||||||
dbfile = configuration["database"]
|
dbfile = configuration["database"]
|
||||||
`sqlite3 #{dbfile} < "#{filename}"`
|
flags = extra_flags.try!(:join, " ")
|
||||||
|
`sqlite3 #{flags} #{dbfile} < "#{filename}"`
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -61,7 +61,7 @@ module ActiveRecord
|
||||||
instance = klazz.new
|
instance = klazz.new
|
||||||
|
|
||||||
klazz.stubs(:new).returns instance
|
klazz.stubs(:new).returns instance
|
||||||
instance.expects(:structure_dump).with("awesome-file.sql")
|
instance.expects(:structure_dump).with("awesome-file.sql", nil)
|
||||||
|
|
||||||
ActiveRecord::Tasks::DatabaseTasks.register_task(/foo/, klazz)
|
ActiveRecord::Tasks::DatabaseTasks.register_task(/foo/, klazz)
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :foo }, "awesome-file.sql")
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :foo }, "awesome-file.sql")
|
||||||
|
@ -411,7 +411,7 @@ module ActiveRecord
|
||||||
|
|
||||||
ADAPTERS_TASKS.each do |k, v|
|
ADAPTERS_TASKS.each do |k, v|
|
||||||
define_method("test_#{k}_structure_dump") do
|
define_method("test_#{k}_structure_dump") do
|
||||||
eval("@#{v}").expects(:structure_dump).with("awesome-file.sql")
|
eval("@#{v}").expects(:structure_dump).with("awesome-file.sql", nil)
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => k }, "awesome-file.sql")
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => k }, "awesome-file.sql")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -422,7 +422,7 @@ module ActiveRecord
|
||||||
|
|
||||||
ADAPTERS_TASKS.each do |k, v|
|
ADAPTERS_TASKS.each do |k, v|
|
||||||
define_method("test_#{k}_structure_load") do
|
define_method("test_#{k}_structure_load") do
|
||||||
eval("@#{v}").expects(:structure_load).with("awesome-file.sql")
|
eval("@#{v}").expects(:structure_load).with("awesome-file.sql", nil)
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_load({ "adapter" => k }, "awesome-file.sql")
|
ActiveRecord::Tasks::DatabaseTasks.structure_load({ "adapter" => k }, "awesome-file.sql")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -294,6 +294,17 @@ if current_adapter?(:Mysql2Adapter)
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename)
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_structure_dump_with_extra_flags
|
||||||
|
filename = "awesome-file.sql"
|
||||||
|
expected_command = ["mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "--noop", "test-db"]
|
||||||
|
|
||||||
|
assert_called_with(Kernel, :system, expected_command, returns: true) do
|
||||||
|
with_structure_dump_flags(["--noop"]) do
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_warn_when_external_structure_dump_command_execution_fails
|
def test_warn_when_external_structure_dump_command_execution_fails
|
||||||
filename = "awesome-file.sql"
|
filename = "awesome-file.sql"
|
||||||
Kernel.expects(:system)
|
Kernel.expects(:system)
|
||||||
|
@ -323,6 +334,15 @@ if current_adapter?(:Mysql2Adapter)
|
||||||
@configuration.merge("sslca" => "ca.crt"),
|
@configuration.merge("sslca" => "ca.crt"),
|
||||||
filename)
|
filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def with_structure_dump_flags(flags)
|
||||||
|
old = ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = flags
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = old
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class MySQLStructureLoadTest < ActiveRecord::TestCase
|
class MySQLStructureLoadTest < ActiveRecord::TestCase
|
||||||
|
@ -340,6 +360,26 @@ if current_adapter?(:Mysql2Adapter)
|
||||||
|
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_structure_load
|
||||||
|
filename = "awesome-file.sql"
|
||||||
|
expected_command = ["mysql", "--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}, "--database", "test-db", "--noop"]
|
||||||
|
|
||||||
|
assert_called_with(Kernel, :system, expected_command, returns: true) do
|
||||||
|
with_structure_load_flags(["--noop"]) do
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def with_structure_load_flags(flags)
|
||||||
|
old = ActiveRecord::Tasks::DatabaseTasks.structure_load_flags
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = flags
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = old
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -236,6 +236,16 @@ if current_adapter?(:PostgreSQLAdapter)
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_structure_dump_with_extra_flags
|
||||||
|
expected_command = ["pg_dump", "-s", "-x", "-O", "-f", @filename, "--noop", "my-app-db"]
|
||||||
|
|
||||||
|
assert_called_with(Kernel, :system, expected_command, returns: true) do
|
||||||
|
with_structure_dump_flags(["--noop"]) do
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_structure_dump_with_schema_search_path
|
def test_structure_dump_with_schema_search_path
|
||||||
@configuration["schema_search_path"] = "foo,bar"
|
@configuration["schema_search_path"] = "foo,bar"
|
||||||
|
|
||||||
|
@ -263,7 +273,6 @@ if current_adapter?(:PostgreSQLAdapter)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def with_dump_schemas(value, &block)
|
def with_dump_schemas(value, &block)
|
||||||
old_dump_schemas = ActiveRecord::Base.dump_schemas
|
old_dump_schemas = ActiveRecord::Base.dump_schemas
|
||||||
ActiveRecord::Base.dump_schemas = value
|
ActiveRecord::Base.dump_schemas = value
|
||||||
|
@ -271,6 +280,14 @@ if current_adapter?(:PostgreSQLAdapter)
|
||||||
ensure
|
ensure
|
||||||
ActiveRecord::Base.dump_schemas = old_dump_schemas
|
ActiveRecord::Base.dump_schemas = old_dump_schemas
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def with_structure_dump_flags(flags)
|
||||||
|
old = ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = flags
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = old
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class PostgreSQLStructureLoadTest < ActiveRecord::TestCase
|
class PostgreSQLStructureLoadTest < ActiveRecord::TestCase
|
||||||
|
@ -293,12 +310,32 @@ if current_adapter?(:PostgreSQLAdapter)
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_structure_load_with_extra_flags
|
||||||
|
filename = "awesome-file.sql"
|
||||||
|
expected_command = ["psql", "-v", "ON_ERROR_STOP=1", "-q", "-f", filename, "--noop", @configuration["database"]]
|
||||||
|
|
||||||
|
assert_called_with(Kernel, :system, expected_command, returns: true) do
|
||||||
|
with_structure_load_flags(["--noop"]) do
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_structure_load_accepts_path_with_spaces
|
def test_structure_load_accepts_path_with_spaces
|
||||||
filename = "awesome file.sql"
|
filename = "awesome file.sql"
|
||||||
Kernel.expects(:system).with("psql", "-v", "ON_ERROR_STOP=1", "-q", "-f", filename, @configuration["database"]).returns(true)
|
Kernel.expects(:system).with("psql", "-v", "ON_ERROR_STOP=1", "-q", "-f", filename, @configuration["database"]).returns(true)
|
||||||
|
|
||||||
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def with_structure_load_flags(flags)
|
||||||
|
old = ActiveRecord::Tasks::DatabaseTasks.structure_load_flags
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = flags
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
ActiveRecord::Tasks::DatabaseTasks.structure_load_flags = old
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue