diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 7d5bc5e095..08d59008cb 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,17 @@ +* Allow schema cache path to be defined in the database configuration file. + + For example: + + ``` + development: + adapter: postgresql + database: blog_development + pool: 5 + schema_cache_path: tmp/schema/main.yml + ``` + + *Katrina Owen* + * Deprecate `#remove_connection` in favor of `#remove_connection_pool` when called on the handler. `#remove_connection` is deprecated in order to support returning a `DatabaseConfig` object instead of a `Hash`. Use `#remove_connection_pool`, `#remove_connection` will be removed in 6.2. diff --git a/activerecord/lib/active_record/database_configurations/database_config.rb b/activerecord/lib/active_record/database_configurations/database_config.rb index e52933a456..663a594a36 100644 --- a/activerecord/lib/active_record/database_configurations/database_config.rb +++ b/activerecord/lib/active_record/database_configurations/database_config.rb @@ -65,6 +65,10 @@ module ActiveRecord def for_current_env? env_name == ActiveRecord::ConnectionHandling::DEFAULT_ENV.call end + + def schema_cache_path + raise NotImplementedError + end end end end diff --git a/activerecord/lib/active_record/database_configurations/hash_config.rb b/activerecord/lib/active_record/database_configurations/hash_config.rb index 25177c17eb..b5e17bcd5a 100644 --- a/activerecord/lib/active_record/database_configurations/hash_config.rb +++ b/activerecord/lib/active_record/database_configurations/hash_config.rb @@ -87,6 +87,13 @@ module ActiveRecord def adapter configuration_hash[:adapter] end + + # The path to the schema cache dump file for a database. + # If omitted, the filename will be read from ENV or a + # default will be derived. + def schema_cache_path + configuration_hash[:schema_cache_path] + end end end end diff --git a/activerecord/lib/active_record/railties/databases.rake b/activerecord/lib/active_record/railties/databases.rake index aa7cb721f9..e6a0220a8f 100644 --- a/activerecord/lib/active_record/railties/databases.rake +++ b/activerecord/lib/active_record/railties/databases.rake @@ -407,7 +407,10 @@ 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) - filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name) + filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename( + db_config.spec_name, + schema_cache_path: db_config.schema_cache_path, + ) ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache( ActiveRecord::Base.connection, filename, @@ -418,8 +421,13 @@ db_namespace = namespace :db do desc "Clears a db/schema_cache.yml file." task clear: :load_config do ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config| - filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.spec_name) - rm_f filename, verbose: false + filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename( + db_config.spec_name, + schema_cache_path: db_config.schema_cache_path, + ) + ActiveRecord::Tasks::DatabaseTasks.clear_schema_cache( + filename, + ) end end end diff --git a/activerecord/lib/active_record/tasks/database_tasks.rb b/activerecord/lib/active_record/tasks/database_tasks.rb index f24d3c271e..5fb3a0367a 100644 --- a/activerecord/lib/active_record/tasks/database_tasks.rb +++ b/activerecord/lib/active_record/tasks/database_tasks.rb @@ -409,14 +409,14 @@ module ActiveRecord ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename) end - def cache_dump_filename(namespace) + def cache_dump_filename(namespace, schema_cache_path: nil) filename = if namespace == "primary" "schema_cache.yml" else "#{namespace}_schema_cache.yml" end - ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename) + schema_cache_path || ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename) end def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env) @@ -454,6 +454,10 @@ module ActiveRecord open(filename, "wb") { |f| f.write(YAML.dump(conn.schema_cache)) } end + def clear_schema_cache(filename) + FileUtils.rm_f filename, verbose: false + end + private def resolve_configuration(configuration) Base.configurations.resolve(configuration) diff --git a/activerecord/test/cases/tasks/database_tasks_test.rb b/activerecord/test/cases/tasks/database_tasks_test.rb index bc0e594efa..58aa433916 100644 --- a/activerecord/test/cases/tasks/database_tasks_test.rb +++ b/activerecord/test/cases/tasks/database_tasks_test.rb @@ -208,12 +208,78 @@ module ActiveRecord class DatabaseTasksDumpSchemaCacheTest < ActiveRecord::TestCase def test_dump_schema_cache - path = "/tmp/my_schema_cache.yml" - ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, path) - assert File.file?(path) + Dir.mktmpdir do |dir| + ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, dir) do + path = File.join(dir, "schema_cache.yml") + assert_not File.file?(path) + ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, path) + assert File.file?(path) + end + end ensure ActiveRecord::Base.clear_cache! - FileUtils.rm_rf(path) + end + + def test_clear_schema_cache + Dir.mktmpdir do |dir| + ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, dir) do + path = File.join(dir, "schema_cache.yml") + File.open(path, "wb") do |f| + f.puts "This is a cache." + end + assert File.file?(path) + ActiveRecord::Tasks::DatabaseTasks.clear_schema_cache(path) + assert_not File.file?(path) + end + end + end + + def test_cache_dump_default_filename + old_path = ENV["SCHEMA_CACHE"] + ENV.delete("SCHEMA_CACHE") + + ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "db") do + path = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename("primary") + assert_equal "db/schema_cache.yml", path + end + ensure + ENV["SCHEMA_CACHE"] = old_path + end + + def test_cache_dump_alternate_filename + old_path = ENV["SCHEMA_CACHE"] + ENV.delete("SCHEMA_CACHE") + + ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "db") do + path = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename("alternate") + assert_equal "db/alternate_schema_cache.yml", path + end + ensure + ENV["SCHEMA_CACHE"] = old_path + end + + def test_cache_dump_filename_with_env_override + old_path = ENV["SCHEMA_CACHE"] + ENV["SCHEMA_CACHE"] = "tmp/something.yml" + + ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "db") do + path = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename("primary") + assert_equal "tmp/something.yml", path + end + ensure + ENV["SCHEMA_CACHE"] = old_path + end + + def test_cache_dump_filename_with_path_from_db_config + old_path = ENV["SCHEMA_CACHE"] + ENV.delete("SCHEMA_CACHE") + + ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "db") do + path = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename("primary", schema_cache_path: "tmp/something.yml") + assert_equal "tmp/something.yml", path + end + ensure + ENV["SCHEMA_CACHE"] = old_path end end