From 5eb4488d02fd975ff5c387a8697fc58cca28b9b4 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Fri, 16 Mar 2018 14:04:09 -0400 Subject: Add ability to create/drop/migrate all dbs for a given env `each_current_configuration` is used by create, drop, and other methods to find the configs for a given environment and returning those to the method calling them. The change here allows for the database commands to operate on all the configs in the environment. Previously we couldn't slice the hashes and iterate over them becasue they could be two tier or could be three tier. By using the database config structs we don't need to care whether we're dealing with a three tier or two tier, we can just parse all the configs based on the environment. This makes it possible for us to run `bin/rails db:create` and it will create all the configs for the dev and test environment ust like it does for a two tier - it creates the db for dev and test. Now `db:create` will create `primary` for dev and test, and `animals` for dev and test if our database.yml looks like: ``` development: primary: etc animals: etc test: primary: etc animals: etc ``` This means that `bin/rails db:create`, `bin/rails db:drop`, and `bin/rails db:migrate` will operate on the dev and test env for both primary and animals ds. --- activerecord/lib/active_record/tasks/database_tasks.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'activerecord/lib/active_record/tasks/database_tasks.rb') diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index af1bbc7e93..705a28eef5 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -261,8 +261,8 @@ module ActiveRecord end def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env) - each_current_configuration(environment) { |configuration, configuration_environment| - load_schema configuration, format, file, configuration_environment + each_current_configuration(environment) { |configuration, spec_name, env| + load_schema configuration, format, file, env } ActiveRecord::Base.establish_connection(environment.to_sym) end @@ -312,10 +312,10 @@ module ActiveRecord environments = [environment] environments << "test" if environment == "development" - ActiveRecord::Base.configurations.slice(*environments).each do |configuration_environment, configuration| - next unless configuration["database"] - - yield configuration, configuration_environment + environments.each do |env| + ActiveRecord::Base.configs_for(env) do |spec_name, configuration| + yield configuration, spec_name, env + end end end -- cgit v1.2.3 From 0f0aa6a275876502e002c054896734d6536ba5cd Mon Sep 17 00:00:00 2001 From: eileencodes Date: Fri, 16 Mar 2018 14:44:20 -0400 Subject: Update schema/structure dump tasks for multi db Adds the ability to dump the schema or structure files for mulitple databases. Loops through the configs for a given env and sets a filename based on the format, then establishes a connection for that config and dumps into the file. --- activerecord/lib/active_record/tasks/database_tasks.rb | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record/tasks/database_tasks.rb') diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index 705a28eef5..e2c292ee56 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -252,14 +252,28 @@ module ActiveRecord end def schema_file(format = ActiveRecord::Base.schema_format) + File.join(db_dir, schema_file_type(format)) + end + + def schema_file_type(format = ActiveRecord::Base.schema_format) case format when :ruby - File.join(db_dir, "schema.rb") + "schema.rb" when :sql - File.join(db_dir, "structure.sql") + "structure.sql" end end + def dump_filename(namespace, format = ActiveRecord::Base.schema_format) + filename = if namespace == "primary" + schema_file_type(format) + else + "#{namespace}_#{schema_file_type(format)}" + end + + ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename) + end + def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env) each_current_configuration(environment) { |configuration, spec_name, env| load_schema configuration, format, file, env -- cgit v1.2.3 From 4e663c1e8d1e643783f157f904b5276e62f65589 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Tue, 20 Mar 2018 13:47:34 -0400 Subject: Refactor configs_for and friends Moves the configs_for and DatabaseConfig struct into it's own file. I was considering doing this in a future refactoring but our set up forced me to move it now. You see there are `mattr_accessor`'s on the Core module that have default settings. For example the `schema_format` defaults to Ruby. So if I call `configs_for` or any methods in the Core module it will reset the `schema_format` to `:ruby`. By moving it to it's own class we can keep the logic contained and avoid this unfortunate issue. The second change here does a double loop over the yaml files. Bear with me... Our tests dictate that we need to load an environment before our rake tasks because we could have something in an environment that the database.yml depends on. There are side-effects to this and I think there's a deeper bug that needs to be fixed but that's for another issue. The gist of the problem is when I was creating the dynamic rake tasks if the yaml that that rake task is calling evaluates code (like erb) that calls the environment configs the code will blow up because the environment is not loaded yet. To avoid this issue we added a new method that simply loads the yaml and does not evaluate the erb or anything in it. We then use that yaml to create the task name. Inside the task name we can then call `load_config` and load the real config to actually call the code internal to the task. I admit, this is gross, but refactoring can't all be pretty all the time and I'm working hard with `@tenderlove` to refactor much more of this code to get to a better place re connection management and rake tasks. --- activerecord/lib/active_record/tasks/database_tasks.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'activerecord/lib/active_record/tasks/database_tasks.rb') diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index e2c292ee56..5787660148 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -134,6 +134,13 @@ module ActiveRecord end end + def for_each + databases = Rails.application.config.load_database_yaml + ActiveRecord::DatabaseConfigurations.configs_for(Rails.env, databases) do |spec_name, _| + yield spec_name + end + end + def create_current(environment = env) each_current_configuration(environment) { |configuration| create configuration @@ -327,7 +334,7 @@ module ActiveRecord environments << "test" if environment == "development" environments.each do |env| - ActiveRecord::Base.configs_for(env) do |spec_name, configuration| + ActiveRecord::DatabaseConfigurations.configs_for(env) do |spec_name, configuration| yield configuration, spec_name, env end end -- cgit v1.2.3