strong_migrations 0.6.7 → 0.6.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c2afb67b7b25f7608d3d77d266703a23b5585fcfe006d8442a3da42547979f8d
4
- data.tar.gz: 502347f1d82a120f93694bdffb3cc9d434573bb2e6c14f75f61c5dc1b43c723d
3
+ metadata.gz: f64d60856479de1a9071b64be2186256e619c30a6caea46d2f8094fb1d3ded4b
4
+ data.tar.gz: 586c15c10b53ba6273685d3d4bbeaa84f0c23fc973643abac1a2687d3ad2e986
5
5
  SHA512:
6
- metadata.gz: bb821b724c1d55150415e117c1509f407edadcb209312ee869b230563b59e55e64072371631b9a75f59e84bbc7af0bdde05e5e5e872ad0dc738917d28ea5c49f
7
- data.tar.gz: eb503dd38ecc6ad8877e4a2c506b6503f5a00ac661f8adbc4962d6802009c278091d4a7236dff4c83d64885405d468a9275fd4601e869d3dffac709c3c39cc13
6
+ metadata.gz: d5aac390d0d1f965819311ec4ad0cc18b66eb310768f5ed95635670ca646f8804cf0fb672c94f4f1b59f6d812b027cc2d666607bf9b55d5a5f58f37726056d8c
7
+ data.tar.gz: f0ec6e96d589aa99df461bbcc29201142a25a74a951edbbdf72c49e8a1d81a58623ccb6f049d2630a5cbd517f9edf9119511087d51da90f95c9794a13f5c1fb1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.6.8 (2020-05-13)
2
+
3
+ - `change_column_null` on a column with a `NOT NULL` constraint is safe in Postgres 12+
4
+
1
5
  ## 0.6.7 (2020-05-13)
2
6
 
3
7
  - Improved comments in initializer
data/README.md CHANGED
@@ -497,11 +497,17 @@ class ValidateSomeColumnNotNull < ActiveRecord::Migration[6.0]
497
497
  safety_assured do
498
498
  execute 'ALTER TABLE "users" VALIDATE CONSTRAINT "users_some_column_null"'
499
499
  end
500
+
501
+ # in Postgres 12+, you can safely turn this into a traditional column constraint
502
+ change_column_null :users, :some_column, false
503
+ safety_assured do
504
+ execute 'ALTER TABLE "users" DROP CONSTRAINT "users_some_column_null"'
505
+ end
500
506
  end
501
507
  end
502
508
  ```
503
509
 
504
- Note: This is not 100% the same as `NOT NULL` column constraint. Here’s a [good explanation](https://medium.com/doctolib/adding-a-not-null-constraint-on-pg-faster-with-minimal-locking-38b2c00c4d1c).
510
+ Note: This is not 100% the same as `NOT NULL` column constraint before Postgres 12. Here’s a [good explanation](https://medium.com/doctolib/adding-a-not-null-constraint-on-pg-faster-with-minimal-locking-38b2c00c4d1c).
505
511
 
506
512
  ### Keeping non-unique indexes to three columns or less
507
513
 
@@ -196,12 +196,26 @@ Then add the foreign key in separate migrations."
196
196
  table, column, null, default = args
197
197
  if !null
198
198
  if postgresql?
199
- # match https://github.com/nullobject/rein
200
- constraint_name = "#{table}_#{column}_null"
199
+ safe = false
200
+ if postgresql_version >= Gem::Version.new("12")
201
+ # TODO likely need to quote the column in some situations
202
+ safe = constraints(table).any? { |c| c["def"] == "CHECK ((#{column} IS NOT NULL))" }
203
+ end
204
+
205
+ unless safe
206
+ # match https://github.com/nullobject/rein
207
+ constraint_name = "#{table}_#{column}_null"
208
+
209
+ validate_constraint_code = String.new(constraint_str("ALTER TABLE %s VALIDATE CONSTRAINT %s", [table, constraint_name]))
210
+ if postgresql_version >= Gem::Version.new("12")
211
+ validate_constraint_code << "\n #{command_str(:change_column_null, [table, column, null])}"
212
+ validate_constraint_code << "\n #{constraint_str("ALTER TABLE %s DROP CONSTRAINT %s", [table, constraint_name])}"
213
+ end
201
214
 
202
- raise_error :change_column_null_postgresql,
203
- add_constraint_code: constraint_str("ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s IS NOT NULL) NOT VALID", [table, constraint_name, column]),
204
- validate_constraint_code: constraint_str("ALTER TABLE %s VALIDATE CONSTRAINT %s", [table, constraint_name])
215
+ raise_error :change_column_null_postgresql,
216
+ add_constraint_code: constraint_str("ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s IS NOT NULL) NOT VALID", [table, constraint_name, column]),
217
+ validate_constraint_code: validate_constraint_code
218
+ end
205
219
  elsif mysql? || mariadb?
206
220
  raise_error :change_column_null_mysql
207
221
  elsif !default.nil?
@@ -255,7 +269,6 @@ Then add the foreign key in separate migrations."
255
269
  result
256
270
  end
257
271
 
258
- # TODO allow string timeouts in 0.7.0
259
272
  def set_timeouts
260
273
  if !@timeouts_set
261
274
  if StrongMigrations.statement_timeout
@@ -379,7 +392,7 @@ Then add the foreign key in separate migrations."
379
392
 
380
393
  # units: https://www.postgresql.org/docs/current/config-setting.html
381
394
  def timeout_to_sec(timeout)
382
- suffixes = {
395
+ units = {
383
396
  "us" => 0.001,
384
397
  "ms" => 1,
385
398
  "s" => 1000,
@@ -388,7 +401,7 @@ Then add the foreign key in separate migrations."
388
401
  "d" => 1000 * 60 * 60 * 24
389
402
  }
390
403
  timeout_ms = timeout.to_i
391
- suffixes.each do |k, v|
404
+ units.each do |k, v|
392
405
  if timeout.end_with?(k)
393
406
  timeout_ms *= v
394
407
  break
@@ -405,6 +418,16 @@ Then add the foreign key in separate migrations."
405
418
  end
406
419
  end
407
420
 
421
+ def constraints(table_name)
422
+ query = <<-SQL
423
+ SELECT conname AS name, pg_get_constraintdef(oid) AS def FROM pg_constraint
424
+ WHERE contype = 'c'
425
+ AND convalidated
426
+ AND conrelid = #{connection.quote(connection.quote_table_name(table_name))}::regclass
427
+ SQL
428
+ connection.select_all(query.squish).to_a
429
+ end
430
+
408
431
  def raise_error(message_key, header: nil, append: nil, **vars)
409
432
  return unless StrongMigrations.check_enabled?(message_key, version: version)
410
433
 
@@ -1,3 +1,3 @@
1
1
  module StrongMigrations
2
- VERSION = "0.6.7"
2
+ VERSION = "0.6.8"
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.6.7
4
+ version: 0.6.8
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: 2020-05-13 00:00:00.000000000 Z
13
+ date: 2020-05-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord