Module: OnlineMigrations::BackgroundSchemaMigrations::MigrationHelpers
- Included in:
- SchemaStatements
- Defined in:
- lib/online_migrations/background_schema_migrations/migration_helpers.rb
Instance Method Summary collapse
- #add_index_in_background(table_name, column_name, **options) ⇒ Object
- #enqueue_background_schema_migration(name, table_name, **options) ⇒ Object
-
#ensure_background_schema_migration_succeeded(migration_name) ⇒ Object
Ensures that the background schema migration with the provided migration name succeeded.
- #remove_index_in_background(table_name, column_name = nil, name:, **options) ⇒ Object
- #validate_constraint_in_background(table_name, constraint_name, **options) ⇒ Object
- #validate_foreign_key_in_background(from_table, to_table = nil, **options) ⇒ Object
Instance Method Details
#add_index_in_background(table_name, column_name, **options) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 6 def add_index_in_background(table_name, column_name, **) = .extract!(:max_attempts, :statement_timeout, :connection_class_name) [:algorithm] = :concurrently index, algorithm, if_not_exists = (table_name, column_name, **) # Need to check this first, because `index_exists?` does not check for `:where`s. if index_name_exists?(table_name, index.name) Utils.raise_or_say(<<~MSG) Index creation was not enqueued because the index with name '#{index.name}' already exists. This can be due to an aborted migration or you need to explicitly provide another name via `:name` option. MSG return end if index_exists?(table_name, column_name, **) Utils.raise_or_say("Index creation was not enqueued because the index already exists.") return end create_index = ActiveRecord::ConnectionAdapters::CreateIndexDefinition.new(index, algorithm, if_not_exists) schema_creation = ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaCreation.new(self) definition = schema_creation.accept(create_index) enqueue_background_schema_migration(index.name, table_name, definition: definition, **) end |
#enqueue_background_schema_migration(name, table_name, **options) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 91 def enqueue_background_schema_migration(name, table_name, **) if [:connection_class_name].nil? && Utils.multiple_databases? raise ArgumentError, "You must pass a :connection_class_name when using multiple databases." end migration = create_background_schema_migration(name, table_name, **) run_inline = OnlineMigrations.config.run_background_migrations_inline if run_inline && run_inline.call runner = MigrationRunner.new(migration) runner.run end migration end |
#ensure_background_schema_migration_succeeded(migration_name) ⇒ Object
Ensures that the background schema migration with the provided migration name succeeded.
If the enqueued migration was not found in development (probably when resetting a dev environment
followed by db:migrate
), then a log warning is printed.
If enqueued migration was not found in production, then the error is raised.
If enqueued migration was found but is not succeeded, then the error is raised.
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 80 def ensure_background_schema_migration_succeeded(migration_name) migration = Migration.parents.find_by(migration_name: migration_name) if migration.nil? Utils.raise_in_prod_or_say_in_dev("Could not find background schema migration: '#{migration_name}'") elsif !migration.succeeded? raise "Expected background schema migration '#{migration_name}' to be marked as 'succeeded', " \ "but it is '#{migration.status}'." end end |
#remove_index_in_background(table_name, column_name = nil, name:, **options) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 34 def remove_index_in_background(table_name, column_name = nil, name:, **) raise ArgumentError, "Index name must be specified" if name.blank? = .extract!(:max_attempts, :statement_timeout, :connection_class_name) if !index_exists?(table_name, column_name, **, name: name) Utils.raise_or_say("Index deletion was not enqueued because the index does not exist.") return end definition = "DROP INDEX CONCURRENTLY IF EXISTS #{quote_column_name(name)}" enqueue_background_schema_migration(name, table_name, definition: definition, **) end |
#validate_constraint_in_background(table_name, constraint_name, **options) ⇒ Object
60 61 62 63 64 65 66 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 60 def validate_constraint_in_background(table_name, constraint_name, **) definition = <<~SQL.squish ALTER TABLE #{quote_table_name(table_name)} VALIDATE CONSTRAINT #{quote_table_name(constraint_name)} SQL enqueue_background_schema_migration(constraint_name, table_name, definition: definition, **) end |
#validate_foreign_key_in_background(from_table, to_table = nil, **options) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 48 def validate_foreign_key_in_background(from_table, to_table = nil, **) = .extract!(:max_attempts, :statement_timeout, :connection_class_name) if !foreign_key_exists?(from_table, to_table, **) Utils.raise_or_say("Foreign key validation was not enqueued because the foreign key does not exist.") return end fk_name_to_validate = foreign_key_for!(from_table, to_table: to_table, **).name validate_constraint_in_background(from_table, fk_name_to_validate, **) end |