strong_migrations 1.3.1 → 1.4.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 +11 -0
- data/README.md +21 -2
- data/lib/strong_migrations/adapters/mariadb_adapter.rb +3 -0
- data/lib/strong_migrations/adapters/mysql_adapter.rb +3 -0
- data/lib/strong_migrations/checker.rb +2 -0
- data/lib/strong_migrations/checks.rb +25 -9
- data/lib/strong_migrations/error_messages.rb +14 -1
- data/lib/strong_migrations/safe_methods.rb +1 -1
- data/lib/strong_migrations/version.rb +1 -1
- data/lib/strong_migrations.rb +11 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cbc9cb28c4558aec3f349f8b394db58e0f1a52f5f554259c9ded55d13e70fa4
|
4
|
+
data.tar.gz: b739a47825673f01c2e7c328ff0e25dbe3e326d09d2af3ae611154861df1a645
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e86416fab6ffbbdb2838080acf49171f2327f0734d7960aa24476d91725156b94281b8c3661f7d672ea8f462542a74282231543b232155aad45c0ac11418a80
|
7
|
+
data.tar.gz: e1f11e93dd82cf002d20a9eb9568e011889c13b2c2154f9aae10996a6be17a7e4d8d4c88b85e03c07fd7d3e6feeeeccb31882418aef57c6d75401f556e2821b2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 1.4.0 (2022-10-31)
|
2
|
+
|
3
|
+
- Added check for `add_exclusion_constraint`
|
4
|
+
- Added support for `RACK_ENV`
|
5
|
+
- Fixed error when `Rails` defined without `Rails.env`
|
6
|
+
- Fixed error with `change_column_null` when table does not exist
|
7
|
+
|
8
|
+
## 1.3.2 (2022-10-09)
|
9
|
+
|
10
|
+
- Improved error message for `add_column` with `default: nil` with Postgres 10
|
11
|
+
|
1
12
|
## 1.3.1 (2022-09-21)
|
2
13
|
|
3
14
|
- Fixed check for `add_column` with `default: nil` with Postgres 10
|
data/README.md
CHANGED
@@ -74,6 +74,7 @@ Postgres-specific checks:
|
|
74
74
|
- [adding an index non-concurrently](#adding-an-index-non-concurrently)
|
75
75
|
- [adding a reference](#adding-a-reference)
|
76
76
|
- [adding a foreign key](#adding-a-foreign-key)
|
77
|
+
- [adding an exclusion constraint](#adding-an-exclusion-constraint)
|
77
78
|
- [adding a json column](#adding-a-json-column)
|
78
79
|
- [setting NOT NULL on an existing column](#setting-not-null-on-an-existing-column)
|
79
80
|
|
@@ -107,7 +108,7 @@ end
|
|
107
108
|
end
|
108
109
|
```
|
109
110
|
|
110
|
-
2. Deploy code
|
111
|
+
2. Deploy the code
|
111
112
|
3. Write a migration to remove the column (wrap in `safety_assured` block)
|
112
113
|
|
113
114
|
```ruby
|
@@ -118,7 +119,7 @@ end
|
|
118
119
|
end
|
119
120
|
```
|
120
121
|
|
121
|
-
4. Deploy and run migration
|
122
|
+
4. Deploy and run the migration
|
122
123
|
5. Remove the line added in step 1
|
123
124
|
|
124
125
|
### Adding a column with a default value
|
@@ -488,6 +489,24 @@ class ValidateForeignKeyOnUsers < ActiveRecord::Migration[7.0]
|
|
488
489
|
end
|
489
490
|
```
|
490
491
|
|
492
|
+
### Adding an exclusion constraint
|
493
|
+
|
494
|
+
#### Bad
|
495
|
+
|
496
|
+
In Postgres, adding an exclusion constraint blocks reads and writes while every row is checked.
|
497
|
+
|
498
|
+
```ruby
|
499
|
+
class AddExclusionContraint < ActiveRecord::Migration[7.1]
|
500
|
+
def change
|
501
|
+
add_exclusion_constraint :users, "number WITH =", using: :gist
|
502
|
+
end
|
503
|
+
end
|
504
|
+
```
|
505
|
+
|
506
|
+
#### Good
|
507
|
+
|
508
|
+
[Let us know](https://github.com/ankane/strong_migrations/issues/new) if you have a safe way to do this (exclusion constraints cannot be marked `NOT VALID`).
|
509
|
+
|
491
510
|
### Adding a json column
|
492
511
|
|
493
512
|
#### Bad
|
@@ -18,6 +18,9 @@ module StrongMigrations
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def set_statement_timeout(timeout)
|
21
|
+
# fix deprecation warning with Active Record 7.1
|
22
|
+
timeout = timeout.value if timeout.is_a?(ActiveSupport::Duration)
|
23
|
+
|
21
24
|
select_all("SET max_statement_time = #{connection.quote(timeout)}")
|
22
25
|
end
|
23
26
|
|
@@ -25,6 +25,9 @@ module StrongMigrations
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def set_lock_timeout(timeout)
|
28
|
+
# fix deprecation warning with Active Record 7.1
|
29
|
+
timeout = timeout.value if timeout.is_a?(ActiveSupport::Duration)
|
30
|
+
|
28
31
|
select_all("SET lock_wait_timeout = #{connection.quote(timeout)}")
|
29
32
|
end
|
30
33
|
|
@@ -44,14 +44,21 @@ module StrongMigrations
|
|
44
44
|
Then add the NOT NULL constraint in separate migrations."
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
if default.nil?
|
48
|
+
raise_error :add_column_default_null,
|
49
|
+
command: command_str("add_column", [table, column, type, options.except(:default)]),
|
50
|
+
append: append,
|
51
|
+
rewrite_blocks: adapter.rewrite_blocks
|
52
|
+
else
|
53
|
+
raise_error :add_column_default,
|
54
|
+
add_command: command_str("add_column", [table, column, type, options.except(:default)]),
|
55
|
+
change_command: command_str("change_column_default", [table, column, default]),
|
56
|
+
remove_command: command_str("remove_column", [table, column]),
|
57
|
+
code: backfill_code(table, column, default, volatile),
|
58
|
+
append: append,
|
59
|
+
rewrite_blocks: adapter.rewrite_blocks,
|
60
|
+
default_type: (volatile ? "volatile" : "non-null")
|
61
|
+
end
|
55
62
|
elsif default.is_a?(Proc) && postgresql?
|
56
63
|
# adding a column with a VOLATILE default is not safe
|
57
64
|
# https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-NOTES
|
@@ -66,6 +73,14 @@ Then add the NOT NULL constraint in separate migrations."
|
|
66
73
|
end
|
67
74
|
end
|
68
75
|
|
76
|
+
def check_add_exclusion_constraint(*args)
|
77
|
+
table = args[0]
|
78
|
+
|
79
|
+
unless new_table?(table)
|
80
|
+
raise_error :add_exclusion_constraint
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
69
84
|
# unlike add_index, we don't make an exception here for new tables
|
70
85
|
#
|
71
86
|
# with add_index, it's fine to lock a new table even after inserting data
|
@@ -163,7 +178,8 @@ Then add the foreign key in separate migrations."
|
|
163
178
|
table, column, type = args
|
164
179
|
|
165
180
|
safe = false
|
166
|
-
|
181
|
+
table_columns = connection.columns(table) rescue []
|
182
|
+
existing_column = table_columns.find { |c| c.name.to_s == column.to_s }
|
167
183
|
if existing_column
|
168
184
|
existing_type = existing_column.sql_type.sub(/\(\d+(,\d+)?\)/, "")
|
169
185
|
safe = adapter.change_type_safe?(table, column, type, options, existing_column, existing_type)
|
@@ -25,6 +25,16 @@ class Backfill%{migration_name} < ActiveRecord::Migration%{migration_suffix}
|
|
25
25
|
end
|
26
26
|
end",
|
27
27
|
|
28
|
+
add_column_default_null:
|
29
|
+
"Adding a column with a null default blocks %{rewrite_blocks} while the entire table is rewritten.
|
30
|
+
Instead, add the column without a default value.
|
31
|
+
|
32
|
+
class %{migration_name} < ActiveRecord::Migration%{migration_suffix}
|
33
|
+
def change
|
34
|
+
%{command}
|
35
|
+
end
|
36
|
+
end",
|
37
|
+
|
28
38
|
add_column_default_callable:
|
29
39
|
"Strong Migrations does not support inspecting callable default values.
|
30
40
|
Please make really sure you're not calling a VOLATILE function,
|
@@ -221,7 +231,10 @@ end",
|
|
221
231
|
|
222
232
|
validate_check_constraint:
|
223
233
|
"Validating a check constraint while writes are blocked is dangerous.
|
224
|
-
Use disable_ddl_transaction! or a separate migration."
|
234
|
+
Use disable_ddl_transaction! or a separate migration.",
|
235
|
+
|
236
|
+
add_exclusion_constraint:
|
237
|
+
"Adding an exclusion constraint blocks reads and writes while every row is checked."
|
225
238
|
}
|
226
239
|
self.enabled_checks = (error_messages.keys - [:remove_index]).map { |k| [k, {}] }.to_h
|
227
240
|
end
|
@@ -64,7 +64,7 @@ module StrongMigrations
|
|
64
64
|
@migration.validate_check_constraint(table, **validate_options)
|
65
65
|
end
|
66
66
|
dir.down do
|
67
|
-
@migration.remove_check_constraint(table, expression, **add_options)
|
67
|
+
@migration.remove_check_constraint(table, expression, **add_options.except(:validate))
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
data/lib/strong_migrations.rb
CHANGED
@@ -41,7 +41,17 @@ module StrongMigrations
|
|
41
41
|
|
42
42
|
# private
|
43
43
|
def self.developer_env?
|
44
|
-
|
44
|
+
env == "development" || env == "test"
|
45
|
+
end
|
46
|
+
|
47
|
+
# private
|
48
|
+
def self.env
|
49
|
+
if defined?(Rails.env)
|
50
|
+
Rails.env
|
51
|
+
else
|
52
|
+
# default to production for safety
|
53
|
+
ENV["RACK_ENV"] || "production"
|
54
|
+
end
|
45
55
|
end
|
46
56
|
|
47
57
|
def self.lock_timeout_limit
|
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.
|
4
|
+
version: 1.4.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: 2022-
|
13
|
+
date: 2022-10-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|