strong_migrations 0.6.7 → 0.6.8

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: 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