diff --git a/CHANGELOG.md b/CHANGELOG.md index 828c3c7..27c4232 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## 1.7.1 (unreleased) +- Added `ignored_databases` option +- Added warning for unsupported adapter - Updated instructions for removing a column to append to `ignored_columns` ## 1.7.0 (2024-01-05) diff --git a/README.md b/README.md index 468d31b..dfd73f6 100644 --- a/README.md +++ b/README.md @@ -797,6 +797,14 @@ By default, checks are disabled when migrating down. Enable them with: StrongMigrations.check_down = true ``` +## Multiple Databases + +Disable all functionality for specific databases with: [unreleased] + +```ruby +StrongMigrations.ignored_databases += [:catalog] +``` + ## Custom Messages To customize specific messages, create an initializer with: diff --git a/lib/strong_migrations.rb b/lib/strong_migrations.rb index 9763593..9dd1121 100644 --- a/lib/strong_migrations.rb +++ b/lib/strong_migrations.rb @@ -29,7 +29,7 @@ class << self :target_postgresql_version, :target_mysql_version, :target_mariadb_version, :enabled_checks, :lock_timeout, :statement_timeout, :check_down, :target_version, :safe_by_default, :target_sql_mode, :lock_timeout_retries, :lock_timeout_retry_delay, - :alphabetize_schema + :alphabetize_schema, :ignored_databases attr_writer :lock_timeout_limit end self.auto_analyze = false @@ -40,6 +40,7 @@ class << self self.safe_by_default = false self.check_down = false self.alphabetize_schema = false + self.ignored_databases = [] # private def self.developer_env? diff --git a/lib/strong_migrations/checker.rb b/lib/strong_migrations/checker.rb index ac9ccea..f33836d 100644 --- a/lib/strong_migrations/checker.rb +++ b/lib/strong_migrations/checker.rb @@ -28,6 +28,8 @@ def self.safety_assured end def perform(method, *args) + return if !enabled? + check_adapter check_version_supported set_timeouts check_lock_timeout @@ -131,6 +133,28 @@ def version_safe? private + def enabled? + return true if StrongMigrations.ignored_databases.empty? + + # Active Record 6.0 supports multiple databases + # but connection.pool.spec.name always returns "primary" + # in migrations with rails db:migrate + if ActiveRecord::VERSION::STRING.to_f < 6.1 + # error class is not shown in db:migrate output so ensure message is descriptive + raise StrongMigrations::Error, "StrongMigrations.ignored_databases is not supported for Active Record < 6.1" + end + + !StrongMigrations.ignored_databases.map(&:to_s).include?(connection.pool.db_config.name) + end + + def check_adapter + if adapter.instance_of?(Adapters::AbstractAdapter) + # TODO raise error in 2.0 + # TODO add database name for Active Record 6.1+ + warn "[strong_migrations] Unsupported adapter: #{connection.adapter_name}. Use StrongMigrations.ignored_databases to silence this warning." + end + end + def check_version_supported return if defined?(@version_checked) diff --git a/lib/strong_migrations/migrator.rb b/lib/strong_migrations/migrator.rb index cda11e9..18503da 100644 --- a/lib/strong_migrations/migrator.rb +++ b/lib/strong_migrations/migrator.rb @@ -6,8 +6,10 @@ def ddl_transaction(migration, *args) # handle MigrationProxy class migration = migration.send(:migration) if migration.respond_to?(:migration, true) - # retry migration since the entire transaction needs to be rerun checker = migration.send(:strong_migrations_checker) + return super unless checker.send(:enabled?) + + # retry migration since the entire transaction needs to be rerun checker.retry_lock_timeouts(check_committed: true) do # failed transaction reverts timeout, so need to re-apply checker.timeouts_set = false diff --git a/test/multiple_databases_test.rb b/test/multiple_databases_test.rb index a3e780b..437f0a5 100644 --- a/test/multiple_databases_test.rb +++ b/test/multiple_databases_test.rb @@ -40,6 +40,30 @@ def test_target_version_unsupported end end + def test_ignored_databases + skip unless multiple_dbs? + + with_ignored_databases([:animals]) do + with_database(:primary) do + assert_unsafe ExecuteArbitrarySQL + end + with_database(:animals) do + assert_safe ExecuteArbitrarySQL + end + end + end + + def test_ignored_databases_unsupported + skip if multiple_dbs? + + with_ignored_databases([:animals]) do + error = assert_raises(StrongMigrations::Error) do + assert_safe ExecuteArbitrarySQL + end + assert_equal "StrongMigrations.ignored_databases is not supported for Active Record < 6.1", error.message + end + end + private def with_database(database, &block) @@ -59,6 +83,13 @@ def with_database(database, &block) ActiveRecord::Base.establish_connection(previous_db_config) if previous_db_config end + def with_ignored_databases(databases) + StrongMigrations.ignored_databases = databases + yield + ensure + StrongMigrations.ignored_databases = [] + end + def multiple_dbs? ActiveRecord::VERSION::STRING.to_f >= 6.1 end