strong_migrations 1.3.2 → 1.4.1
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 +27 -2
- data/lib/strong_migrations/adapters/abstract_adapter.rb +17 -1
- 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 +10 -1
- data/lib/strong_migrations/error_messages.rb +4 -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 +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a296161cd1d5cdd070c94c34bd250feb2d62cb7b5274205007bab92e50dc7d0a
|
4
|
+
data.tar.gz: e95730e625ed31bb3745c0c55fddf4aa2cd6d7d99607add097d23ae1181a8b50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '03479a3996622262cad8eab0843f6fdd266e041d854ab49ced8dd334e6c9709556f6887f7708d1eeab87f98524bb558e813457f5f0cbb4c16323557353438680'
|
7
|
+
data.tar.gz: 263a6238d3cc34d1211f7f6c6410248f8ee104e475f04f5e3687efb8602389ab26b12ec9155a6e782fc828e733af85b9315e9a282b5589d39f5891b46a5a83e6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 1.4.1 (2023-01-05)
|
2
|
+
|
3
|
+
- Added support for multiple databases to `target_version`
|
4
|
+
|
5
|
+
## 1.4.0 (2022-10-31)
|
6
|
+
|
7
|
+
- Added check for `add_exclusion_constraint`
|
8
|
+
- Added support for `RACK_ENV`
|
9
|
+
- Fixed error when `Rails` defined without `Rails.env`
|
10
|
+
- Fixed error with `change_column_null` when table does not exist
|
11
|
+
|
1
12
|
## 1.3.2 (2022-10-09)
|
2
13
|
|
3
14
|
- Improved error message 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
|
@@ -805,6 +824,12 @@ The major version works well for Postgres, while the full version is recommended
|
|
805
824
|
|
806
825
|
For safety, this option only affects development and test environments. In other environments, the actual server version is always used.
|
807
826
|
|
827
|
+
If your app has multiple databases with different versions, with Rails 6.1+, you can use:
|
828
|
+
|
829
|
+
```ruby
|
830
|
+
StrongMigrations.target_version = {primary: 13, catalog: 15}
|
831
|
+
```
|
832
|
+
|
808
833
|
## Analyze Tables
|
809
834
|
|
810
835
|
Analyze tables automatically (to update planner statistics) after an index is added. Create an initializer with:
|
@@ -50,7 +50,23 @@ module StrongMigrations
|
|
50
50
|
target_version ||= StrongMigrations.target_version
|
51
51
|
version =
|
52
52
|
if target_version && StrongMigrations.developer_env?
|
53
|
-
target_version.
|
53
|
+
if target_version.is_a?(Hash)
|
54
|
+
# Active Record 6.0 supports multiple databases
|
55
|
+
# but connection.pool.spec.name always returns "primary"
|
56
|
+
# in migrations with rails db:migrate
|
57
|
+
if ActiveRecord::VERSION::STRING.to_f < 6.1
|
58
|
+
# error class is not shown in db:migrate output so ensure message is descriptive
|
59
|
+
raise StrongMigrations::Error, "StrongMigrations.target_version does not support multiple databases for Active Record < 6.1"
|
60
|
+
end
|
61
|
+
|
62
|
+
db_config_name = connection.pool.db_config.name
|
63
|
+
target_version.stringify_keys.fetch(db_config_name) do
|
64
|
+
# error class is not shown in db:migrate output so ensure message is descriptive
|
65
|
+
raise StrongMigrations::Error, "StrongMigrations.target_version is not configured for :#{db_config_name} database"
|
66
|
+
end.to_s
|
67
|
+
else
|
68
|
+
target_version.to_s
|
69
|
+
end
|
54
70
|
else
|
55
71
|
yield
|
56
72
|
end
|
@@ -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
|
|
@@ -73,6 +73,14 @@ Then add the NOT NULL constraint in separate migrations."
|
|
73
73
|
end
|
74
74
|
end
|
75
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
|
+
|
76
84
|
# unlike add_index, we don't make an exception here for new tables
|
77
85
|
#
|
78
86
|
# with add_index, it's fine to lock a new table even after inserting data
|
@@ -170,7 +178,8 @@ Then add the foreign key in separate migrations."
|
|
170
178
|
table, column, type = args
|
171
179
|
|
172
180
|
safe = false
|
173
|
-
|
181
|
+
table_columns = connection.columns(table) rescue []
|
182
|
+
existing_column = table_columns.find { |c| c.name.to_s == column.to_s }
|
174
183
|
if existing_column
|
175
184
|
existing_type = existing_column.sql_type.sub(/\(\d+(,\d+)?\)/, "")
|
176
185
|
safe = adapter.change_type_safe?(table, column, type, options, existing_column, existing_type)
|
@@ -231,7 +231,10 @@ end",
|
|
231
231
|
|
232
232
|
validate_check_constraint:
|
233
233
|
"Validating a check constraint while writes are blocked is dangerous.
|
234
|
-
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."
|
235
238
|
}
|
236
239
|
self.enabled_checks = (error_messages.keys - [:remove_index]).map { |k| [k, {}] }.to_h
|
237
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.1
|
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:
|
13
|
+
date: 2023-01-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
78
|
+
rubygems_version: 3.4.1
|
79
79
|
signing_key:
|
80
80
|
specification_version: 4
|
81
81
|
summary: Catch unsafe migrations in development
|