1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fixed db:prepare task for multiple databases.

When one database existed already, but not the other,
during setup of missing one, existing database was wiped out.
This commit is contained in:
Wojciech Wnętrzak 2019-06-03 15:55:37 +02:00
parent 35a0fba187
commit 87796b3c81
No known key found for this signature in database
GPG key ID: 0EABD3BE530ECAC6
4 changed files with 99 additions and 31 deletions

View file

@ -266,12 +266,31 @@ db_namespace = namespace :db do
desc "Runs setup if database does not exist, or runs migrations if it does"
task prepare: :load_config do
seed = false
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
ActiveRecord::Base.establish_connection(db_config.config)
db_namespace["migrate"].invoke
ActiveRecord::Tasks::DatabaseTasks.migrate
# Skipped when no database
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, ActiveRecord::Base.schema_format, db_config.spec_name)
rescue ActiveRecord::NoDatabaseError
db_namespace["setup"].invoke
ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, db_config.spec_name)
ActiveRecord::Tasks::DatabaseTasks.load_schema(
db_config.config,
ActiveRecord::Base.schema_format,
nil,
db_config.env_name,
db_config.spec_name
)
seed = true
end
ActiveRecord::Base.establish_connection
ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
end
desc "Loads the seed data from db/seeds.rb"
@ -336,13 +355,9 @@ db_namespace = namespace :db do
namespace :schema do
desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
task dump: :load_config do
require "active_record/schema_dumper"
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :ruby)
File.open(filename, "w:utf-8") do |file|
ActiveRecord::Base.establish_connection(db_config.config)
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
end
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :ruby, db_config.spec_name)
end
db_namespace["schema:dump"].reenable
@ -385,14 +400,7 @@ db_namespace = namespace :db do
task dump: :load_config do
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
ActiveRecord::Base.establish_connection(db_config.config)
filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.spec_name, :sql)
ActiveRecord::Tasks::DatabaseTasks.structure_dump(db_config.config, filename)
if ActiveRecord::SchemaMigration.table_exists?
File.open(filename, "a") do |f|
f.puts ActiveRecord::Base.connection.dump_schema_information
f.print "\n"
end
end
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config.config, :sql, db_config.spec_name)
end
db_namespace["structure:dump"].reenable

View file

@ -169,8 +169,8 @@ module ActiveRecord
end
end
def create_current(environment = env)
each_current_configuration(environment) { |configuration|
def create_current(environment = env, spec_name = nil)
each_current_configuration(environment, spec_name) { |configuration|
create configuration
}
ActiveRecord::Base.establish_connection(environment.to_sym)
@ -325,6 +325,26 @@ module ActiveRecord
Migration.verbose = verbose_was
end
def dump_schema(configuration, format = ActiveRecord::Base.schema_format, spec_name = "primary")
require "active_record/schema_dumper"
filename = dump_filename(spec_name, format)
case format
when :ruby
File.open(filename, "w:utf-8") do |file|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
end
when :sql
structure_dump(configuration, filename)
if ActiveRecord::SchemaMigration.table_exists?
File.open(filename, "a") do |f|
f.puts ActiveRecord::Base.connection.dump_schema_information
f.print "\n"
end
end
end
end
def schema_file(format = ActiveRecord::Base.schema_format)
File.join(db_dir, schema_file_type(format))
end
@ -406,12 +426,14 @@ module ActiveRecord
task.is_a?(String) ? task.constantize : task
end
def each_current_configuration(environment)
def each_current_configuration(environment, spec_name = nil)
environments = [environment]
environments << "test" if environment == "development"
environments.each do |env|
ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
next if spec_name && spec_name != db_config.spec_name
yield db_config.config, db_config.spec_name, env
end
end

View file

@ -303,6 +303,26 @@ module ApplicationTests
require "#{app_path}/config/environment"
db_prepare
end
test "db:prepare setups missing database without clearing existing one" do
require "#{app_path}/config/environment"
Dir.chdir(app_path) do
# Bug not visible on SQLite3. Can be simplified when https://github.com/rails/rails/issues/36383 resolved
use_postgresql(multi_db: true)
generate_models_for_animals
rails "db:create:animals", "db:migrate:animals", "db:create:primary", "db:migrate:primary", "db:schema:dump"
rails "db:drop:primary"
Dog.create!
output = rails("db:prepare")
assert_match(/Created database/, output)
assert_equal 1, Dog.count
ensure
Dog.connection.disconnect!
rails "db:drop" rescue nil
end
end
end
end
end

View file

@ -448,7 +448,24 @@ module TestHelpers
$:.reject! { |path| path =~ %r'/(#{to_remove.join('|')})/' }
end
def use_postgresql
def use_postgresql(multi_db: false)
if multi_db
File.open("#{app_path}/config/database.yml", "w") do |f|
f.puts <<-YAML
default: &default
adapter: postgresql
pool: 5
development:
primary:
<<: *default
database: railties_test
animals:
<<: *default
database: railties_animals_test
migrations_paths: db/animals_migrate
YAML
end
else
File.open("#{app_path}/config/database.yml", "w") do |f|
f.puts <<-YAML
default: &default
@ -463,6 +480,7 @@ module TestHelpers
end
end
end
end
module Reload
def reload