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
- #create_background_schema_migration(migration_name, table_name, connection_class_name: nil, **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
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 |
#create_background_schema_migration(migration_name, table_name, connection_class_name: nil, **options) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 88 def create_background_schema_migration(migration_name, table_name, connection_class_name: nil, **) .assert_valid_keys(:definition, :max_attempts, :statement_timeout) if connection_class_name connection_class_name = __normalize_connection_class_name(connection_class_name) end Migration.find_or_create_by!(migration_name: migration_name, shard: nil, connection_class_name: connection_class_name) do |migration| migration.assign_attributes(**, table_name: table_name) shards = Utils.shard_names(migration.connection_class) if shards.size > 1 migration.children = shards.map do |shard| child = migration.dup child.shard = shard child end migration.composite = true end end end |
#enqueue_background_schema_migration(name, table_name, **options) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 71 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.
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/online_migrations/background_schema_migrations/migration_helpers.rb', line 60 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 |