mirror of https://github.com/rails/rails
Unify the logic to determine the default schema cache path for a database configuration
When the application has more than one database configuration, only the primary was being loaded by default on boot time. All the other connection pools were loading the schema cache lazily. This logic can be found in:351a8d9bc9/activerecord/lib/active_record/connection_adapters/pool_config.rb (L13)
351a8d9bc9/activerecord/lib/active_record/railtie.rb (L149-L178)
The lazy code path wasn't using the same logic to determine the name of the default schema cache file that the Railties uses, so it was loading the schema cache of the primary config to all the other configs. If no table name coincided nothing bad would happen, but if table names coincided, the schema would be completly wrong in all non-primary connections.
This commit is contained in:
parent
1cf7025b4d
commit
4d1d7d3d1b
|
@ -113,8 +113,12 @@ module ActiveRecord
|
|||
configuration_hash[:schema_cache_path]
|
||||
end
|
||||
|
||||
def default_schema_cache_path
|
||||
"db/schema_cache.yml"
|
||||
def default_schema_cache_path(db_dir = "db")
|
||||
if primary?
|
||||
File.join(db_dir, "schema_cache.yml")
|
||||
else
|
||||
File.join(db_dir, "#{name}_schema_cache.yml")
|
||||
end
|
||||
end
|
||||
|
||||
def lazy_schema_cache_path
|
||||
|
|
|
@ -439,13 +439,10 @@ module ActiveRecord
|
|||
|
||||
def cache_dump_filename(db_config_or_name, schema_cache_path: nil)
|
||||
if db_config_or_name.is_a?(DatabaseConfigurations::DatabaseConfig)
|
||||
filename = if db_config_or_name.primary?
|
||||
"schema_cache.yml"
|
||||
else
|
||||
"#{db_config_or_name.name}_schema_cache.yml"
|
||||
end
|
||||
|
||||
schema_cache_path || db_config_or_name.schema_cache_path || ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
||||
schema_cache_path ||
|
||||
db_config_or_name.schema_cache_path ||
|
||||
ENV["SCHEMA_CACHE"] ||
|
||||
db_config_or_name.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
|
||||
else
|
||||
ActiveRecord.deprecator.deprecation_warning(<<~MSG.squish)
|
||||
Passing a database name to `cache_dump_filename` is deprecated and will be removed in Rails 7.3. Pass a
|
||||
|
|
|
@ -141,11 +141,31 @@ module ActiveRecord
|
|||
assert_equal "db/schema_cache.yml", config.default_schema_cache_path
|
||||
end
|
||||
|
||||
def test_schema_cache_path_default_for_custom_name
|
||||
config = HashConfig.new("default_env", "alternate", adapter: "abstract")
|
||||
assert_equal "db/alternate_schema_cache.yml", config.default_schema_cache_path
|
||||
end
|
||||
|
||||
def test_schema_cache_path_default_for_different_db_dir
|
||||
config = HashConfig.new("default_env", "alternate", adapter: "abstract")
|
||||
assert_equal "my_db/alternate_schema_cache.yml", config.default_schema_cache_path("my_db")
|
||||
end
|
||||
|
||||
def test_schema_cache_path_configuration_hash
|
||||
config = HashConfig.new("default_env", "primary", { schema_cache_path: "db/config_schema_cache.yml", adapter: "abstract" })
|
||||
assert_equal "db/config_schema_cache.yml", config.schema_cache_path
|
||||
end
|
||||
|
||||
def test_lazy_schema_cache_path
|
||||
config = HashConfig.new("default_env", "primary", { schema_cache_path: "db/config_schema_cache.yml", adapter: "abstract" })
|
||||
assert_equal "db/config_schema_cache.yml", config.lazy_schema_cache_path
|
||||
end
|
||||
|
||||
def test_lazy_schema_cache_path_uses_default_if_config_is_not_present
|
||||
config = HashConfig.new("default_env", "alternate", { adapter: "abstract" })
|
||||
assert_equal "db/alternate_schema_cache.yml", config.lazy_schema_cache_path
|
||||
end
|
||||
|
||||
def test_validate_checks_the_adapter_exists
|
||||
config = HashConfig.new("default_env", "primary", adapter: "abstract")
|
||||
assert config.validate!
|
||||
|
|
|
@ -325,6 +325,20 @@ module ActiveRecord
|
|||
ENV["SCHEMA_CACHE"] = old_path
|
||||
end
|
||||
|
||||
def test_cache_dump_default_filename_with_custom_db_dir
|
||||
old_path = ENV["SCHEMA_CACHE"]
|
||||
ENV.delete("SCHEMA_CACHE")
|
||||
|
||||
config = DatabaseConfigurations::HashConfig.new("development", "primary", {})
|
||||
|
||||
ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "my_db") do
|
||||
path = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(config)
|
||||
assert_equal "my_db/schema_cache.yml", path
|
||||
end
|
||||
ensure
|
||||
ENV["SCHEMA_CACHE"] = old_path
|
||||
end
|
||||
|
||||
def test_deprecated_cache_dump_default_filename
|
||||
old_path = ENV["SCHEMA_CACHE"]
|
||||
ENV.delete("SCHEMA_CACHE")
|
||||
|
|
|
@ -810,9 +810,7 @@ module ApplicationTests
|
|||
rails "db:drop" rescue nil
|
||||
end
|
||||
|
||||
# Note that schema cache loader depends on the connection and
|
||||
# does not work for all connections.
|
||||
test "schema_cache is loaded on primary db in multi-db app" do
|
||||
test "schema_cache is loaded on all connection db in multi-db app if it exists for the connection" do
|
||||
require "#{app_path}/config/environment"
|
||||
db_migrate_and_schema_cache_dump
|
||||
|
||||
|
@ -822,11 +820,8 @@ module ApplicationTests
|
|||
cache_tables_a = rails("runner", "p ActiveRecord::Base.connection.schema_cache.columns('books')").strip
|
||||
assert_includes cache_tables_a, "title", "expected cache_tables_a to include a title entry"
|
||||
|
||||
expired_warning = capture(:stderr) do
|
||||
cache_size_b = rails("runner", "p AnimalsBase.connection.schema_cache.size", stderr: true).strip
|
||||
assert_equal "0", cache_size_b
|
||||
end
|
||||
assert_match(/Ignoring .*\.yml because it has expired/, expired_warning)
|
||||
cache_size_b = rails("runner", "p AnimalsBase.connection.schema_cache.size", stderr: true).strip
|
||||
assert_equal "12", cache_size_b, "expected the cache size for animals to be valid since it was dumped"
|
||||
|
||||
cache_tables_b = rails("runner", "p AnimalsBase.connection.schema_cache.columns('dogs')").strip
|
||||
assert_includes cache_tables_b, "name", "expected cache_tables_b to include a name entry"
|
||||
|
|
Loading…
Reference in New Issue