Merge pull request #46134 from eikes/remove-dummy-erb-compiler
Facilitate use of any regular ERB in database.yml
This commit is contained in:
commit
5b8421f56e
@ -46,10 +46,6 @@
|
||||
# Highlight code that triggered database queries in logs.
|
||||
config.active_record.verbose_query_logs = true
|
||||
|
||||
# Show a warning when Rails couldn't parse your database.yml
|
||||
# for multiple databases.
|
||||
config.active_record.suppress_multiple_database_warning = false
|
||||
|
||||
# Debug mode disables concatenation and preprocessing of assets.
|
||||
# This option may cause significant delays in view rendering with a large
|
||||
# number of complex assets.
|
||||
|
@ -46,10 +46,6 @@
|
||||
# Highlight code that triggered database queries in logs.
|
||||
config.active_record.verbose_query_logs = true
|
||||
|
||||
# Show a warning when Rails couldn't parse your database.yml
|
||||
# for multiple databases.
|
||||
config.active_record.suppress_multiple_database_warning = false
|
||||
|
||||
# Debug mode disables concatenation and preprocessing of assets.
|
||||
# This option may cause significant delays in view rendering with a large
|
||||
# number of complex assets.
|
||||
|
@ -1,3 +1,12 @@
|
||||
* Allow any ERB in the database.yml when creating rake tasks.
|
||||
|
||||
Any ERB can be used in `database.yml` even if it accesses environment
|
||||
configurations.
|
||||
|
||||
Deprecates `config.active_record.suppress_multiple_database_warning`.
|
||||
|
||||
*Eike Send*
|
||||
|
||||
* Add table to error for duplicate column definitions.
|
||||
|
||||
If a migration defines duplicate columns for a table, the error message
|
||||
|
@ -336,12 +336,19 @@ def self.global_executor_concurrency # :nodoc:
|
||||
singleton_class.attr_accessor :dump_schemas
|
||||
self.dump_schemas = :schema_search_path
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Show a warning when Rails couldn't parse your database.yml
|
||||
# for multiple databases.
|
||||
singleton_class.attr_accessor :suppress_multiple_database_warning
|
||||
self.suppress_multiple_database_warning = false
|
||||
def self.suppress_multiple_database_warning
|
||||
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
||||
config.active_record.suppress_multiple_database_warning is deprecated and will be removed in Rails 7.2.
|
||||
It no longer has any effect and should be removed from the configuration file.
|
||||
MSG
|
||||
end
|
||||
|
||||
def self.suppress_multiple_database_warning=(value)
|
||||
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
||||
config.active_record.suppress_multiple_database_warning= is deprecated and will be removed in Rails 7.2.
|
||||
It no longer has any effect and should be removed from the configuration file.
|
||||
MSG
|
||||
end
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
|
@ -140,15 +140,7 @@ def create_all
|
||||
def setup_initial_database_yaml
|
||||
return {} unless defined?(Rails)
|
||||
|
||||
begin
|
||||
Rails.application.config.load_database_yaml
|
||||
rescue
|
||||
unless ActiveRecord.suppress_multiple_database_warning
|
||||
$stderr.puts "Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB."
|
||||
end
|
||||
|
||||
{}
|
||||
end
|
||||
Rails.application.config.load_database_yaml
|
||||
end
|
||||
|
||||
def for_each(databases)
|
||||
|
@ -376,24 +376,34 @@ def paths
|
||||
end
|
||||
end
|
||||
|
||||
# Load the database YAML without evaluating ERB. This allows us to
|
||||
# create the rake tasks for multiple databases without filling in the
|
||||
# configuration values or loading the environment. Do not use this
|
||||
# method.
|
||||
# Load the <tt>config/database.yml</tt> to create the Rake tasks for
|
||||
# multiple databases without loading the environment and filling in the
|
||||
# environment specific configuration values.
|
||||
#
|
||||
# This uses a DummyERB custom compiler so YAML can ignore the ERB
|
||||
# tags and load the database.yml for the rake tasks.
|
||||
# Do not use this method, use #database_configuration instead.
|
||||
def load_database_yaml # :nodoc:
|
||||
if path = paths["config/database"].existent.first
|
||||
require "rails/application/dummy_erb_compiler"
|
||||
require "rails/application/dummy_config"
|
||||
|
||||
yaml = DummyERB.new(Pathname.new(path).read).result
|
||||
original_rails_config = Rails.application.config
|
||||
dummy_config = DummyConfig.new(original_rails_config)
|
||||
database_config = {}
|
||||
|
||||
if YAML.respond_to?(:unsafe_load)
|
||||
YAML.unsafe_load(yaml) || {}
|
||||
else
|
||||
YAML.load(yaml) || {}
|
||||
begin
|
||||
Rails.application.config = dummy_config
|
||||
|
||||
yaml = ERB.new(Pathname.new(path).read).result
|
||||
|
||||
if YAML.respond_to?(:unsafe_load)
|
||||
database_config = YAML.unsafe_load(yaml) || {}
|
||||
else
|
||||
database_config = YAML.load(yaml) || {}
|
||||
end
|
||||
ensure
|
||||
Rails.application.config = original_rails_config
|
||||
end
|
||||
|
||||
database_config
|
||||
else
|
||||
{}
|
||||
end
|
||||
|
19
railties/lib/rails/application/dummy_config.rb
Normal file
19
railties/lib/rails/application/dummy_config.rb
Normal file
@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DummyConfig # :nodoc:
|
||||
def initialize(config)
|
||||
@config = config
|
||||
end
|
||||
|
||||
def to_s
|
||||
"DummyConfig"
|
||||
end
|
||||
|
||||
def method_missing(selector, *args, &blk)
|
||||
if @config.respond_to?(selector)
|
||||
@config.send(selector, *args, &blk)
|
||||
else
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
@ -1,18 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# These classes are used to strip out the ERB configuration
|
||||
# values so we can evaluate the database.yml without evaluating
|
||||
# the ERB values.
|
||||
class DummyERB < ERB # :nodoc:
|
||||
def make_compiler(trim_mode)
|
||||
DummyCompiler.new trim_mode
|
||||
end
|
||||
end
|
||||
|
||||
class DummyCompiler < ERB::Compiler # :nodoc:
|
||||
def compile_content(stag, out)
|
||||
if stag == "<%="
|
||||
out.push "_erbout << ''"
|
||||
end
|
||||
end
|
||||
end
|
@ -1769,9 +1769,16 @@ def index
|
||||
assert_not ActiveRecord.verbose_query_logs
|
||||
end
|
||||
|
||||
test "config.active_record.suppress_multiple_database_warning is false by default in development" do
|
||||
test "config.active_record.suppress_multiple_database_warning getter is deprecated" do
|
||||
app "development"
|
||||
assert_not ActiveRecord.suppress_multiple_database_warning
|
||||
|
||||
assert_deprecated { ActiveRecord.suppress_multiple_database_warning }
|
||||
end
|
||||
|
||||
test "config.active_record.suppress_multiple_database_warning setter is deprecated" do
|
||||
app "development"
|
||||
|
||||
assert_deprecated { ActiveRecord.suppress_multiple_database_warning = true }
|
||||
end
|
||||
|
||||
test "config.active_record.use_yaml_unsafe_load is false by default" do
|
||||
|
@ -40,15 +40,6 @@ def db_create_and_drop(expected_database, environment_loaded: true)
|
||||
end
|
||||
end
|
||||
|
||||
def db_create_with_warning(expected_database)
|
||||
Dir.chdir(app_path) do
|
||||
output = rails("db:create")
|
||||
assert_match(/Rails couldn't infer whether you are using multiple databases/, output)
|
||||
assert_match(/Created database/, output)
|
||||
assert File.exist?(expected_database)
|
||||
end
|
||||
end
|
||||
|
||||
test "db:create and db:drop without database URL" do
|
||||
require "#{app_path}/config/environment"
|
||||
db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: "primary")
|
||||
@ -100,6 +91,25 @@ def db_create_with_warning(expected_database)
|
||||
db_create_and_drop("db/development.sqlite3", environment_loaded: false)
|
||||
end
|
||||
|
||||
test "db:create and db:drop don't raise errors when loading YAML with alias ERB" do
|
||||
app_file "config/database.yml", <<-YAML
|
||||
sqlite: &sqlite
|
||||
adapter: sqlite3
|
||||
database: db/development.sqlite3
|
||||
|
||||
development:
|
||||
<<: *<%= ENV["DB"] || "sqlite" %>
|
||||
YAML
|
||||
|
||||
app_file "config/environments/development.rb", <<-RUBY
|
||||
Rails.application.configure do
|
||||
config.database = "db/development.sqlite3"
|
||||
end
|
||||
RUBY
|
||||
|
||||
db_create_and_drop("db/development.sqlite3", environment_loaded: false)
|
||||
end
|
||||
|
||||
test "db:create and db:drop don't raise errors when loading YAML with multiline ERB" do
|
||||
app_file "config/database.yml", <<-YAML
|
||||
development:
|
||||
@ -118,23 +128,21 @@ def db_create_with_warning(expected_database)
|
||||
db_create_and_drop("db/development.sqlite3", environment_loaded: false)
|
||||
end
|
||||
|
||||
test "db:create and db:drop show warning but doesn't raise errors when loading YAML with alias ERB" do
|
||||
test "db:create and db:drop don't raise errors when loading ERB accessing nested configurations" do
|
||||
app_file "config/database.yml", <<-YAML
|
||||
sqlite: &sqlite
|
||||
adapter: sqlite3
|
||||
database: db/development.sqlite3
|
||||
|
||||
development:
|
||||
<<: *<%= ENV["DB"] || "sqlite" %>
|
||||
database: db/development.sqlite3
|
||||
adapter: sqlite3
|
||||
other: <%= Rails.application.config.other.value %>
|
||||
YAML
|
||||
|
||||
app_file "config/environments/development.rb", <<-RUBY
|
||||
Rails.application.configure do
|
||||
config.database = "db/development.sqlite3"
|
||||
config.other = OpenStruct.new(value: 123)
|
||||
end
|
||||
RUBY
|
||||
|
||||
db_create_with_warning("db/development.sqlite3")
|
||||
db_create_and_drop("db/development.sqlite3", environment_loaded: false)
|
||||
end
|
||||
|
||||
test "db:create and db:drop don't raise errors when loading YAML containing conditional statements in ERB" do
|
||||
|
@ -958,6 +958,19 @@ class TwoMigration < ActiveRecord::Migration::Current
|
||||
db_create_and_drop_namespace("primary", "db/development.sqlite3")
|
||||
end
|
||||
|
||||
test "db:create and db:drop don't raise errors when loading YAML containing ERB in database keys" do
|
||||
app_file "config/database.yml", <<-YAML
|
||||
development:
|
||||
<% 5.times do |i| %>
|
||||
shard_<%= i %>:
|
||||
database: db/development_shard_<%= i %>.sqlite3
|
||||
adapter: sqlite3
|
||||
<% end %>
|
||||
YAML
|
||||
|
||||
db_create_and_drop_namespace("shard_3", "db/development_shard_3.sqlite3")
|
||||
end
|
||||
|
||||
test "schema generation when dump_schema_after_migration is true schema_dump is false" do
|
||||
app_file "config/database.yml", <<~EOS
|
||||
development:
|
||||
|
Loading…
Reference in New Issue
Block a user