strong_migrations 0.7.6 → 0.8.0

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: f16481df30c6b961477b4a537034097aa1d41a262bd7f2741c40b7e6dae9cb9e
4
- data.tar.gz: 816bc9a4f9810bce6ac6d5e0a52b185800515794ca5e3d27b5f4d512a9190115
3
+ metadata.gz: 1f885cc0a8b0fb30e3bc4d000e82584fdf3850943563b4b426d3cfc39d70015c
4
+ data.tar.gz: d0dd29ea45ccc3b7c571e8bf03fa98c401d5489d1f5459488a0eff411cf6880e
5
5
  SHA512:
6
- metadata.gz: 2ac9f7c38958c1cc2e80efa3f895730087ac92a3675be31c308f9f8df827ced3323ca8bc3e69c99e2a79b92ef0a5a8b595a76715bf55c45b5698fcdd43b5a586
7
- data.tar.gz: 2cee8d3013ae8780f0bcbce33f22a219375c29f059335902cdfe2285ec557307229b7ec4544e6be59ea1ee7cd039f2b23e9b3693efc41f11f677cbbed1495896
6
+ metadata.gz: c03a023d4c593d2868e524ca0f3e7ebd93e07e087e02f0d7090210b00fdb1fdc50d2abb74ab7df4131bddc6052fc5b9c10ce902ede8c708927476e40ad49d07f
7
+ data.tar.gz: 479e34db0101a15e1db1a593f01773da5665baa5cda3403ad32ea58dca00a0d0faee0ef813cf1975b7e9f99f1591e7f4f2be5c456c96fd6ae4633b48b6a0b3b4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## 0.8.0 (2022-02-09)
2
+
3
+ - Fixed error with versioned schema with Active Record 7.0.2+
4
+ - Dropped support for Ruby < 2.6 and Active Record < 5.2
5
+
6
+ ## 0.7.9 (2021-12-15)
7
+
8
+ - Fixed error with multiple databases with Active Record 7
9
+
10
+ ## 0.7.8 (2021-08-03)
11
+
12
+ - Fixed issue with `add_reference ..., foreign_key: {to_table: ...}` with `safe_by_default`
13
+
14
+ ## 0.7.7 (2021-06-07)
15
+
16
+ - Removed timeouts and `auto_analyze` from schema load
17
+
1
18
  ## 0.7.6 (2021-01-17)
2
19
 
3
20
  - Fixed `NOT NULL` constraint check for quoted columns
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Bob Remeika and David Waller, 2015-2021 Andrew Kane
1
+ Copyright (c) 2013 Bob Remeika and David Waller, 2015-2022 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -15,7 +15,7 @@ Supports for PostgreSQL, MySQL, and MariaDB
15
15
  Add this line to your application’s Gemfile:
16
16
 
17
17
  ```ruby
18
- gem 'strong_migrations'
18
+ gem "strong_migrations"
19
19
  ```
20
20
 
21
21
  And run:
@@ -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[6.1]
46
+ class RemoveColumn < ActiveRecord::Migration[7.0]
47
47
  def change
48
48
  safety_assured { remove_column :users, :name }
49
49
  end
@@ -90,7 +90,7 @@ You can also add [custom checks](#custom-checks) or [disable specific checks](#d
90
90
  Active Record caches database columns at runtime, so if you drop a column, it can cause exceptions until your app reboots.
91
91
 
92
92
  ```ruby
93
- class RemoveSomeColumnFromUsers < ActiveRecord::Migration[6.1]
93
+ class RemoveSomeColumnFromUsers < ActiveRecord::Migration[7.0]
94
94
  def change
95
95
  remove_column :users, :some_column
96
96
  end
@@ -111,7 +111,7 @@ end
111
111
  3. Write a migration to remove the column (wrap in `safety_assured` block)
112
112
 
113
113
  ```ruby
114
- class RemoveSomeColumnFromUsers < ActiveRecord::Migration[6.1]
114
+ class RemoveSomeColumnFromUsers < ActiveRecord::Migration[7.0]
115
115
  def change
116
116
  safety_assured { remove_column :users, :some_column }
117
117
  end
@@ -119,6 +119,7 @@ end
119
119
  ```
120
120
 
121
121
  4. Deploy and run migration
122
+ 5. Remove the line added in step 1
122
123
 
123
124
  ### Adding a column with a default value
124
125
 
@@ -127,7 +128,7 @@ end
127
128
  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.
128
129
 
129
130
  ```ruby
130
- class AddSomeColumnToUsers < ActiveRecord::Migration[6.1]
131
+ class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
131
132
  def change
132
133
  add_column :users, :some_column, :text, default: "default_value"
133
134
  end
@@ -141,7 +142,7 @@ In Postgres 11+, MySQL 8.0.12+, and MariaDB 10.3.2+, this no longer requires a t
141
142
  Instead, add the column without a default value, then change the default.
142
143
 
143
144
  ```ruby
144
- class AddSomeColumnToUsers < ActiveRecord::Migration[6.1]
145
+ class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
145
146
  def up
146
147
  add_column :users, :some_column, :text
147
148
  change_column_default :users, :some_column, "default_value"
@@ -162,7 +163,7 @@ See the next section for how to backfill.
162
163
  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/).
163
164
 
164
165
  ```ruby
165
- class AddSomeColumnToUsers < ActiveRecord::Migration[6.1]
166
+ class AddSomeColumnToUsers < ActiveRecord::Migration[7.0]
166
167
  def change
167
168
  add_column :users, :some_column, :text
168
169
  User.update_all some_column: "default_value"
@@ -177,7 +178,7 @@ Also, running a single query to update data can cause issues for large tables.
177
178
  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!`.
178
179
 
179
180
  ```ruby
180
- class BackfillSomeColumn < ActiveRecord::Migration[6.1]
181
+ class BackfillSomeColumn < ActiveRecord::Migration[7.0]
181
182
  disable_ddl_transaction!
182
183
 
183
184
  def up
@@ -196,7 +197,7 @@ end
196
197
  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.
197
198
 
198
199
  ```ruby
199
- class ChangeSomeColumnType < ActiveRecord::Migration[6.1]
200
+ class ChangeSomeColumnType < ActiveRecord::Migration[7.0]
200
201
  def change
201
202
  change_column :users, :some_column, :new_type
202
203
  end
@@ -235,7 +236,7 @@ A safer approach is to:
235
236
  Renaming a column that’s in use will cause errors in your application.
236
237
 
237
238
  ```ruby
238
- class RenameSomeColumn < ActiveRecord::Migration[6.1]
239
+ class RenameSomeColumn < ActiveRecord::Migration[7.0]
239
240
  def change
240
241
  rename_column :users, :some_column, :new_name
241
242
  end
@@ -260,7 +261,7 @@ A safer approach is to:
260
261
  Renaming a table that’s in use will cause errors in your application.
261
262
 
262
263
  ```ruby
263
- class RenameUsersToCustomers < ActiveRecord::Migration[6.1]
264
+ class RenameUsersToCustomers < ActiveRecord::Migration[7.0]
264
265
  def change
265
266
  rename_table :users, :customers
266
267
  end
@@ -285,7 +286,7 @@ A safer approach is to:
285
286
  The `force` option can drop an existing table.
286
287
 
287
288
  ```ruby
288
- class CreateUsers < ActiveRecord::Migration[6.1]
289
+ class CreateUsers < ActiveRecord::Migration[7.0]
289
290
  def change
290
291
  create_table :users, force: true do |t|
291
292
  # ...
@@ -299,7 +300,7 @@ end
299
300
  Create tables without the `force` option.
300
301
 
301
302
  ```ruby
302
- class CreateUsers < ActiveRecord::Migration[6.1]
303
+ class CreateUsers < ActiveRecord::Migration[7.0]
303
304
  def change
304
305
  create_table :users do |t|
305
306
  # ...
@@ -319,7 +320,7 @@ If you intend to drop an existing table, run `drop_table` first.
319
320
  Adding a check constraint blocks reads and writes in Postgres and blocks writes in MySQL and MariaDB while every row is checked.
320
321
 
321
322
  ```ruby
322
- class AddCheckConstraint < ActiveRecord::Migration[6.1]
323
+ class AddCheckConstraint < ActiveRecord::Migration[7.0]
323
324
  def change
324
325
  add_check_constraint :users, "price > 0", name: "price_check"
325
326
  end
@@ -331,7 +332,7 @@ end
331
332
  Add the check constraint without validating existing rows:
332
333
 
333
334
  ```ruby
334
- class AddCheckConstraint < ActiveRecord::Migration[6.1]
335
+ class AddCheckConstraint < ActiveRecord::Migration[7.0]
335
336
  def change
336
337
  add_check_constraint :users, "price > 0", name: "price_check", validate: false
337
338
  end
@@ -341,7 +342,7 @@ end
341
342
  Then validate them in a separate migration.
342
343
 
343
344
  ```ruby
344
- class ValidateCheckConstraint < ActiveRecord::Migration[6.1]
345
+ class ValidateCheckConstraint < ActiveRecord::Migration[7.0]
345
346
  def change
346
347
  validate_check_constraint :users, name: "price_check"
347
348
  end
@@ -361,7 +362,7 @@ end
361
362
  Setting `NOT NULL` on an existing column blocks reads and writes while every row is checked.
362
363
 
363
364
  ```ruby
364
- class SetSomeColumnNotNull < ActiveRecord::Migration[6.1]
365
+ class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
365
366
  def change
366
367
  change_column_null :users, :some_column, false
367
368
  end
@@ -375,7 +376,7 @@ Instead, add a check constraint.
375
376
  For Rails 6.1, use:
376
377
 
377
378
  ```ruby
378
- class SetSomeColumnNotNull < ActiveRecord::Migration[6.1]
379
+ class SetSomeColumnNotNull < ActiveRecord::Migration[7.0]
379
380
  def change
380
381
  add_check_constraint :users, "some_column IS NOT NULL", name: "users_some_column_null", validate: false
381
382
  end
@@ -399,7 +400,7 @@ Then validate it in a separate migration. A `NOT NULL` check constraint is [func
399
400
  For Rails 6.1, use:
400
401
 
401
402
  ```ruby
402
- class ValidateSomeColumnNotNull < ActiveRecord::Migration[6.1]
403
+ class ValidateSomeColumnNotNull < ActiveRecord::Migration[7.0]
403
404
  def change
404
405
  validate_check_constraint :users, name: "users_some_column_null"
405
406
 
@@ -437,7 +438,7 @@ end
437
438
  Strong Migrations can’t ensure safety for raw SQL statements. Make really sure that what you’re doing is safe, then use:
438
439
 
439
440
  ```ruby
440
- class ExecuteSQL < ActiveRecord::Migration[6.1]
441
+ class ExecuteSQL < ActiveRecord::Migration[7.0]
441
442
  def change
442
443
  safety_assured { execute "..." }
443
444
  end
@@ -453,7 +454,7 @@ end
453
454
  In Postgres, adding an index non-concurrently blocks writes.
454
455
 
455
456
  ```ruby
456
- class AddSomeIndexToUsers < ActiveRecord::Migration[6.1]
457
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
457
458
  def change
458
459
  add_index :users, :some_column
459
460
  end
@@ -465,7 +466,7 @@ end
465
466
  Add indexes concurrently.
466
467
 
467
468
  ```ruby
468
- class AddSomeIndexToUsers < ActiveRecord::Migration[6.1]
469
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
469
470
  disable_ddl_transaction!
470
471
 
471
472
  def change
@@ -491,7 +492,7 @@ rails g index table column
491
492
  Rails adds an index non-concurrently to references by default, which blocks writes in Postgres.
492
493
 
493
494
  ```ruby
494
- class AddReferenceToUsers < ActiveRecord::Migration[6.1]
495
+ class AddReferenceToUsers < ActiveRecord::Migration[7.0]
495
496
  def change
496
497
  add_reference :users, :city
497
498
  end
@@ -503,7 +504,7 @@ end
503
504
  Make sure the index is added concurrently.
504
505
 
505
506
  ```ruby
506
- class AddReferenceToUsers < ActiveRecord::Migration[6.1]
507
+ class AddReferenceToUsers < ActiveRecord::Migration[7.0]
507
508
  disable_ddl_transaction!
508
509
 
509
510
  def change
@@ -521,7 +522,7 @@ end
521
522
  In Postgres, adding a foreign key blocks writes on both tables.
522
523
 
523
524
  ```ruby
524
- class AddForeignKeyOnUsers < ActiveRecord::Migration[6.1]
525
+ class AddForeignKeyOnUsers < ActiveRecord::Migration[7.0]
525
526
  def change
526
527
  add_foreign_key :users, :orders
527
528
  end
@@ -531,7 +532,7 @@ end
531
532
  or
532
533
 
533
534
  ```ruby
534
- class AddReferenceToUsers < ActiveRecord::Migration[6.1]
535
+ class AddReferenceToUsers < ActiveRecord::Migration[7.0]
535
536
  def change
536
537
  add_reference :users, :order, foreign_key: true
537
538
  end
@@ -540,52 +541,26 @@ end
540
541
 
541
542
  #### Good
542
543
 
543
- Add the foreign key without validating existing rows, then validate them in a separate migration.
544
-
545
- For Rails 5.2+, use:
544
+ Add the foreign key without validating existing rows:
546
545
 
547
546
  ```ruby
548
- class AddForeignKeyOnUsers < ActiveRecord::Migration[6.1]
547
+ class AddForeignKeyOnUsers < ActiveRecord::Migration[7.0]
549
548
  def change
550
549
  add_foreign_key :users, :orders, validate: false
551
550
  end
552
551
  end
553
552
  ```
554
553
 
555
- Then:
554
+ Then validate them in a separate migration.
556
555
 
557
556
  ```ruby
558
- class ValidateForeignKeyOnUsers < ActiveRecord::Migration[6.1]
557
+ class ValidateForeignKeyOnUsers < ActiveRecord::Migration[7.0]
559
558
  def change
560
559
  validate_foreign_key :users, :orders
561
560
  end
562
561
  end
563
562
  ```
564
563
 
565
- For Rails < 5.2, use:
566
-
567
- ```ruby
568
- class AddForeignKeyOnUsers < ActiveRecord::Migration[5.1]
569
- def change
570
- safety_assured do
571
- execute 'ALTER TABLE "users" ADD CONSTRAINT "fk_rails_c1e9b98e31" FOREIGN KEY ("order_id") REFERENCES "orders" ("id") NOT VALID'
572
- end
573
- end
574
- end
575
- ```
576
-
577
- Then:
578
-
579
- ```ruby
580
- class ValidateForeignKeyOnUsers < ActiveRecord::Migration[5.1]
581
- def change
582
- safety_assured do
583
- execute 'ALTER TABLE "users" VALIDATE CONSTRAINT "fk_rails_c1e9b98e31"'
584
- end
585
- end
586
- end
587
- ```
588
-
589
564
  ### Adding a json column
590
565
 
591
566
  #### Bad
@@ -593,7 +568,7 @@ end
593
568
  In Postgres, there’s no equality operator for the `json` column type, which can cause errors for existing `SELECT DISTINCT` queries in your application.
594
569
 
595
570
  ```ruby
596
- class AddPropertiesToUsers < ActiveRecord::Migration[6.1]
571
+ class AddPropertiesToUsers < ActiveRecord::Migration[7.0]
597
572
  def change
598
573
  add_column :users, :properties, :json
599
574
  end
@@ -605,7 +580,7 @@ end
605
580
  Use `jsonb` instead.
606
581
 
607
582
  ```ruby
608
- class AddPropertiesToUsers < ActiveRecord::Migration[6.1]
583
+ class AddPropertiesToUsers < ActiveRecord::Migration[7.0]
609
584
  def change
610
585
  add_column :users, :properties, :jsonb
611
586
  end
@@ -619,7 +594,7 @@ end
619
594
  Adding a non-unique index with more than three columns rarely improves performance.
620
595
 
621
596
  ```ruby
622
- class AddSomeIndexToUsers < ActiveRecord::Migration[6.1]
597
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
623
598
  def change
624
599
  add_index :users, [:a, :b, :c, :d]
625
600
  end
@@ -631,7 +606,7 @@ end
631
606
  Instead, start an index with columns that narrow down the results the most.
632
607
 
633
608
  ```ruby
634
- class AddSomeIndexToUsers < ActiveRecord::Migration[6.1]
609
+ class AddSomeIndexToUsers < ActiveRecord::Migration[7.0]
635
610
  def change
636
611
  add_index :users, [:b, :d]
637
612
  end
@@ -645,7 +620,7 @@ For Postgres, be sure to add them concurrently.
645
620
  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.
646
621
 
647
622
  ```ruby
648
- class MySafeMigration < ActiveRecord::Migration[6.1]
623
+ class MySafeMigration < ActiveRecord::Migration[7.0]
649
624
  def change
650
625
  safety_assured { remove_column :users, :some_column }
651
626
  end
@@ -818,11 +793,15 @@ StrongMigrations.auto_analyze = true
818
793
 
819
794
  ## Faster Migrations
820
795
 
821
- Only dump the schema when adding a new migration. If you use Git, create an initializer with:
796
+ Only dump the schema when adding a new migration. If you use Git, add to the end of your `Rakefile`:
822
797
 
823
- ```ruby
824
- ActiveRecord::Base.dump_schema_after_migration = Rails.env.development? &&
825
- `git status db/migrate/ --porcelain`.present?
798
+ ```rb
799
+ task :faster_migrations do
800
+ ActiveRecord::Base.dump_schema_after_migration = Rails.env.development? &&
801
+ `git status db/migrate/ --porcelain`.present?
802
+ end
803
+
804
+ task "db:migrate": "faster_migrations"
826
805
  ```
827
806
 
828
807
  ## Schema Sanity
@@ -86,8 +86,7 @@ module StrongMigrations
86
86
  options ||= {}
87
87
  default = options[:default]
88
88
 
89
- if !default.nil? && !((postgresql? && postgresql_version >= Gem::Version.new("11")) || (mysql? && mysql_version >= Gem::Version.new("8.0.12")) || (mariadb? && mariadb_version >= Gem::Version.new("10.3.2")))
90
-
89
+ if !default.nil? && !add_column_default_safe?
91
90
  if options[:null] == false
92
91
  options = options.except(:null)
93
92
  append = "
@@ -230,8 +229,10 @@ Then add the foreign key in separate migrations."
230
229
  validate_code = constraint_str("ALTER TABLE %s VALIDATE CONSTRAINT %s", [table, constraint_name])
231
230
  remove_code = constraint_str("ALTER TABLE %s DROP CONSTRAINT %s", [table, constraint_name])
232
231
 
232
+ constraint_methods = ar_version >= 6.1
233
+
233
234
  validate_constraint_code =
234
- if ar_version >= 6.1
235
+ if constraint_methods
235
236
  String.new(command_str(:validate_check_constraint, [table, {name: constraint_name}]))
236
237
  else
237
238
  String.new(safety_assured_str(validate_code))
@@ -242,7 +243,7 @@ Then add the foreign key in separate migrations."
242
243
 
243
244
  validate_constraint_code << "\n #{command_str(:change_column_null, change_args)}"
244
245
 
245
- if ar_version >= 6.1
246
+ if constraint_methods
246
247
  validate_constraint_code << "\n #{command_str(:remove_check_constraint, [table, {name: constraint_name}])}"
247
248
  else
248
249
  validate_constraint_code << "\n #{safety_assured_str(remove_code)}"
@@ -252,7 +253,7 @@ Then add the foreign key in separate migrations."
252
253
  return safe_change_column_null(add_code, validate_code, change_args, remove_code) if StrongMigrations.safe_by_default
253
254
 
254
255
  add_constraint_code =
255
- if ar_version >= 6.1
256
+ if constraint_methods
256
257
  # only quote when needed
257
258
  expr_column = column.to_s =~ /\A[a-z0-9_]+\z/ ? column : connection.quote_column_name(column)
258
259
  command_str(:add_check_constraint, [table, "#{expr_column} IS NOT NULL", {name: constraint_name, validate: false}])
@@ -275,32 +276,14 @@ Then add the foreign key in separate migrations."
275
276
  from_table, to_table, options = args
276
277
  options ||= {}
277
278
 
278
- # always validated before 5.2
279
- validate = options.fetch(:validate, true) || ar_version < 5.2
279
+ validate = options.fetch(:validate, true)
280
280
 
281
281
  if postgresql? && validate
282
- if ar_version < 5.2
283
- # fk name logic from rails
284
- primary_key = options[:primary_key] || "id"
285
- column = options[:column] || "#{to_table.to_s.singularize}_id"
286
- hashed_identifier = Digest::SHA256.hexdigest("#{from_table}_#{column}_fk").first(10)
287
- fk_name = options[:name] || "fk_rails_#{hashed_identifier}"
288
-
289
- add_code = constraint_str("ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s) NOT VALID", [from_table, fk_name, column, to_table, primary_key])
290
- validate_code = constraint_str("ALTER TABLE %s VALIDATE CONSTRAINT %s", [from_table, fk_name])
291
-
292
- return safe_add_foreign_key_code(from_table, to_table, add_code, validate_code) if StrongMigrations.safe_by_default
282
+ return safe_add_foreign_key(from_table, to_table, options) if StrongMigrations.safe_by_default
293
283
 
294
- raise_error :add_foreign_key,
295
- add_foreign_key_code: safety_assured_str(add_code),
296
- validate_foreign_key_code: safety_assured_str(validate_code)
297
- else
298
- return safe_add_foreign_key(from_table, to_table, options) if StrongMigrations.safe_by_default
299
-
300
- raise_error :add_foreign_key,
301
- add_foreign_key_code: command_str("add_foreign_key", [from_table, to_table, options.merge(validate: false)]),
302
- validate_foreign_key_code: command_str("validate_foreign_key", [from_table, to_table])
303
- end
284
+ raise_error :add_foreign_key,
285
+ add_foreign_key_code: command_str("add_foreign_key", [from_table, to_table, options.merge(validate: false)]),
286
+ validate_foreign_key_code: command_str("validate_foreign_key", [from_table, to_table])
304
287
  end
305
288
  when :validate_foreign_key
306
289
  if postgresql? && writes_blocked?
@@ -340,11 +323,7 @@ Then add the foreign key in separate migrations."
340
323
 
341
324
  # outdated statistics + a new index can hurt performance of existing queries
342
325
  if StrongMigrations.auto_analyze && direction == :up && method == :add_index
343
- if postgresql?
344
- connection.execute "ANALYZE #{connection.quote_table_name(args[0].to_s)}"
345
- elsif mariadb? || mysql?
346
- connection.execute "ANALYZE TABLE #{connection.quote_table_name(args[0].to_s)}"
347
- end
326
+ analyze_table(args[0])
348
327
  end
349
328
 
350
329
  result
@@ -396,8 +375,7 @@ Then add the foreign key in separate migrations."
396
375
  end
397
376
 
398
377
  def safe?
399
- @safe || ENV["SAFETY_ASSURED"] || @migration.is_a?(ActiveRecord::Schema) ||
400
- (direction == :down && !StrongMigrations.check_down) || version_safe?
378
+ @safe || ENV["SAFETY_ASSURED"] || (direction == :down && !StrongMigrations.check_down) || version_safe?
401
379
  end
402
380
 
403
381
  def version_safe?
@@ -508,6 +486,14 @@ Then add the foreign key in separate migrations."
508
486
  end
509
487
  end
510
488
 
489
+ def analyze_table(table)
490
+ if postgresql?
491
+ connection.execute "ANALYZE #{connection.quote_table_name(table.to_s)}"
492
+ elsif mariadb? || mysql?
493
+ connection.execute "ANALYZE TABLE #{connection.quote_table_name(table.to_s)}"
494
+ end
495
+ end
496
+
511
497
  def constraints(table_name)
512
498
  query = <<~SQL
513
499
  SELECT
@@ -595,5 +581,17 @@ Then add the foreign key in separate migrations."
595
581
  def new_table?(table)
596
582
  @new_tables.include?(table.to_s)
597
583
  end
584
+
585
+ def add_column_default_safe?
586
+ if postgresql?
587
+ postgresql_version >= Gem::Version.new("11")
588
+ elsif mysql?
589
+ mysql_version >= Gem::Version.new("8.0.12")
590
+ elsif mariadb?
591
+ mariadb_version >= Gem::Version.new("10.3.2")
592
+ else
593
+ false
594
+ end
595
+ end
598
596
  end
599
597
  end
@@ -1,6 +1,7 @@
1
1
  module StrongMigrations
2
2
  module DatabaseTasks
3
- def migrate
3
+ # Active Record 7 adds version argument
4
+ def migrate(*args)
4
5
  super
5
6
  rescue => e
6
7
  if e.cause.is_a?(StrongMigrations::Error)
@@ -7,6 +7,11 @@ module StrongMigrations
7
7
  end
8
8
 
9
9
  def method_missing(method, *args)
10
+ return super if is_a?(ActiveRecord::Schema)
11
+
12
+ # Active Record 7.0.2+ versioned schema
13
+ return super if defined?(ActiveRecord::Schema::Definition) && is_a?(ActiveRecord::Schema::Definition)
14
+
10
15
  strong_migrations_checker.perform(method, *args) do
11
16
  super
12
17
  end
@@ -30,7 +30,11 @@ module StrongMigrations
30
30
  (ActiveRecord::Base.pluralize_table_names ? reference.to_s.pluralize : reference).to_sym
31
31
  end
32
32
 
33
- @migration.add_foreign_key(table, name)
33
+ if reference
34
+ @migration.add_foreign_key(table, name, column: "#{reference}_id")
35
+ else
36
+ @migration.add_foreign_key(table, name)
37
+ end
34
38
  end
35
39
  end
36
40
  dir.down do
@@ -52,21 +56,6 @@ module StrongMigrations
52
56
  end
53
57
  end
54
58
 
55
- def safe_add_foreign_key_code(from_table, to_table, add_code, validate_code)
56
- @migration.reversible do |dir|
57
- dir.up do
58
- @migration.safety_assured do
59
- @migration.execute(add_code)
60
- disable_transaction
61
- @migration.execute(validate_code)
62
- end
63
- end
64
- dir.down do
65
- @migration.remove_foreign_key(from_table, to_table)
66
- end
67
- end
68
- end
69
-
70
59
  def safe_add_check_constraint(table, expression, add_options, validate_options)
71
60
  @migration.reversible do |dir|
72
61
  dir.up do
@@ -1,3 +1,3 @@
1
1
  module StrongMigrations
2
- VERSION = "0.7.6"
2
+ VERSION = "0.8.0"
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: 0.7.6
4
+ version: 0.8.0
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: 2021-01-17 00:00:00.000000000 Z
13
+ date: 2022-02-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -18,87 +18,17 @@ dependencies:
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '5'
21
+ version: '5.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: '5'
29
- - !ruby/object:Gem::Dependency
30
- name: bundler
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: '0'
36
- type: :development
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: '0'
43
- - !ruby/object:Gem::Dependency
44
- name: rake
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: '0'
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: '0'
57
- - !ruby/object:Gem::Dependency
58
- name: minitest
59
- requirement: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- version: '0'
64
- type: :development
65
- prerelease: false
66
- version_requirements: !ruby/object:Gem::Requirement
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- version: '0'
71
- - !ruby/object:Gem::Dependency
72
- name: pg
73
- requirement: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - ">="
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
- type: :development
79
- prerelease: false
80
- version_requirements: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: '0'
85
- - !ruby/object:Gem::Dependency
86
- name: mysql2
87
- requirement: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- type: :development
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: '0'
28
+ version: '5.2'
99
29
  description:
100
30
  email:
101
- - andrew@chartkick.com
31
+ - andrew@ankane.org
102
32
  - bob.remeika@gmail.com
103
33
  executables: []
104
34
  extensions: []
@@ -131,14 +61,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
131
61
  requirements:
132
62
  - - ">="
133
63
  - !ruby/object:Gem::Version
134
- version: '2.4'
64
+ version: '2.6'
135
65
  required_rubygems_version: !ruby/object:Gem::Requirement
136
66
  requirements:
137
67
  - - ">="
138
68
  - !ruby/object:Gem::Version
139
69
  version: '0'
140
70
  requirements: []
141
- rubygems_version: 3.2.3
71
+ rubygems_version: 3.3.3
142
72
  signing_key:
143
73
  specification_version: 4
144
74
  summary: Catch unsafe migrations in development