strong_migrations 1.6.3 → 1.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd18b6da9358b37dfe07adbda611a65905173b4c4bd1aae1920588002d89afe6
4
- data.tar.gz: 87f5393be68a9c685adbb38a29ac1980615f933f28b1b03634c2618af3db3963
3
+ metadata.gz: 5399a374f21a5e61350adbe125184d43664bc654cd1583804e7b01c9d6240aab
4
+ data.tar.gz: 71e638db667d72b1fdf433eb27cc4f382a6472bd0f75885f5ae244990c1b768a
5
5
  SHA512:
6
- metadata.gz: 4bde3a8af5e9bae18dcf270155afeefb82b726d93c9b49ac7eeee72706af2c85a31401b8eb415b89f2df3c3234ec74b1c5b5fd48404da0b0cdb65d1c5d205099
7
- data.tar.gz: 352f30e395b489175ef038d6bb418266a2ecdb7fb3f7b0df4dd1d5290994efae1962b87b8dc0e4a5a494718a781e7552ef9f530001880f493f497ac374beb6c9
6
+ metadata.gz: 4c8dbc405cb94e4b8eb92a08161cb8689996e7a6ba216b326db27a83151f5dd796d53c42e5b4dd2f8e0cb224f3f6c8f94ff81edd23063438a8143f0d36c507b9
7
+ data.tar.gz: 532f43609d8006f71e325a708a74c45df8161d5957a5173701c77cc22e7dd3111562cbc70b715c6f94c955d08cda0fd43cfc577b9d902cda8a9e1fedcd4693cc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.6.4 (2023-10-17)
2
+
3
+ - Fixed false positives with `revert`
4
+
1
5
  ## 1.6.3 (2023-09-20)
2
6
 
3
7
  - Added support for Trilogy
@@ -241,7 +245,7 @@ Other
241
245
  ## 0.2.2 (2018-02-14)
242
246
 
243
247
  - Friendlier output
244
- - Better method of hooking into ActiveRecord
248
+ - Better method of hooking into Active Record
245
249
 
246
250
  ## 0.2.1 (2018-02-07)
247
251
 
data/README.md CHANGED
@@ -43,7 +43,7 @@ end
43
43
 
44
44
  Deploy the code, then wrap this step in a safety_assured { ... } block.
45
45
 
46
- class RemoveColumn < ActiveRecord::Migration[7.0]
46
+ class RemoveColumn < ActiveRecord::Migration[7.1]
47
47
  def change
48
48
  safety_assured { remove_column :users, :name }
49
49
  end
@@ -96,7 +96,7 @@ You can also add [custom checks](#custom-checks) or [disable specific checks](#d
96
96
  Active Record caches database columns at runtime, so if you drop a column, it can cause exceptions until your app reboots.
97
97
 
98
98
  ```ruby
99
- class RemoveSomeColumnFromUsers < ActiveRecord::Migration[7.0]
99
+ class RemoveSomeColumnFromUsers < ActiveRecord::Migration[7.1]
100
100
  def change
101
101
  remove_column :users, :some_column
102
102
  end
@@ -117,7 +117,7 @@ end
117
117
  3. Write a migration to remove the column (wrap in `safety_assured` block)
118
118
 
119
119
  ```ruby
120
- class RemoveSomeColumnFromUsers < ActiveRecord::Migration[7.0]
120
+ class RemoveSomeColumnFromUsers < ActiveRecord::Migration[7.1]
121
121
  def change
122
122
  safety_assured { remove_column :users, :some_column }
123
123
  end
@@ -134,7 +134,7 @@ end
134
134
  In earlier versions of Postgres, MySQL, and MariaDB, adding a column with a default value to an existing table causes the entire table to be rewritten. During this time, reads and writes are blocked in Postgres, and writes are blocked in MySQL and MariaDB.
135
135
 
136
136
  ```ruby
137
- class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
137
+ class AddSomeColumnToUsers < ActiveRecord::Migration[7.1]
138
138
  def change
139
139
  add_column :users, :some_column, :text, default: "default_value"
140
140
  end
@@ -148,7 +148,7 @@ In Postgres 11+, MySQL 8.0.12+, and MariaDB 10.3.2+, this no longer requires a t
148
148
  Instead, add the column without a default value, then change the default.
149
149
 
150
150
  ```ruby
151
- class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
151
+ class AddSomeColumnToUsers < ActiveRecord::Migration[7.1]
152
152
  def up
153
153
  add_column :users, :some_column, :text
154
154
  change_column_default :users, :some_column, "default_value"
@@ -169,7 +169,7 @@ See the next section for how to backfill.
169
169
  Active Record creates a transaction around each migration, and backfilling in the same transaction that alters a table keeps the table locked for the [duration of the backfill](https://wework.github.io/data/2015/11/05/add-columns-with-default-values-to-large-tables-in-rails-postgres/).
170
170
 
171
171
  ```ruby
172
- class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
172
+ class AddSomeColumnToUsers < ActiveRecord::Migration[7.1]
173
173
  def change
174
174
  add_column :users, :some_column, :text
175
175
  User.update_all some_column: "default_value"
@@ -184,7 +184,7 @@ Also, running a single query to update data can cause issues for large tables.
184
184
  There are three keys to backfilling safely: batching, throttling, and running it outside a transaction. Use the Rails console or a separate migration with `disable_ddl_transaction!`.
185
185
 
186
186
  ```ruby
187
- class BackfillSomeColumn < ActiveRecord::Migration[7.0]
187
+ class BackfillSomeColumn < ActiveRecord::Migration[7.1]
188
188
  disable_ddl_transaction!
189
189
 
190
190
  def up
@@ -203,7 +203,7 @@ end
203
203
  Adding a stored generated column causes the entire table to be rewritten. During this time, reads and writes are blocked in Postgres, and writes are blocked in MySQL and MariaDB.
204
204
 
205
205
  ```ruby
206
- class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
206
+ class AddSomeColumnToUsers < ActiveRecord::Migration[7.1]
207
207
  def change
208
208
  add_column :users, :some_column, :virtual, type: :string, as: "...", stored: true
209
209
  end
@@ -221,7 +221,7 @@ Add a non-generated column and use callbacks or triggers instead (or a virtual g
221
221
  Changing the type of a column causes the entire table to be rewritten. During this time, reads and writes are blocked in Postgres, and writes are blocked in MySQL and MariaDB.
222
222
 
223
223
  ```ruby
224
- class ChangeSomeColumnType < ActiveRecord::Migration[7.0]
224
+ class ChangeSomeColumnType < ActiveRecord::Migration[7.1]
225
225
  def change
226
226
  change_column :users, :some_column, :new_type
227
227
  end
@@ -267,7 +267,7 @@ A safer approach is to:
267
267
  Renaming a column that’s in use will cause errors in your application.
268
268
 
269
269
  ```ruby
270
- class RenameSomeColumn < ActiveRecord::Migration[7.0]
270
+ class RenameSomeColumn < ActiveRecord::Migration[7.1]
271
271
  def change
272
272
  rename_column :users, :some_column, :new_name
273
273
  end
@@ -292,7 +292,7 @@ A safer approach is to:
292
292
  Renaming a table that’s in use will cause errors in your application.
293
293
 
294
294
  ```ruby
295
- class RenameUsersToCustomers < ActiveRecord::Migration[7.0]
295
+ class RenameUsersToCustomers < ActiveRecord::Migration[7.1]
296
296
  def change
297
297
  rename_table :users, :customers
298
298
  end
@@ -317,7 +317,7 @@ A safer approach is to:
317
317
  The `force` option can drop an existing table.
318
318
 
319
319
  ```ruby
320
- class CreateUsers < ActiveRecord::Migration[7.0]
320
+ class CreateUsers < ActiveRecord::Migration[7.1]
321
321
  def change
322
322
  create_table :users, force: true do |t|
323
323
  # ...
@@ -331,7 +331,7 @@ end
331
331
  Create tables without the `force` option.
332
332
 
333
333
  ```ruby
334
- class CreateUsers < ActiveRecord::Migration[7.0]
334
+ class CreateUsers < ActiveRecord::Migration[7.1]
335
335
  def change
336
336
  create_table :users do |t|
337
337
  # ...
@@ -351,7 +351,7 @@ If you intend to drop an existing table, run `drop_table` first.
351
351
  Adding a check constraint blocks reads and writes in Postgres and blocks writes in MySQL and MariaDB while every row is checked.
352
352
 
353
353
  ```ruby
354
- class AddCheckConstraint < ActiveRecord::Migration[7.0]
354
+ class AddCheckConstraint < ActiveRecord::Migration[7.1]
355
355
  def change
356
356
  add_check_constraint :users, "price > 0", name: "price_check"
357
357
  end
@@ -363,7 +363,7 @@ end
363
363
  Add the check constraint without validating existing rows:
364
364
 
365
365
  ```ruby
366
- class AddCheckConstraint < ActiveRecord::Migration[7.0]
366
+ class AddCheckConstraint < ActiveRecord::Migration[7.1]
367
367
  def change
368
368
  add_check_constraint :users, "price > 0", name: "price_check", validate: false
369
369
  end
@@ -373,7 +373,7 @@ end
373
373
  Then validate them in a separate migration.
374
374
 
375
375
  ```ruby
376
- class ValidateCheckConstraint < ActiveRecord::Migration[7.0]
376
+ class ValidateCheckConstraint < ActiveRecord::Migration[7.1]
377
377
  def change
378
378
  validate_check_constraint :users, name: "price_check"
379
379
  end
@@ -389,7 +389,7 @@ end
389
389
  Strong Migrations can’t ensure safety for raw SQL statements. Make really sure that what you’re doing is safe, then use:
390
390
 
391
391
  ```ruby
392
- class ExecuteSQL < ActiveRecord::Migration[7.0]
392
+ class ExecuteSQL < ActiveRecord::Migration[7.1]
393
393
  def change
394
394
  safety_assured { execute "..." }
395
395
  end
@@ -405,7 +405,7 @@ end
405
405
  In Postgres, adding an index non-concurrently blocks writes.
406
406
 
407
407
  ```ruby
408
- class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
408
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.1]
409
409
  def change
410
410
  add_index :users, :some_column
411
411
  end
@@ -417,7 +417,7 @@ end
417
417
  Add indexes concurrently.
418
418
 
419
419
  ```ruby
420
- class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
420
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.1]
421
421
  disable_ddl_transaction!
422
422
 
423
423
  def change
@@ -443,7 +443,7 @@ rails g index table column
443
443
  Rails adds an index non-concurrently to references by default, which blocks writes in Postgres.
444
444
 
445
445
  ```ruby
446
- class AddReferenceToUsers < ActiveRecord::Migration[7.0]
446
+ class AddReferenceToUsers < ActiveRecord::Migration[7.1]
447
447
  def change
448
448
  add_reference :users, :city
449
449
  end
@@ -455,7 +455,7 @@ end
455
455
  Make sure the index is added concurrently.
456
456
 
457
457
  ```ruby
458
- class AddReferenceToUsers < ActiveRecord::Migration[7.0]
458
+ class AddReferenceToUsers < ActiveRecord::Migration[7.1]
459
459
  disable_ddl_transaction!
460
460
 
461
461
  def change
@@ -473,7 +473,7 @@ end
473
473
  In Postgres, adding a foreign key blocks writes on both tables.
474
474
 
475
475
  ```ruby
476
- class AddForeignKeyOnUsers < ActiveRecord::Migration[7.0]
476
+ class AddForeignKeyOnUsers < ActiveRecord::Migration[7.1]
477
477
  def change
478
478
  add_foreign_key :users, :orders
479
479
  end
@@ -483,7 +483,7 @@ end
483
483
  or
484
484
 
485
485
  ```ruby
486
- class AddReferenceToUsers < ActiveRecord::Migration[7.0]
486
+ class AddReferenceToUsers < ActiveRecord::Migration[7.1]
487
487
  def change
488
488
  add_reference :users, :order, foreign_key: true
489
489
  end
@@ -495,7 +495,7 @@ end
495
495
  Add the foreign key without validating existing rows:
496
496
 
497
497
  ```ruby
498
- class AddForeignKeyOnUsers < ActiveRecord::Migration[7.0]
498
+ class AddForeignKeyOnUsers < ActiveRecord::Migration[7.1]
499
499
  def change
500
500
  add_foreign_key :users, :orders, validate: false
501
501
  end
@@ -505,7 +505,7 @@ end
505
505
  Then validate them in a separate migration.
506
506
 
507
507
  ```ruby
508
- class ValidateForeignKeyOnUsers < ActiveRecord::Migration[7.0]
508
+ class ValidateForeignKeyOnUsers < ActiveRecord::Migration[7.1]
509
509
  def change
510
510
  validate_foreign_key :users, :orders
511
511
  end
@@ -537,7 +537,7 @@ end
537
537
  In Postgres, there’s no equality operator for the `json` column type, which can cause errors for existing `SELECT DISTINCT` queries in your application.
538
538
 
539
539
  ```ruby
540
- class AddPropertiesToUsers < ActiveRecord::Migration[7.0]
540
+ class AddPropertiesToUsers < ActiveRecord::Migration[7.1]
541
541
  def change
542
542
  add_column :users, :properties, :json
543
543
  end
@@ -549,7 +549,7 @@ end
549
549
  Use `jsonb` instead.
550
550
 
551
551
  ```ruby
552
- class AddPropertiesToUsers < ActiveRecord::Migration[7.0]
552
+ class AddPropertiesToUsers < ActiveRecord::Migration[7.1]
553
553
  def change
554
554
  add_column :users, :properties, :jsonb
555
555
  end
@@ -565,7 +565,7 @@ end
565
565
  In Postgres, setting `NOT NULL` on an existing column blocks reads and writes while every row is checked.
566
566
 
567
567
  ```ruby
568
- class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
568
+ class SetSomeColumnNotNull < ActiveRecord::Migration[7.1]
569
569
  def change
570
570
  change_column_null :users, :some_column, false
571
571
  end
@@ -576,10 +576,10 @@ end
576
576
 
577
577
  Instead, add a check constraint.
578
578
 
579
- For Rails 6.1, use:
579
+ For Rails 6.1+, use:
580
580
 
581
581
  ```ruby
582
- class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
582
+ class SetSomeColumnNotNull < ActiveRecord::Migration[7.1]
583
583
  def change
584
584
  add_check_constraint :users, "some_column IS NOT NULL", name: "users_some_column_null", validate: false
585
585
  end
@@ -600,10 +600,10 @@ end
600
600
 
601
601
  Then validate it in a separate migration. A `NOT NULL` check constraint is [functionally equivalent](https://medium.com/doctolib/adding-a-not-null-constraint-on-pg-faster-with-minimal-locking-38b2c00c4d1c) to setting `NOT NULL` on the column (but it won’t show up in `schema.rb` in Rails < 6.1). In Postgres 12+, once the check constraint is validated, you can safely set `NOT NULL` on the column and drop the check constraint.
602
602
 
603
- For Rails 6.1, use:
603
+ For Rails 6.1+, use:
604
604
 
605
605
  ```ruby
606
- class ValidateSomeColumnNotNull < ActiveRecord::Migration[7.0]
606
+ class ValidateSomeColumnNotNull < ActiveRecord::Migration[7.1]
607
607
  def change
608
608
  validate_check_constraint :users, name: "users_some_column_null"
609
609
 
@@ -656,7 +656,7 @@ Disable partial writes in `config/application.rb`. For Rails < 7, use:
656
656
  config.active_record.partial_writes = false
657
657
  ```
658
658
 
659
- For Rails 7, use:
659
+ For Rails 7+, use:
660
660
 
661
661
  ```ruby
662
662
  config.active_record.partial_inserts = false
@@ -669,7 +669,7 @@ config.active_record.partial_inserts = false
669
669
  Adding a non-unique index with more than three columns rarely improves performance.
670
670
 
671
671
  ```ruby
672
- class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
672
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.1]
673
673
  def change
674
674
  add_index :users, [:a, :b, :c, :d]
675
675
  end
@@ -681,7 +681,7 @@ end
681
681
  Instead, start an index with columns that narrow down the results the most.
682
682
 
683
683
  ```ruby
684
- class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
684
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.1]
685
685
  def change
686
686
  add_index :users, [:b, :d]
687
687
  end
@@ -695,7 +695,7 @@ For Postgres, be sure to add them concurrently.
695
695
  To mark a step in the migration as safe, despite using a method that might otherwise be dangerous, wrap it in a `safety_assured` block.
696
696
 
697
697
  ```ruby
698
- class MySafeMigration < ActiveRecord::Migration[7.0]
698
+ class MySafeMigration < ActiveRecord::Migration[7.1]
699
699
  def change
700
700
  safety_assured { remove_column :users, :some_column }
701
701
  end
@@ -793,25 +793,6 @@ ALTER ROLE myuser SET statement_timeout = '1h';
793
793
 
794
794
  Note: If you use PgBouncer in transaction mode, you must set timeouts on the database user.
795
795
 
796
- ## Lock Timeout Retries [experimental]
797
-
798
- There’s the option to automatically retry statements when the lock timeout is reached. Here’s how it works:
799
-
800
- - If a lock timeout happens outside a transaction, the statement is retried
801
- - If it happens inside the DDL transaction, the entire migration is retried (only applicable to Postgres)
802
-
803
- Add to `config/initializers/strong_migrations.rb`:
804
-
805
- ```ruby
806
- StrongMigrations.lock_timeout_retries = 3
807
- ```
808
-
809
- Set the delay between retries with:
810
-
811
- ```ruby
812
- StrongMigrations.lock_timeout_retry_delay = 10.seconds
813
- ```
814
-
815
796
  ## App Timeouts
816
797
 
817
798
  We recommend adding timeouts to `config/database.yml` to prevent connections from hanging and individual queries from taking up too many resources in controllers, jobs, the Rails console, and other places.
@@ -855,12 +836,31 @@ production:
855
836
 
856
837
  For HTTP connections, Redis, and other services, check out [this guide](https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts).
857
838
 
839
+ ## Lock Timeout Retries [experimental]
840
+
841
+ There’s the option to automatically retry statements for migrations when the lock timeout is reached. Here’s how it works:
842
+
843
+ - If a lock timeout happens outside a transaction, the statement is retried
844
+ - If it happens inside the DDL transaction, the entire migration is retried (only applicable to Postgres)
845
+
846
+ Add to `config/initializers/strong_migrations.rb`:
847
+
848
+ ```ruby
849
+ StrongMigrations.lock_timeout_retries = 3
850
+ ```
851
+
852
+ Set the delay between retries with:
853
+
854
+ ```ruby
855
+ StrongMigrations.lock_timeout_retry_delay = 10.seconds
856
+ ```
857
+
858
858
  ## Existing Migrations
859
859
 
860
860
  To mark migrations as safe that were created before installing this gem, create an initializer with:
861
861
 
862
862
  ```ruby
863
- StrongMigrations.start_after = 20170101000000
863
+ StrongMigrations.start_after = 20230101000000
864
864
  ```
865
865
 
866
866
  Use the version from your latest migration.
@@ -123,6 +123,10 @@ module StrongMigrations
123
123
  end
124
124
  end
125
125
 
126
+ def version_safe?
127
+ version && version <= StrongMigrations.start_after
128
+ end
129
+
126
130
  private
127
131
 
128
132
  def check_version_supported
@@ -163,11 +167,7 @@ module StrongMigrations
163
167
  end
164
168
 
165
169
  def safe?
166
- self.class.safe || ENV["SAFETY_ASSURED"] || (direction == :down && !StrongMigrations.check_down) || version_safe?
167
- end
168
-
169
- def version_safe?
170
- version && version <= StrongMigrations.start_after
170
+ self.class.safe || ENV["SAFETY_ASSURED"] || (direction == :down && !StrongMigrations.check_down) || version_safe? || @migration.reverting?
171
171
  end
172
172
 
173
173
  def version
@@ -20,6 +20,14 @@ module StrongMigrations
20
20
  end
21
21
  ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
22
22
 
23
+ def revert(*)
24
+ if strong_migrations_checker.version_safe?
25
+ safety_assured { super }
26
+ else
27
+ super
28
+ end
29
+ end
30
+
23
31
  def safety_assured
24
32
  strong_migrations_checker.class.safety_assured do
25
33
  yield
@@ -1,3 +1,3 @@
1
1
  module StrongMigrations
2
- VERSION = "1.6.3"
2
+ VERSION = "1.6.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strong_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-09-20 00:00:00.000000000 Z
13
+ date: 2023-10-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord