strong_migrations 1.5.0 → 1.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +35 -1
- data/lib/strong_migrations/checker.rb +18 -10
- data/lib/strong_migrations/checks.rb +19 -0
- data/lib/strong_migrations/error_messages.rb +7 -0
- data/lib/strong_migrations/migration.rb +1 -1
- data/lib/strong_migrations/safe_methods.rb +3 -2
- data/lib/strong_migrations/version.rb +1 -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: bd18b6da9358b37dfe07adbda611a65905173b4c4bd1aae1920588002d89afe6
|
4
|
+
data.tar.gz: 87f5393be68a9c685adbb38a29ac1980615f933f28b1b03634c2618af3db3963
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bde3a8af5e9bae18dcf270155afeefb82b726d93c9b49ac7eeee72706af2c85a31401b8eb415b89f2df3c3234ec74b1c5b5fd48404da0b0cdb65d1c5d205099
|
7
|
+
data.tar.gz: 352f30e395b489175ef038d6bb418266a2ecdb7fb3f7b0df4dd1d5290994efae1962b87b8dc0e4a5a494718a781e7552ef9f530001880f493f497ac374beb6c9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
## 1.6.3 (2023-09-20)
|
2
|
+
|
3
|
+
- Added support for Trilogy
|
4
|
+
|
5
|
+
## 1.6.2 (2023-09-13)
|
6
|
+
|
7
|
+
- Fixed foreign key options with `add_reference` and `safe_by_default`
|
8
|
+
- Fixed `safety_assured` with `revert`
|
9
|
+
|
10
|
+
## 1.6.1 (2023-08-09)
|
11
|
+
|
12
|
+
- Fixed `safety_assured` for custom checks with `safe_by_default`
|
13
|
+
|
14
|
+
## 1.6.0 (2023-07-22)
|
15
|
+
|
16
|
+
- Added check for `change_column_default`
|
17
|
+
|
1
18
|
## 1.5.0 (2023-07-02)
|
2
19
|
|
3
20
|
- Added check for `add_column` with stored generated columns
|
data/README.md
CHANGED
@@ -62,7 +62,7 @@ Potentially dangerous operations:
|
|
62
62
|
- [removing a column](#removing-a-column)
|
63
63
|
- [adding a column with a default value](#adding-a-column-with-a-default-value)
|
64
64
|
- [backfilling data](#backfilling-data)
|
65
|
-
- [adding a stored generated column](#adding-a-stored-generated-column)
|
65
|
+
- [adding a stored generated column](#adding-a-stored-generated-column)
|
66
66
|
- [changing the type of a column](#changing-the-type-of-a-column)
|
67
67
|
- [renaming a column](#renaming-a-column)
|
68
68
|
- [renaming a table](#renaming-a-table)
|
@@ -79,6 +79,10 @@ Postgres-specific checks:
|
|
79
79
|
- [adding a json column](#adding-a-json-column)
|
80
80
|
- [setting NOT NULL on an existing column](#setting-not-null-on-an-existing-column)
|
81
81
|
|
82
|
+
Config-specific checks:
|
83
|
+
|
84
|
+
- [changing the default value of a column](#changing-the-default-value-of-a-column)
|
85
|
+
|
82
86
|
Best practices:
|
83
87
|
|
84
88
|
- [keeping non-unique indexes to three columns or less](#keeping-non-unique-indexes-to-three-columns-or-less)
|
@@ -628,6 +632,36 @@ class ValidateSomeColumnNotNull < ActiveRecord::Migration[6.0]
|
|
628
632
|
end
|
629
633
|
```
|
630
634
|
|
635
|
+
### Changing the default value of a column
|
636
|
+
|
637
|
+
#### Bad
|
638
|
+
|
639
|
+
Rails < 7 enables partial writes by default, which can cause incorrect values to be inserted when changing the default value of a column.
|
640
|
+
|
641
|
+
```ruby
|
642
|
+
class ChangeSomeColumnDefault < ActiveRecord::Migration[6.1]
|
643
|
+
def change
|
644
|
+
change_column_default :users, :some_column, from: "old", to: "new"
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
User.create!(some_column: "old") # can insert "new"
|
649
|
+
```
|
650
|
+
|
651
|
+
#### Good
|
652
|
+
|
653
|
+
Disable partial writes in `config/application.rb`. For Rails < 7, use:
|
654
|
+
|
655
|
+
```ruby
|
656
|
+
config.active_record.partial_writes = false
|
657
|
+
```
|
658
|
+
|
659
|
+
For Rails 7, use:
|
660
|
+
|
661
|
+
```ruby
|
662
|
+
config.active_record.partial_inserts = false
|
663
|
+
```
|
664
|
+
|
631
665
|
### Keeping non-unique indexes to three columns or less
|
632
666
|
|
633
667
|
#### Bad
|
@@ -5,21 +5,25 @@ module StrongMigrations
|
|
5
5
|
|
6
6
|
attr_accessor :direction, :transaction_disabled, :timeouts_set
|
7
7
|
|
8
|
+
class << self
|
9
|
+
attr_accessor :safe
|
10
|
+
end
|
11
|
+
|
8
12
|
def initialize(migration)
|
9
13
|
@migration = migration
|
10
14
|
@new_tables = []
|
11
|
-
@
|
15
|
+
@new_columns = []
|
12
16
|
@timeouts_set = false
|
13
17
|
@committed = false
|
14
18
|
end
|
15
19
|
|
16
|
-
def safety_assured
|
17
|
-
previous_value =
|
20
|
+
def self.safety_assured
|
21
|
+
previous_value = safe
|
18
22
|
begin
|
19
|
-
|
23
|
+
self.safe = true
|
20
24
|
yield
|
21
25
|
ensure
|
22
|
-
|
26
|
+
self.safe = previous_value
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
@@ -46,6 +50,8 @@ module StrongMigrations
|
|
46
50
|
check_add_reference(method, *args)
|
47
51
|
when :change_column
|
48
52
|
check_change_column(*args)
|
53
|
+
when :change_column_default
|
54
|
+
check_change_column_default(*args)
|
49
55
|
when :change_column_null
|
50
56
|
check_change_column_null(*args)
|
51
57
|
when :change_table
|
@@ -75,9 +81,11 @@ module StrongMigrations
|
|
75
81
|
@committed = true
|
76
82
|
end
|
77
83
|
|
78
|
-
|
79
|
-
|
80
|
-
|
84
|
+
if !safe?
|
85
|
+
# custom checks
|
86
|
+
StrongMigrations.checks.each do |check|
|
87
|
+
@migration.instance_exec(method, args, &check)
|
88
|
+
end
|
81
89
|
end
|
82
90
|
end
|
83
91
|
|
@@ -155,7 +163,7 @@ module StrongMigrations
|
|
155
163
|
end
|
156
164
|
|
157
165
|
def safe?
|
158
|
-
|
166
|
+
self.class.safe || ENV["SAFETY_ASSURED"] || (direction == :down && !StrongMigrations.check_down) || version_safe?
|
159
167
|
end
|
160
168
|
|
161
169
|
def version_safe?
|
@@ -172,7 +180,7 @@ module StrongMigrations
|
|
172
180
|
case connection.adapter_name
|
173
181
|
when /postg/i # PostgreSQL, PostGIS
|
174
182
|
Adapters::PostgreSQLAdapter
|
175
|
-
when /mysql/i
|
183
|
+
when /mysql|trilogy/i
|
176
184
|
if connection.try(:mariadb?)
|
177
185
|
Adapters::MariaDBAdapter
|
178
186
|
else
|
@@ -32,6 +32,9 @@ module StrongMigrations
|
|
32
32
|
table, column, type = args
|
33
33
|
default = options[:default]
|
34
34
|
|
35
|
+
# keep track of new columns of change_column_default check
|
36
|
+
@new_columns << [table.to_s, column.to_s]
|
37
|
+
|
35
38
|
# Check key since DEFAULT NULL behaves differently from no default
|
36
39
|
#
|
37
40
|
# Also, Active Record has special case for uuid columns that allows function default values
|
@@ -198,6 +201,18 @@ Then add the foreign key in separate migrations."
|
|
198
201
|
raise_error :change_column, rewrite_blocks: adapter.rewrite_blocks unless safe
|
199
202
|
end
|
200
203
|
|
204
|
+
def check_change_column_default(*args)
|
205
|
+
table, column, _default_or_changes = args
|
206
|
+
|
207
|
+
# just check ActiveRecord::Base, even though can override on model
|
208
|
+
partial_inserts = ar_version >= 7 ? ActiveRecord::Base.partial_inserts : ActiveRecord::Base.partial_writes
|
209
|
+
|
210
|
+
if partial_inserts && !new_column?(table, column)
|
211
|
+
raise_error :change_column_default,
|
212
|
+
config: ar_version >= 7 ? "partial_inserts" : "partial_writes"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
201
216
|
def check_change_column_null(*args)
|
202
217
|
table, column, null, default = args
|
203
218
|
if !null
|
@@ -460,5 +475,9 @@ Then add the foreign key in separate migrations."
|
|
460
475
|
def new_table?(table)
|
461
476
|
@new_tables.include?(table.to_s)
|
462
477
|
end
|
478
|
+
|
479
|
+
def new_column?(table, column)
|
480
|
+
new_table?(table) || @new_columns.include?([table.to_s, column.to_s])
|
481
|
+
end
|
463
482
|
end
|
464
483
|
end
|
@@ -161,6 +161,13 @@ Otherwise, remove the force option.",
|
|
161
161
|
execute call, so cannot help you here. Please make really sure that what
|
162
162
|
you're doing is safe before proceeding, then wrap it in a safety_assured { ... } block.",
|
163
163
|
|
164
|
+
change_column_default:
|
165
|
+
"Partial writes are enabled, which can cause incorrect values
|
166
|
+
to be inserted when changing the default value of a column.
|
167
|
+
Disable partial writes in config/application.rb:
|
168
|
+
|
169
|
+
config.active_record.%{config} = false",
|
170
|
+
|
164
171
|
change_column_null:
|
165
172
|
"Passing a default value to change_column_null runs a single UPDATE query,
|
166
173
|
which can cause downtime. Instead, backfill the existing rows in the
|
@@ -30,10 +30,11 @@ module StrongMigrations
|
|
30
30
|
(ActiveRecord::Base.pluralize_table_names ? reference.to_s.pluralize : reference).to_sym
|
31
31
|
end
|
32
32
|
|
33
|
+
foreign_key_opts = foreign_key.is_a?(Hash) ? foreign_key.except(:to_table) : {}
|
33
34
|
if reference
|
34
|
-
@migration.add_foreign_key(table, name, column: "#{reference}_id")
|
35
|
+
@migration.add_foreign_key(table, name, column: "#{reference}_id", **foreign_key_opts)
|
35
36
|
else
|
36
|
-
@migration.add_foreign_key(table, name)
|
37
|
+
@migration.add_foreign_key(table, name, **foreign_key_opts)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
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: 1.
|
4
|
+
version: 1.6.3
|
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: 2023-
|
13
|
+
date: 2023-09-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|