online_migrations 0.33.1 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -2
- data/README.md +4 -3
- data/docs/configuring.md +1 -1
- data/lib/generators/online_migrations/templates/background_migrations_change_status_default.rb.tt +1 -1
- data/lib/generators/online_migrations/templates/initializer.rb.tt +1 -1
- data/lib/online_migrations/background_data_migrations/migration_helpers.rb +12 -3
- data/lib/online_migrations/background_data_migrations/scheduler.rb +22 -5
- data/lib/online_migrations/background_schema_migrations/migration.rb +24 -18
- data/lib/online_migrations/background_schema_migrations/migration_helpers.rb +13 -6
- data/lib/online_migrations/config.rb +1 -1
- data/lib/online_migrations/data_migration.rb +2 -1
- data/lib/online_migrations/error_messages.rb +4 -16
- data/lib/online_migrations/schema_cache.rb +0 -77
- data/lib/online_migrations/schema_statements.rb +2 -7
- data/lib/online_migrations/version.rb +1 -1
- data/lib/online_migrations.rb +1 -6
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b7f1dd28a4540742f77c2a33d7336f4f6f2b12a4f267a1cc556975f7b7122ba4
|
|
4
|
+
data.tar.gz: db448dca841dc39418cd92e5d86108ee0b59b69b72eeda391b0a81a30aa7ce71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b423580e44eefc2f1ff71b2ebdcd15e4ff449f869231aaebe38c4598dc364d817eb3b484a82b7a0cc493727f94d956610ced75ac409092227c2e5cc727935eee
|
|
7
|
+
data.tar.gz: 3287e23ec07a09a1026790ab4747427eafbc70f675fd2cbf7382f302a86f748c3fde45f5a7546b3e66848cd1e12eb86f073ff3e5461471bb35ba79f5b0a160ec
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
## master (unreleased)
|
|
2
2
|
|
|
3
|
+
## 0.34.0 (2026-05-29)
|
|
4
|
+
|
|
5
|
+
- Drop support for Rails < 7.2
|
|
6
|
+
|
|
7
|
+
- Do not schedule background data migrations with non existent data migration classes
|
|
8
|
+
|
|
9
|
+
This prevents a situation when the background data migration was enqueued and started running
|
|
10
|
+
before the deploy completes and the data migration class is available.
|
|
11
|
+
|
|
12
|
+
- Add ability to enqueue background migrations for specific shards (if using sharding)
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
add_index_in_background(:users, :name, connection_class_name: "ApplicationRecord", shard: :shard_one)
|
|
16
|
+
enqueue_background_data_migration("MyMigration", shard: :shard_one)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Fix validating foreign key in `add_reference_concurrently` when multiple foreign keys target the same table
|
|
20
|
+
|
|
21
|
+
## 0.33.2 (2026-03-16)
|
|
22
|
+
|
|
23
|
+
- Fix message for adding to `ignored_columns` when renaming a column
|
|
24
|
+
- Schedule background data migration jobs only after committing the database transaction
|
|
25
|
+
|
|
3
26
|
## 0.33.1 (2026-02-05)
|
|
4
27
|
|
|
5
28
|
- Allow "running" to "enqueued" state transition for stuck background data migrations
|
|
@@ -17,7 +40,7 @@
|
|
|
17
40
|
- Add ability to create delayed background migrations
|
|
18
41
|
|
|
19
42
|
```ruby
|
|
20
|
-
add_index_in_background(:users, :name, delay: true)
|
|
43
|
+
add_index_in_background(:users, :name, connection_class_name: "ApplicationRecord", delay: true)
|
|
21
44
|
enqueue_background_data_migration("MyMigration", delay: true)
|
|
22
45
|
```
|
|
23
46
|
|
|
@@ -94,7 +117,7 @@
|
|
|
94
117
|
- Drop support for Ruby < 3.1 and Rails < 7.1
|
|
95
118
|
- Add check for `change_column` for columns with check constraints
|
|
96
119
|
|
|
97
|
-
- Allow to require safety reason explanation when calling `
|
|
120
|
+
- Allow to require safety reason explanation when calling `safety_assured`
|
|
98
121
|
|
|
99
122
|
```ruby
|
|
100
123
|
# config/initializers/online_migrations.rb
|
data/README.md
CHANGED
|
@@ -17,7 +17,7 @@ See [comparison to `strong_migrations`](#comparison-to-strong_migrations)
|
|
|
17
17
|
## Requirements
|
|
18
18
|
|
|
19
19
|
- Ruby 3.1+
|
|
20
|
-
- Rails 7.
|
|
20
|
+
- Rails 7.2+
|
|
21
21
|
- PostgreSQL 12+
|
|
22
22
|
|
|
23
23
|
For older Ruby and Rails versions you can use older versions of this gem.
|
|
@@ -441,8 +441,9 @@ It will use a combination of a VIEW and column aliasing to work with both column
|
|
|
441
441
|
```
|
|
442
442
|
|
|
443
443
|
4. Replace usages of the old column with a new column in the codebase
|
|
444
|
-
5. If
|
|
445
|
-
(is disabled by default in Active Record >= 7),
|
|
444
|
+
5. If the model has `ignored_columns` set, or you enabled Active Record
|
|
445
|
+
`enumerate_columns_in_select_statements` setting (is disabled by default in Active Record >= 7),
|
|
446
|
+
then you need to ignore the old column:
|
|
446
447
|
|
|
447
448
|
```ruby
|
|
448
449
|
class User < ApplicationRecord
|
data/docs/configuring.md
CHANGED
|
@@ -40,7 +40,7 @@ Check the [source code](https://github.com/fatkodima/online_migrations/blob/mast
|
|
|
40
40
|
|
|
41
41
|
## Requiring safety_assured reason
|
|
42
42
|
|
|
43
|
-
To require safety reason explanation when calling `
|
|
43
|
+
To require safety reason explanation when calling `safety_assured` (disabled by default):
|
|
44
44
|
|
|
45
45
|
```ruby
|
|
46
46
|
config.require_safety_assured_reason = true
|
data/lib/generators/online_migrations/templates/background_migrations_change_status_default.rb.tt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class BackgroundMigrationsChangeStatusDefault < <%= migration_parent %>
|
|
2
2
|
def change
|
|
3
3
|
safety_assured do
|
|
4
4
|
change_column_default :background_data_migrations, :status, from: "enqueued", to: "pending"
|
|
@@ -12,7 +12,7 @@ OnlineMigrations.configure do |config|
|
|
|
12
12
|
# Set the version of the production database so the right checks are run in development.
|
|
13
13
|
# config.target_version = 17
|
|
14
14
|
|
|
15
|
-
# Configure whether to require safety reason explanation when calling #
|
|
15
|
+
# Configure whether to require safety reason explanation when calling #safety_assured.
|
|
16
16
|
config.require_safety_assured_reason = false
|
|
17
17
|
|
|
18
18
|
# Configure whether to perform checks when migrating down.
|
|
@@ -339,6 +339,7 @@ module OnlineMigrations
|
|
|
339
339
|
# @param migration_name [String, Class] Background migration class name
|
|
340
340
|
# @param arguments [Array] Extra arguments to pass to the migration instance when the migration runs
|
|
341
341
|
# @param delay [Boolean] Whether this migration should be delayed and approved by the user to start running.
|
|
342
|
+
# @param shard [String, Symbol] Specific shard this migration will be enqueued for. Defaults to all shards.
|
|
342
343
|
# @option options [Integer] :max_attempts (5) Maximum number of batch run attempts
|
|
343
344
|
# @option options [String, nil] :connection_class_name Class name to use to get connections
|
|
344
345
|
#
|
|
@@ -369,7 +370,7 @@ module OnlineMigrations
|
|
|
369
370
|
# @note For convenience, the enqueued background data migration is run inline
|
|
370
371
|
# in development and test environments
|
|
371
372
|
#
|
|
372
|
-
def enqueue_background_data_migration(migration_name, *arguments, delay: false, **options)
|
|
373
|
+
def enqueue_background_data_migration(migration_name, *arguments, delay: false, shard: nil, **options)
|
|
373
374
|
options.assert_valid_keys(:max_attempts, :iteration_pause, :connection_class_name)
|
|
374
375
|
|
|
375
376
|
migration_name = migration_name.name if migration_name.is_a?(Class)
|
|
@@ -380,8 +381,16 @@ module OnlineMigrations
|
|
|
380
381
|
end
|
|
381
382
|
|
|
382
383
|
connection_class = options[:connection_class_name].constantize
|
|
383
|
-
shards = Utils.shard_names(connection_class)
|
|
384
|
-
|
|
384
|
+
shards = Utils.shard_names(connection_class).map(&:to_s)
|
|
385
|
+
if shards.size == 1
|
|
386
|
+
shards = [nil]
|
|
387
|
+
elsif shard
|
|
388
|
+
shard = shard.to_s
|
|
389
|
+
raise "Unknown shard: #{shard}" if !shards.include?(shard)
|
|
390
|
+
|
|
391
|
+
shards = [shard]
|
|
392
|
+
end
|
|
393
|
+
|
|
385
394
|
status = delay ? :delayed : :pending
|
|
386
395
|
|
|
387
396
|
shards.each do |shard|
|
|
@@ -33,20 +33,27 @@ module OnlineMigrations
|
|
|
33
33
|
relation = Migration.queue_order
|
|
34
34
|
relation = relation.where(shard: shard) if shard
|
|
35
35
|
|
|
36
|
+
migrations_to_enqueue = []
|
|
37
|
+
|
|
36
38
|
with_lock do
|
|
37
39
|
stuck_migrations, active_migrations = relation.running.partition(&:stuck?)
|
|
38
|
-
runnable_migrations = relation.pending + stuck_migrations
|
|
40
|
+
runnable_migrations = migrations_with_existing_classes(relation.pending) + stuck_migrations
|
|
39
41
|
|
|
40
42
|
# Ensure no more than 'concurrency' migrations are running at the same time.
|
|
41
43
|
remaining_to_enqueue = concurrency - active_migrations.count
|
|
42
44
|
if remaining_to_enqueue > 0
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
runnable_migrations.take(remaining_to_enqueue).each do |migration|
|
|
46
|
+
migration.update!(status: :enqueued)
|
|
47
|
+
|
|
48
|
+
migrations_to_enqueue << migration
|
|
46
49
|
end
|
|
47
50
|
end
|
|
48
51
|
end
|
|
49
52
|
|
|
53
|
+
migrations_to_enqueue.each do |migration|
|
|
54
|
+
enqueue_migration(migration)
|
|
55
|
+
end
|
|
56
|
+
|
|
50
57
|
true
|
|
51
58
|
end
|
|
52
59
|
|
|
@@ -64,10 +71,20 @@ module OnlineMigrations
|
|
|
64
71
|
end
|
|
65
72
|
end
|
|
66
73
|
|
|
74
|
+
def migrations_with_existing_classes(migrations)
|
|
75
|
+
migrations.select do |migration|
|
|
76
|
+
# Detect if the data migration class exists.
|
|
77
|
+
# It may not yet exist if the data migration was enqueued before the deploy finished.
|
|
78
|
+
migration.data_migration
|
|
79
|
+
true
|
|
80
|
+
rescue DataMigration::NotFoundError
|
|
81
|
+
false
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
67
85
|
def enqueue_migration(migration)
|
|
68
86
|
job = OnlineMigrations.config.background_data_migrations.job
|
|
69
87
|
job_class = job.constantize
|
|
70
|
-
migration.update!(status: :enqueued)
|
|
71
88
|
|
|
72
89
|
jid = job_class.perform_async(migration.id)
|
|
73
90
|
if jid
|
|
@@ -151,28 +151,28 @@ module OnlineMigrations
|
|
|
151
151
|
# @private
|
|
152
152
|
def run
|
|
153
153
|
on_shard_if_present do
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
154
|
+
with_connection do |connection|
|
|
155
|
+
connection.with_lock_retries do
|
|
156
|
+
statement_timeout = self.statement_timeout || OnlineMigrations.config.statement_timeout
|
|
157
|
+
|
|
158
|
+
with_statement_timeout(connection, statement_timeout) do
|
|
159
|
+
if index_addition?
|
|
160
|
+
index = connection.indexes(table_name).find { |i| name.match?(/\b#{i.name}\b/) }
|
|
161
|
+
if index
|
|
162
|
+
if index.valid?
|
|
163
|
+
return
|
|
164
|
+
else
|
|
165
|
+
connection.remove_index(table_name, name: index.name, algorithm: :concurrently)
|
|
166
|
+
end
|
|
167
167
|
end
|
|
168
168
|
end
|
|
169
|
-
end
|
|
170
169
|
|
|
171
|
-
|
|
170
|
+
connection.execute(definition)
|
|
172
171
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
# Outdated statistics + a new index can hurt performance of existing queries.
|
|
173
|
+
if OnlineMigrations.config.auto_analyze
|
|
174
|
+
connection.execute("ANALYZE #{table_name}")
|
|
175
|
+
end
|
|
176
176
|
end
|
|
177
177
|
end
|
|
178
178
|
end
|
|
@@ -206,6 +206,12 @@ module OnlineMigrations
|
|
|
206
206
|
indexes_in_progress.include?(name)
|
|
207
207
|
end
|
|
208
208
|
|
|
209
|
+
# Extension point, do not remove this method.
|
|
210
|
+
def with_connection(&block)
|
|
211
|
+
# https://github.com/rails/rails/pull/51083
|
|
212
|
+
connection_class.with_connection(&block)
|
|
213
|
+
end
|
|
214
|
+
|
|
209
215
|
def with_statement_timeout(connection, timeout)
|
|
210
216
|
return yield if timeout.nil?
|
|
211
217
|
|
|
@@ -4,7 +4,7 @@ module OnlineMigrations
|
|
|
4
4
|
module BackgroundSchemaMigrations
|
|
5
5
|
module MigrationHelpers
|
|
6
6
|
def add_index_in_background(table_name, column_name, **options)
|
|
7
|
-
migration_options = options.extract!(:max_attempts, :statement_timeout, :connection_class_name, :delay)
|
|
7
|
+
migration_options = options.extract!(:max_attempts, :statement_timeout, :connection_class_name, :delay, :shard)
|
|
8
8
|
|
|
9
9
|
options[:algorithm] = :concurrently
|
|
10
10
|
index, algorithm, if_not_exists = add_index_options(table_name, column_name, **options)
|
|
@@ -34,7 +34,7 @@ module OnlineMigrations
|
|
|
34
34
|
def remove_index_in_background(table_name, column_name = nil, name:, **options)
|
|
35
35
|
raise ArgumentError, "Index name must be specified" if name.blank?
|
|
36
36
|
|
|
37
|
-
migration_options = options.extract!(:max_attempts, :statement_timeout, :connection_class_name, :delay)
|
|
37
|
+
migration_options = options.extract!(:max_attempts, :statement_timeout, :connection_class_name, :delay, :shard)
|
|
38
38
|
|
|
39
39
|
if !index_exists?(table_name, column_name, **options, name: name)
|
|
40
40
|
Utils.raise_or_say("Index deletion was not enqueued because the index does not exist.")
|
|
@@ -46,7 +46,7 @@ module OnlineMigrations
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def validate_foreign_key_in_background(from_table, to_table = nil, **options)
|
|
49
|
-
migration_options = options.extract!(:max_attempts, :statement_timeout, :connection_class_name, :delay)
|
|
49
|
+
migration_options = options.extract!(:max_attempts, :statement_timeout, :connection_class_name, :delay, :shard)
|
|
50
50
|
|
|
51
51
|
if !foreign_key_exists?(from_table, to_table, **options)
|
|
52
52
|
Utils.raise_or_say("Foreign key validation was not enqueued because the foreign key does not exist.")
|
|
@@ -87,7 +87,7 @@ module OnlineMigrations
|
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
def enqueue_background_schema_migration(migration_name, table_name, connection_class_name: nil, delay: false, **options)
|
|
90
|
+
def enqueue_background_schema_migration(migration_name, table_name, connection_class_name: nil, delay: false, shard: nil, **options)
|
|
91
91
|
options.assert_valid_keys(:definition, :max_attempts, :statement_timeout)
|
|
92
92
|
|
|
93
93
|
if Utils.multiple_databases? && !connection_class_name
|
|
@@ -104,8 +104,15 @@ module OnlineMigrations
|
|
|
104
104
|
# Normalize to the real connection class name.
|
|
105
105
|
connection_class_name = connection_class.name
|
|
106
106
|
|
|
107
|
-
shards = Utils.shard_names(connection_class)
|
|
108
|
-
|
|
107
|
+
shards = Utils.shard_names(connection_class).map(&:to_s)
|
|
108
|
+
if shards.size == 1
|
|
109
|
+
shards = [nil]
|
|
110
|
+
elsif shard
|
|
111
|
+
shard = shard.to_s
|
|
112
|
+
raise "Unknown shard: #{shard}" if !shards.include?(shard)
|
|
113
|
+
|
|
114
|
+
shards = [shard]
|
|
115
|
+
end
|
|
109
116
|
|
|
110
117
|
status = delay ? :delayed : :pending
|
|
111
118
|
|
|
@@ -16,6 +16,7 @@ module OnlineMigrations
|
|
|
16
16
|
# @return [DataMigration] the Data Migration with the given name.
|
|
17
17
|
#
|
|
18
18
|
# @raise [NotFoundError] if a Data Migration with the given name does not exist.
|
|
19
|
+
# @raise [ArgumentError] if a Data Migration with the given name is not a subclass of DataMigration.
|
|
19
20
|
#
|
|
20
21
|
def named(name)
|
|
21
22
|
namespace = OnlineMigrations.config.background_data_migrations.migrations_module.constantize
|
|
@@ -26,7 +27,7 @@ module OnlineMigrations
|
|
|
26
27
|
|
|
27
28
|
raise NotFoundError.new("Data Migration #{name} not found", name) if migration.nil?
|
|
28
29
|
if !(migration.is_a?(Class) && migration < self)
|
|
29
|
-
raise
|
|
30
|
+
raise ArgumentError, "#{name} is not a Data Migration"
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
migration
|
|
@@ -148,14 +148,14 @@ It will use a combination of a VIEW and column aliasing to work with both column
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
4. Replace usages of the old column with a new column in the codebase
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
5. If the model has `ignored_columns` set, or you enabled
|
|
152
|
+
`enumerate_columns_in_select_statements`, ignore the old column:
|
|
153
153
|
|
|
154
154
|
self.ignored_columns += [:<%= column_name %>]
|
|
155
155
|
|
|
156
156
|
6. Deploy
|
|
157
157
|
7. Remove the column rename config from step 1
|
|
158
|
-
8. Remove the column ignore from step 5
|
|
158
|
+
8. Remove the column ignore from step 5, if added
|
|
159
159
|
9. Remove the VIEW created in step 3 and finally rename the column:
|
|
160
160
|
|
|
161
161
|
class Finalize<%= migration_name %> < <%= migration_parent %>
|
|
@@ -165,19 +165,7 @@ It will use a combination of a VIEW and column aliasing to work with both column
|
|
|
165
165
|
end
|
|
166
166
|
|
|
167
167
|
10. Deploy
|
|
168
|
-
|
|
169
|
-
5. Deploy
|
|
170
|
-
6. Remove the column rename config from step 1
|
|
171
|
-
7. Remove the VIEW created in step 3 and finally rename the column:
|
|
172
|
-
|
|
173
|
-
class Finalize<%= migration_name %> < <%= migration_parent %>
|
|
174
|
-
def change
|
|
175
|
-
finalize_column_rename :<%= table_name %>, :<%= column_name %>, :<%= new_column %>
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
8. Deploy
|
|
180
|
-
<% end %>",
|
|
168
|
+
",
|
|
181
169
|
|
|
182
170
|
change_column_with_not_null:
|
|
183
171
|
"Changing the type is safe, but setting NOT NULL is not.",
|
|
@@ -3,83 +3,6 @@
|
|
|
3
3
|
module OnlineMigrations
|
|
4
4
|
# @private
|
|
5
5
|
module SchemaCache
|
|
6
|
-
def primary_keys(connection, table_name)
|
|
7
|
-
if (renamed_table = renamed_table?(connection, table_name))
|
|
8
|
-
super(connection, renamed_table)
|
|
9
|
-
elsif renamed_column?(connection, table_name)
|
|
10
|
-
super(connection, column_rename_table(table_name))
|
|
11
|
-
else
|
|
12
|
-
super
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def columns(connection, table_name)
|
|
17
|
-
if (renamed_table = renamed_table?(connection, table_name))
|
|
18
|
-
super(connection, renamed_table)
|
|
19
|
-
elsif renamed_column?(connection, table_name)
|
|
20
|
-
columns = super(connection, column_rename_table(table_name))
|
|
21
|
-
OnlineMigrations.config.column_renames[table_name].each do |old_column_name, new_column_name|
|
|
22
|
-
duplicate_column(old_column_name, new_column_name, columns)
|
|
23
|
-
end
|
|
24
|
-
columns
|
|
25
|
-
else
|
|
26
|
-
super.reject { |column| column.name.end_with?("_for_type_change") }
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def indexes(connection, table_name)
|
|
31
|
-
if (renamed_table = renamed_table?(connection, table_name))
|
|
32
|
-
super(connection, renamed_table)
|
|
33
|
-
elsif renamed_column?(connection, table_name)
|
|
34
|
-
super(connection, column_rename_table(table_name))
|
|
35
|
-
else
|
|
36
|
-
super
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def clear_data_source_cache!(connection, name)
|
|
41
|
-
if (renamed_table = renamed_table?(connection, name))
|
|
42
|
-
super(connection, renamed_table)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
if renamed_column?(connection, name)
|
|
46
|
-
super(connection, column_rename_table(name))
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
super
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
def renamed_table?(connection, table_name)
|
|
54
|
-
table_renames = OnlineMigrations.config.table_renames
|
|
55
|
-
if table_renames.key?(table_name) && connection.view_exists?(table_name)
|
|
56
|
-
table_renames[table_name]
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def renamed_column?(connection, table_name)
|
|
61
|
-
column_renames = OnlineMigrations.config.column_renames
|
|
62
|
-
column_renames.key?(table_name) && connection.view_exists?(table_name)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def column_rename_table(table_name)
|
|
66
|
-
"#{table_name}_column_rename"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def duplicate_column(old_column_name, new_column_name, columns)
|
|
70
|
-
old_column = columns.find { |column| column.name == old_column_name }
|
|
71
|
-
new_column = old_column.dup
|
|
72
|
-
# Active Record defines only reader for :name
|
|
73
|
-
new_column.instance_variable_set(:@name, new_column_name)
|
|
74
|
-
# Correspond to the Active Record freezing of each column
|
|
75
|
-
columns << new_column.freeze
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# @private
|
|
80
|
-
module SchemaCache72
|
|
81
|
-
# Active Record >= 7.2 changed signature of the methods,
|
|
82
|
-
# see https://github.com/rails/rails/pull/48716.
|
|
83
6
|
def primary_keys(pool, table_name)
|
|
84
7
|
if (renamed_table = renamed_table?(pool, table_name))
|
|
85
8
|
super(pool, renamed_table)
|
|
@@ -705,7 +705,7 @@ module OnlineMigrations
|
|
|
705
705
|
add_foreign_key(table_name, foreign_table_name, **foreign_key, column: column_name, validate: false)
|
|
706
706
|
|
|
707
707
|
if foreign_key[:validate] != false
|
|
708
|
-
validate_foreign_key(table_name, foreign_table_name, **foreign_key)
|
|
708
|
+
validate_foreign_key(table_name, foreign_table_name, **foreign_key, column: column_name)
|
|
709
709
|
end
|
|
710
710
|
end
|
|
711
711
|
end
|
|
@@ -992,12 +992,7 @@ module OnlineMigrations
|
|
|
992
992
|
|
|
993
993
|
def __tmp_table_name_for_column_rename(table_name)
|
|
994
994
|
suffix = "_column_rename"
|
|
995
|
-
|
|
996
|
-
# On ActiveRecord 7.1 can use table_name_length instead of max_identifier_length,
|
|
997
|
-
# see https://github.com/rails/rails/pull/45136.
|
|
998
|
-
# Also we need to account for "_pkey", because older versions does not correctly rename
|
|
999
|
-
# tables with long names. Remove when supporting newer versions only.
|
|
1000
|
-
prefix_length = max_identifier_length - "_pkey".size - suffix.length
|
|
995
|
+
prefix_length = max_identifier_length - suffix.length
|
|
1001
996
|
table_name[0, prefix_length] + suffix
|
|
1002
997
|
end
|
|
1003
998
|
end
|
data/lib/online_migrations.rb
CHANGED
|
@@ -116,16 +116,11 @@ module OnlineMigrations
|
|
|
116
116
|
ActiveRecord::Migration.prepend(OnlineMigrations::Migration)
|
|
117
117
|
ActiveRecord::Migrator.prepend(OnlineMigrations::Migrator)
|
|
118
118
|
ActiveRecord::SchemaDumper.prepend(OnlineMigrations::SchemaDumper)
|
|
119
|
+
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(OnlineMigrations::SchemaCache)
|
|
119
120
|
|
|
120
121
|
ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(OnlineMigrations::DatabaseTasks)
|
|
121
122
|
ActiveRecord::Migration::CommandRecorder.include(OnlineMigrations::CommandRecorder)
|
|
122
123
|
|
|
123
|
-
if OnlineMigrations::Utils.ar_version >= 7.2
|
|
124
|
-
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(OnlineMigrations::SchemaCache72)
|
|
125
|
-
else
|
|
126
|
-
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(OnlineMigrations::SchemaCache)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
124
|
if !ActiveRecord::Batches::BatchEnumerator.method_defined?(:use_ranges)
|
|
130
125
|
ActiveRecord::Batches::BatchEnumerator.include(OnlineMigrations::ActiveRecordBatchEnumerator)
|
|
131
126
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: online_migrations
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.34.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- fatkodima
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '7.
|
|
18
|
+
version: '7.2'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '7.
|
|
25
|
+
version: '7.2'
|
|
26
26
|
email:
|
|
27
27
|
- fatkodima123@gmail.com
|
|
28
28
|
executables: []
|
|
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
115
115
|
- !ruby/object:Gem::Version
|
|
116
116
|
version: '0'
|
|
117
117
|
requirements: []
|
|
118
|
-
rubygems_version: 4.0.
|
|
118
|
+
rubygems_version: 4.0.10
|
|
119
119
|
specification_version: 4
|
|
120
120
|
summary: Catch unsafe PostgreSQL migrations in development and run them easier in
|
|
121
121
|
production
|