diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index ef1d07f1c3..d84191e435 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,27 @@ +* Support hash config for `structure_dump_flags` and `structure_load_flags` flags + Now that Active Record supports multiple databases configuration + we need a way to pass specific flags for dump/load databases since + the options are not the same for different adapters. + We can use in the original way: + + ```ruby + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-defaults', '--skip-add-drop-table'] + #or + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = '--no-defaults --skip-add-drop-table' + ``` + + And also use it passing a hash, with one or more keys, where the key + is the adapter + + ```ruby + ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = { + mysql2: ['--no-defaults', '--skip-add-drop-table'], + postgres: '--no-tablespaces' + } + ``` + + *Gustavo Gonzalez* + * Connection specification now passes the "url" key as a configuration for the adapter if the "url" protocol is "jdbc", "http", or "https". Previously only urls with the "jdbc" prefix were passed to the Active Record Adapter, others diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index 92040f8914..2d47cdf73e 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -39,11 +39,18 @@ module ActiveRecord ## # :singleton-method: # Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:schema:dump + # It can be used as a string/array (the typical case) or a hash (when you use multiple adapters) + # Example: + # ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = { + # mysql2: ['--no-defaults', '--skip-add-drop-table'], + # postgres: '--no-tablespaces' + # } mattr_accessor :structure_dump_flags, instance_accessor: false ## # :singleton-method: # Extra flags passed to database CLI tool when calling db:schema:load + # It can be used as a string/array (the typical case) or a hash (when you use multiple adapters) mattr_accessor :structure_load_flags, instance_accessor: false extend self @@ -338,13 +345,15 @@ module ActiveRecord def structure_dump(configuration, *arguments) db_config = resolve_configuration(configuration) filename = arguments.delete_at(0) - database_adapter_for(db_config, *arguments).structure_dump(filename, structure_dump_flags) + flags = structure_dump_flags_for(db_config.adapter) + database_adapter_for(db_config, *arguments).structure_dump(filename, flags) end def structure_load(configuration, *arguments) db_config = resolve_configuration(configuration) filename = arguments.delete_at(0) - database_adapter_for(db_config, *arguments).structure_load(filename, structure_load_flags) + flags = structure_load_flags_for(db_config.adapter) + database_adapter_for(db_config, *arguments).structure_load(filename, flags) end def load_schema(db_config, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc: @@ -566,6 +575,22 @@ module ActiveRecord def schema_sha1(file) Digest::SHA1.hexdigest(File.read(file)) end + + def structure_dump_flags_for(adapter) + if structure_dump_flags.is_a?(Hash) + structure_dump_flags[adapter.to_sym] + else + structure_dump_flags + end + end + + def structure_load_flags_for(adapter) + if structure_load_flags.is_a?(Hash) + structure_load_flags[adapter.to_sym] + else + structure_load_flags + end + end end end end diff --git a/activerecord/test/cases/tasks/mysql_rake_test.rb b/activerecord/test/cases/tasks/mysql_rake_test.rb index 23a6d285a0..cf87f00c8a 100644 --- a/activerecord/test/cases/tasks/mysql_rake_test.rb +++ b/activerecord/test/cases/tasks/mysql_rake_test.rb @@ -318,6 +318,28 @@ if current_adapter?(:Mysql2Adapter) end end + def test_structure_dump_with_hash_extra_flags_for_a_different_driver + filename = "awesome-file.sql" + expected_command = ["mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db"] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_dump_flags({ postgresql: ["--noop"] }) do + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + end + end + end + + def test_structure_dump_with_hash_extra_flags_for_the_correct_driver + filename = "awesome-file.sql" + expected_command = ["mysqldump", "--noop", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db"] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_dump_flags({ mysql2: ["--noop"] }) do + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename) + end + end + end + def test_structure_dump_with_ignore_tables filename = "awesome-file.sql" ActiveRecord::SchemaDumper.stub(:ignore_tables, ["foo", "bar"]) do @@ -404,6 +426,28 @@ if current_adapter?(:Mysql2Adapter) end end + def test_structure_load_with_hash_extra_flags_for_a_different_driver + filename = "awesome-file.sql" + expected_command = ["mysql", "--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}, "--database", "test-db"] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_load_flags({ postgresql: ["--noop"] }) do + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end + end + end + + def test_structure_load_with_hash_extra_flags_for_the_correct_driver + filename = "awesome-file.sql" + expected_command = ["mysql", "--noop", "--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}, "--database", "test-db"] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_load_flags({ mysql2: ["--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 diff --git a/activerecord/test/cases/tasks/postgresql_rake_test.rb b/activerecord/test/cases/tasks/postgresql_rake_test.rb index 4430afba96..2c5f2a08da 100644 --- a/activerecord/test/cases/tasks/postgresql_rake_test.rb +++ b/activerecord/test/cases/tasks/postgresql_rake_test.rb @@ -387,6 +387,26 @@ if current_adapter?(:PostgreSQLAdapter) end end + def test_structure_dump_with_hash_extra_flags_for_a_different_driver + expected_command = ["pg_dump", "--schema-only", "--no-privileges", "--no-owner", "--file", @filename, "my-app-db"] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_dump_flags({ mysql2: ["--noop"] }) do + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + end + end + end + + def test_structure_dump_with_hash_extra_flags_for_the_correct_driver + expected_command = ["pg_dump", "--schema-only", "--no-privileges", "--no-owner", "--file", @filename, "--noop", "my-app-db"] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_dump_flags({ postgresql: ["--noop"] }) do + ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, @filename) + end + end + end + def test_structure_dump_with_ignore_tables assert_called( ActiveRecord::SchemaDumper, @@ -509,6 +529,28 @@ if current_adapter?(:PostgreSQLAdapter) end end + def test_structure_load_with_hash_extra_flags_for_a_different_driver + filename = "awesome-file.sql" + expected_command = ["psql", "--set", "ON_ERROR_STOP=1", "--quiet", "--no-psqlrc", "--file", filename, @configuration["database"]] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_load_flags({ mysql2: ["--noop"] }) do + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end + end + end + + def test_structure_load_with_hash_extra_flags_for_the_correct_driver + filename = "awesome-file.sql" + expected_command = ["psql", "--set", "ON_ERROR_STOP=1", "--quiet", "--no-psqlrc", "--file", filename, "--noop", @configuration["database"]] + + assert_called_with(Kernel, :system, expected_command, returns: true) do + with_structure_load_flags({ postgresql: ["--noop"] }) do + ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename) + end + end + end + def test_structure_load_accepts_path_with_spaces filename = "awesome file.sql" assert_called_with(