mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Handle up/down for multiple databases
This change adds the ability to run up/down for a database in a multi-db environment. If you have an app with a primary and animals database the following tasks will be generated: ``` VERSION=123 rake db:migrate:up:primary VERSION=123 rake db:migrate:up:primary VERSION=123 rake db:migrate:down:primary VERSION=123 rake db:migrate:up:animals ``` I didn't generate descriptions with them since we don't generate a description for a single database application. In addition to this change I've made it so if your application has multiple databases Rails will raise if you try to run `up` or `down` without a namespace. This is because we don't know which DB you want to run `up` or `down` against unless the app tells us, so it's safer to just block it and recommend using namespaced versions of up/down respectively. The output for the raise looks like: ``` You're using a multiple database application. To use `db:migrate:down` you must run the namespaced task with a VERSION. Available tasks are db:migrate:down:primary and db:migrate:down:animals. ```
This commit is contained in:
parent
1a5381ff0c
commit
f9244c6585
3 changed files with 115 additions and 1 deletions
|
@ -128,6 +128,8 @@ db_namespace = namespace :db do
|
|||
|
||||
# desc 'Runs the "up" for a given migration VERSION.'
|
||||
task up: :load_config do
|
||||
ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:up")
|
||||
|
||||
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
||||
|
||||
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
||||
|
@ -139,8 +141,30 @@ db_namespace = namespace :db do
|
|||
db_namespace["_dump"].invoke
|
||||
end
|
||||
|
||||
namespace :up do
|
||||
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
||||
desc "up for #{spec_name}"
|
||||
task spec_name => :load_config do
|
||||
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
||||
|
||||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
||||
|
||||
ActiveRecord::Base.establish_connection(db_config.config)
|
||||
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
||||
ActiveRecord::Base.connection.migration_context.run(
|
||||
:up,
|
||||
ActiveRecord::Tasks::DatabaseTasks.target_version
|
||||
)
|
||||
|
||||
db_namespace["_dump"].invoke
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# desc 'Runs the "down" for a given migration VERSION.'
|
||||
task down: :load_config do
|
||||
ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:down")
|
||||
|
||||
raise "VERSION is required - To go down one migration, use db:rollback" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
||||
|
||||
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
||||
|
@ -152,6 +176,25 @@ db_namespace = namespace :db do
|
|||
db_namespace["_dump"].invoke
|
||||
end
|
||||
|
||||
namespace :down do
|
||||
ActiveRecord::Tasks::DatabaseTasks.for_each do |spec_name|
|
||||
task spec_name => :load_config do
|
||||
raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
|
||||
|
||||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, spec_name: spec_name)
|
||||
|
||||
ActiveRecord::Base.establish_connection(db_config.config)
|
||||
ActiveRecord::Tasks::DatabaseTasks.check_target_version
|
||||
ActiveRecord::Base.connection.migration_context.run(
|
||||
:down,
|
||||
ActiveRecord::Tasks::DatabaseTasks.target_version
|
||||
)
|
||||
|
||||
db_namespace["_dump"].invoke
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Display status of migrations"
|
||||
task status: :load_config do
|
||||
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
||||
|
|
|
@ -155,6 +155,20 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def raise_for_multi_db(environment = env, command:)
|
||||
db_configs = ActiveRecord::Base.configurations.configs_for(env_name: environment)
|
||||
|
||||
if db_configs.count > 1
|
||||
dbs_list = []
|
||||
|
||||
db_configs.each do |db|
|
||||
dbs_list << "#{command}:#{db.spec_name}"
|
||||
end
|
||||
|
||||
raise "You're using a multiple database application. To use `#{command}` you must run the namespaced task with a VERSION. Available tasks are #{dbs_list.to_sentence}."
|
||||
end
|
||||
end
|
||||
|
||||
def create_current(environment = env)
|
||||
each_current_configuration(environment) { |configuration|
|
||||
create configuration
|
||||
|
|
|
@ -24,7 +24,6 @@ module ApplicationTests
|
|||
assert_no_match(/already exists/, output)
|
||||
assert File.exist?(expected_database)
|
||||
|
||||
|
||||
output = rails("db:drop")
|
||||
assert_match(/Dropped database/, output)
|
||||
assert_match_namespace(namespace, output)
|
||||
|
@ -137,6 +136,36 @@ module ApplicationTests
|
|||
end
|
||||
end
|
||||
|
||||
def db_up_and_down(version, namespace = nil)
|
||||
Dir.chdir(app_path) do
|
||||
generate_models_for_animals
|
||||
rails("db:migrate")
|
||||
|
||||
if namespace
|
||||
down_output = rails("db:migrate:down:#{namespace}", "VERSION=#{version}")
|
||||
up_output = rails("db:migrate:up:#{namespace}", "VERSION=#{version}")
|
||||
else
|
||||
assert_raises RuntimeError, /You're using a multiple database application/ do
|
||||
down_output = rails("db:migrate:down", "VERSION=#{version}")
|
||||
end
|
||||
|
||||
assert_raises RuntimeError, /You're using a multiple database application/ do
|
||||
up_output = rails("db:migrate:up", "VERSION=#{version}")
|
||||
end
|
||||
end
|
||||
|
||||
case namespace
|
||||
when "primary"
|
||||
assert_match(/OneMigration: reverting/, down_output)
|
||||
assert_match(/OneMigration: migrated/, up_output)
|
||||
when nil
|
||||
else
|
||||
assert_match(/TwoMigration: reverting/, down_output)
|
||||
assert_match(/TwoMigration: migrated/, up_output)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def db_prepare
|
||||
Dir.chdir(app_path) do
|
||||
generate_models_for_animals
|
||||
|
@ -219,6 +248,34 @@ module ApplicationTests
|
|||
end
|
||||
end
|
||||
|
||||
test "db:migrate:down and db:migrate:up without a namespace raises in a multi-db application" do
|
||||
require "#{app_path}/config/environment"
|
||||
|
||||
app_file "db/migrate/01_one_migration.rb", <<-MIGRATION
|
||||
class OneMigration < ActiveRecord::Migration::Current
|
||||
end
|
||||
MIGRATION
|
||||
|
||||
db_up_and_down "01"
|
||||
end
|
||||
|
||||
test "db:migrate:down:namespace and db:migrate:up:namespace works" do
|
||||
require "#{app_path}/config/environment"
|
||||
|
||||
app_file "db/migrate/01_one_migration.rb", <<-MIGRATION
|
||||
class OneMigration < ActiveRecord::Migration::Current
|
||||
end
|
||||
MIGRATION
|
||||
|
||||
app_file "db/animals_migrate/02_two_migration.rb", <<-MIGRATION
|
||||
class TwoMigration < ActiveRecord::Migration::Current
|
||||
end
|
||||
MIGRATION
|
||||
|
||||
db_up_and_down "01", "primary"
|
||||
db_up_and_down "02", "animals"
|
||||
end
|
||||
|
||||
test "db:migrate:status works on all databases" do
|
||||
require "#{app_path}/config/environment"
|
||||
db_migrate_and_migrate_status
|
||||
|
|
Loading…
Reference in a new issue