From 63631e2d5b6a62e56bb102eb00a69feae86ac12c Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 15 Jan 2024 15:50:52 +0100 Subject: [PATCH] Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL` Fix: https://github.com/rails/rails/pull/50745 I went a bit farther and handled all the boolean configs, not just `schema_cache`. Co-Authored-By: Mike Coutermarsh --- activerecord/CHANGELOG.md | 9 ++++ .../database_configurations/url_config.rb | 21 +++++++- .../url_config_test.rb | 53 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 activerecord/test/cases/database_configurations/url_config_test.rb diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 08da22f32f8..53ae9dfcfb3 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,12 @@ +* Make `schema_dump`, `query_cache`, `replica` and `database_tasks` configurable via `DATABASE_URL` + + This wouldn't always work previously because boolean values would be interpreted as strings. + + e.g. `DATABASE_URL=postgres://localhost/foo?schema_dump=false` now properly disable dumping the schema + cache. + + *Mike Coutermarsh*, *Jean Boussier* + * Introduce `ActiveRecord::Transactions::ClassMethods#set_callback` It is identical to `ActiveSupport::Callbacks::ClassMethods#set_callback` diff --git a/activerecord/lib/active_record/database_configurations/url_config.rb b/activerecord/lib/active_record/database_configurations/url_config.rb index fb017e26975..820b5a03a91 100644 --- a/activerecord/lib/active_record/database_configurations/url_config.rb +++ b/activerecord/lib/active_record/database_configurations/url_config.rb @@ -41,10 +41,29 @@ module ActiveRecord super(env_name, name, configuration_hash) @url = url - @configuration_hash = @configuration_hash.merge(build_url_hash).freeze + @configuration_hash = @configuration_hash.merge(build_url_hash) + + if @configuration_hash[:schema_dump] == "false" + @configuration_hash[:schema_dump] = false + end + + if @configuration_hash[:query_cache] == "false" + @configuration_hash[:query_cache] = false + end + + to_boolean!(@configuration_hash, :replica) + to_boolean!(@configuration_hash, :database_tasks) + + @configuration_hash.freeze end private + def to_boolean!(configuration_hash, key) + if configuration_hash[key].is_a?(String) + configuration_hash[key] = configuration_hash[key] != "false" + end + end + # Return a Hash that can be merged into the main config that represents # the passed in url def build_url_hash diff --git a/activerecord/test/cases/database_configurations/url_config_test.rb b/activerecord/test/cases/database_configurations/url_config_test.rb new file mode 100644 index 00000000000..d8511906642 --- /dev/null +++ b/activerecord/test/cases/database_configurations/url_config_test.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require "cases/helper" + +module ActiveRecord + class DatabaseConfigurations + class UrlConfigTest < ActiveRecord::TestCase + def test_schema_dump_parsing + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?schema_dump=false", {}) + assert_nil config.schema_dump + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?schema_dump=db/foo_schema.rb", {}) + assert_equal "db/foo_schema.rb", config.schema_dump + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo", {}) + assert_equal "schema.rb", config.schema_dump + end + + def test_query_cache_parsing + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?query_cache=false", {}) + assert_equal false, config.query_cache + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?query_cache=42", {}) + assert_equal "42", config.query_cache + end + + def test_replica_parsing + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo", {}) + assert_nil config.replica? + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?replica=true", {}) + assert_equal true, config.replica? + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?replica=false", {}) + assert_equal false, config.replica? + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?replica=random", {}) + assert_equal true, config.replica? + end + + def test_database_tasks_parsing + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo", {}) + assert_equal true, config.database_tasks? + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?database_tasks=random", {}) + assert_equal true, config.database_tasks? + + config = UrlConfig.new("default_env", "primary", "postgres://localhost/foo?database_tasks=false", {}) + assert_equal false, config.database_tasks? + end + end + end +end