safe-pg-migrations 2.2.1 → 2.3.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/lib/safe-pg-migrations/base.rb +1 -0
- data/lib/safe-pg-migrations/helpers/statements_helper.rb +19 -0
- data/lib/safe-pg-migrations/plugins/blocking_activity_logger.rb +2 -9
- data/lib/safe-pg-migrations/plugins/idempotent_statements.rb +29 -32
- data/lib/safe-pg-migrations/plugins/statement_retrier.rb +1 -3
- data/lib/safe-pg-migrations/version.rb +1 -1
- metadata +15 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da23106f1db5b2a4f626e37170f2d26f8642f52ffda4775d972822b12156b301
|
4
|
+
data.tar.gz: 49ede8d6b233b0d0c9b26efc5d62be4be99e08111b39beec9c4904928ae31e72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79502033f2e447bea822504895d62ad31e3aa78957c164cfa63a4b857f0282f0e19e0e2a848eba25c8f02cb447fed06316c7c5a1cd2e9f5a021cb9b5a9e178f7
|
7
|
+
data.tar.gz: cd0fb8724abf3ddc17d818fc664e4445cb2b27e87b5644ccb22be5cbe106383792b23ae2ce32c4ad7a6641ad965a8412afe52758b87a9086d2f8cdd979c698cd
|
@@ -6,6 +6,7 @@ require 'safe-pg-migrations/helpers/satisfied_helper'
|
|
6
6
|
require 'safe-pg-migrations/helpers/index_helper'
|
7
7
|
require 'safe-pg-migrations/helpers/batch_over'
|
8
8
|
require 'safe-pg-migrations/helpers/session_setting_management'
|
9
|
+
require 'safe-pg-migrations/helpers/statements_helper'
|
9
10
|
require 'safe-pg-migrations/plugins/verbose_sql_logger'
|
10
11
|
require 'safe-pg-migrations/plugins/blocking_activity_logger'
|
11
12
|
require 'safe-pg-migrations/plugins/statement_insurer/add_column'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SafePgMigrations
|
4
|
+
module Helpers
|
5
|
+
module StatementsHelper
|
6
|
+
RETRIABLE_SCHEMA_STATEMENTS = %i[
|
7
|
+
add_check_constraint
|
8
|
+
add_column
|
9
|
+
add_foreign_key
|
10
|
+
change_column_default
|
11
|
+
change_column_null
|
12
|
+
create_table
|
13
|
+
remove_column
|
14
|
+
remove_foreign_key
|
15
|
+
drop_table
|
16
|
+
].freeze
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -7,16 +7,9 @@ module SafePgMigrations
|
|
7
7
|
module BlockingActivityLogger
|
8
8
|
include Helpers::BlockingActivityFormatter
|
9
9
|
include Helpers::BlockingActivitySelector
|
10
|
+
include Helpers::StatementsHelper
|
10
11
|
|
11
|
-
|
12
|
-
add_column
|
13
|
-
remove_column
|
14
|
-
add_foreign_key
|
15
|
-
remove_foreign_key
|
16
|
-
change_column_default
|
17
|
-
change_column_null
|
18
|
-
create_table
|
19
|
-
].each do |method|
|
12
|
+
RETRIABLE_SCHEMA_STATEMENTS.each do |method|
|
20
13
|
define_method method do |*args, &block|
|
21
14
|
log_context = lambda do
|
22
15
|
break unless SafePgMigrations.config.sensitive_logger
|
@@ -6,15 +6,12 @@ module SafePgMigrations
|
|
6
6
|
|
7
7
|
ruby2_keywords def add_index(table_name, column_name, *args)
|
8
8
|
options = args.last.is_a?(Hash) ? args.last : {}
|
9
|
-
|
10
9
|
index_definition = index_definition(table_name, column_name, **options)
|
11
10
|
|
12
11
|
return super unless index_name_exists?(index_definition.table, index_definition.name)
|
13
12
|
|
14
13
|
if index_valid?(index_definition.name)
|
15
|
-
|
16
|
-
/!\\ Index '#{index_definition.name}' already exists in '#{table_name}'. Skipping statement.
|
17
|
-
MESSAGE
|
14
|
+
log_message("/!\\ Index '#{index_definition.name}' already exists in '#{table_name}'. Skipping statement.")
|
18
15
|
return
|
19
16
|
end
|
20
17
|
|
@@ -23,19 +20,24 @@ module SafePgMigrations
|
|
23
20
|
end
|
24
21
|
|
25
22
|
ruby2_keywords def add_column(table_name, column_name, type, *)
|
26
|
-
|
23
|
+
if column_exists?(table_name, column_name) && !column_exists?(table_name, column_name, type)
|
24
|
+
error_message = "/!\\ Column '#{column_name}' already exists in '#{table_name}' with a different type"
|
25
|
+
raise error_message
|
26
|
+
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
return super unless column_exists?(table_name, column_name, type)
|
29
|
+
|
30
|
+
log_message(<<~MESSAGE.squish
|
31
|
+
/!\\ Column '#{column_name}' already exists in '#{table_name}' with the same type (#{type}).
|
32
|
+
Skipping statement.
|
30
33
|
MESSAGE
|
34
|
+
)
|
31
35
|
end
|
32
36
|
|
33
37
|
ruby2_keywords def remove_column(table_name, column_name, type = nil, *)
|
34
38
|
return super if column_exists?(table_name, column_name)
|
35
39
|
|
36
|
-
|
37
|
-
/!\\ Column '#{column_name}' not found on table '#{table_name}'. Skipping statement.
|
38
|
-
MESSAGE
|
40
|
+
log_message("/!\\ Column '#{column_name}' not found on table '#{table_name}'. Skipping statement.")
|
39
41
|
end
|
40
42
|
|
41
43
|
ruby2_keywords def remove_index(table_name, *args)
|
@@ -44,9 +46,7 @@ module SafePgMigrations
|
|
44
46
|
|
45
47
|
return super if index_name_exists?(table_name, index_name)
|
46
48
|
|
47
|
-
|
48
|
-
/!\\ Index '#{index_name}' not found on table '#{table_name}'. Skipping statement.
|
49
|
-
MESSAGE
|
49
|
+
log_message("/!\\ Index '#{index_name}' not found on table '#{table_name}'. Skipping statement.")
|
50
50
|
end
|
51
51
|
|
52
52
|
ruby2_keywords def add_foreign_key(from_table, to_table, *args)
|
@@ -54,18 +54,14 @@ module SafePgMigrations
|
|
54
54
|
sub_options = options.slice(:name, :column)
|
55
55
|
return super unless foreign_key_exists?(from_table, sub_options.present? ? nil : to_table, **sub_options)
|
56
56
|
|
57
|
-
|
58
|
-
/!\\ Foreign key '#{from_table}' -> '#{to_table}' already exists. Skipping statement.
|
59
|
-
MESSAGE
|
57
|
+
log_message("/!\\ Foreign key '#{from_table}' -> '#{to_table}' already exists. Skipping statement.")
|
60
58
|
end
|
61
59
|
|
62
60
|
def remove_foreign_key(from_table, to_table = nil, **options)
|
63
61
|
return super if foreign_key_exists?(from_table, to_table, **options)
|
64
62
|
|
65
63
|
reference_name = to_table || options[:to_table] || options[:column] || options[:name]
|
66
|
-
|
67
|
-
/!\\ Foreign key '#{from_table}' -> '#{reference_name}' does not exist. Skipping statement.
|
68
|
-
MESSAGE
|
64
|
+
log_message("/!\\ Foreign key '#{from_table}' -> '#{reference_name}' does not exist. Skipping statement.")
|
69
65
|
end
|
70
66
|
|
71
67
|
ruby2_keywords def create_table(table_name, *args)
|
@@ -91,9 +87,7 @@ module SafePgMigrations
|
|
91
87
|
|
92
88
|
return super if constraint_definition.nil?
|
93
89
|
|
94
|
-
|
95
|
-
/!\\ Constraint '#{constraint_definition.name}' already exists. Skipping statement.
|
96
|
-
MESSAGE
|
90
|
+
log_message("/!\\ Constraint '#{constraint_definition.name}' already exists. Skipping statement.")
|
97
91
|
end
|
98
92
|
|
99
93
|
def change_column_null(table_name, column_name, null, *)
|
@@ -101,9 +95,7 @@ module SafePgMigrations
|
|
101
95
|
|
102
96
|
return super if column.null != null
|
103
97
|
|
104
|
-
|
105
|
-
/!\\ Column '#{table_name}.#{column.name}' is already set to 'null: #{null}'. Skipping statement.
|
106
|
-
MESSAGE
|
98
|
+
log_message("/!\\ Column '#{table_name}.#{column.name}' is already set to 'null: #{null}'. Skipping statement.")
|
107
99
|
end
|
108
100
|
|
109
101
|
def validate_check_constraint(table_name, **options)
|
@@ -111,14 +103,11 @@ module SafePgMigrations
|
|
111
103
|
|
112
104
|
return super unless constraint_definition.validated?
|
113
105
|
|
114
|
-
|
115
|
-
/!\\ Constraint '#{constraint_definition.name}' already validated. Skipping statement.
|
116
|
-
MESSAGE
|
106
|
+
log_message("/!\\ Constraint '#{constraint_definition.name}' already validated. Skipping statement.")
|
117
107
|
end
|
118
108
|
|
119
109
|
def change_column_default(table_name, column_name, default_or_changes)
|
120
110
|
column = column_for(table_name, column_name)
|
121
|
-
|
122
111
|
previous_alter_statement = change_column_default_for_alter(table_name, column_name, column.default)
|
123
112
|
new_alter_statement = change_column_default_for_alter(table_name, column_name, default_or_changes)
|
124
113
|
|
@@ -127,16 +116,24 @@ module SafePgMigrations
|
|
127
116
|
|
128
117
|
return super if new_alter_statement != previous_alter_statement
|
129
118
|
|
130
|
-
|
131
|
-
/!\\ Column '#{table_name}.#{column.name}' is already set to 'default: #{column.default}'.
|
119
|
+
log_message(<<~MESSAGE.squish
|
120
|
+
/!\\ Column '#{table_name}.#{column.name}' is already set to 'default: #{column.default}'.
|
121
|
+
Skipping statement.
|
132
122
|
MESSAGE
|
123
|
+
)
|
133
124
|
end
|
134
125
|
|
135
126
|
ruby2_keywords def drop_table(table_name, *)
|
136
127
|
return super if table_exists?(table_name)
|
137
128
|
|
129
|
+
log_message("/!\\ Table '#{table_name} does not exist. Skipping statement.")
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def log_message(message)
|
138
135
|
Helpers::Logger.say <<~MESSAGE.squish, sub_item: true
|
139
|
-
|
136
|
+
#{message}
|
140
137
|
MESSAGE
|
141
138
|
end
|
142
139
|
end
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
module SafePgMigrations
|
4
4
|
module StatementRetrier
|
5
|
-
|
6
|
-
add_column add_foreign_key remove_foreign_key change_column_default change_column_null remove_column drop_table
|
7
|
-
].freeze
|
5
|
+
include Helpers::StatementsHelper
|
8
6
|
|
9
7
|
RETRIABLE_SCHEMA_STATEMENTS.each do |method|
|
10
8
|
define_method method do |*args, &block|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safe-pg-migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthieu Prat
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-10-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -19,6 +19,9 @@ dependencies:
|
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '6.0'
|
22
|
+
- - "<"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 7.1.x
|
22
25
|
type: :runtime
|
23
26
|
prerelease: false
|
24
27
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,6 +29,9 @@ dependencies:
|
|
26
29
|
- - ">="
|
27
30
|
- !ruby/object:Gem::Version
|
28
31
|
version: '6.0'
|
32
|
+
- - "<"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 7.1.x
|
29
35
|
- !ruby/object:Gem::Dependency
|
30
36
|
name: activesupport
|
31
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -33,6 +39,9 @@ dependencies:
|
|
33
39
|
- - ">="
|
34
40
|
- !ruby/object:Gem::Version
|
35
41
|
version: '6.0'
|
42
|
+
- - "<"
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 7.1.x
|
36
45
|
type: :runtime
|
37
46
|
prerelease: false
|
38
47
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -40,6 +49,9 @@ dependencies:
|
|
40
49
|
- - ">="
|
41
50
|
- !ruby/object:Gem::Version
|
42
51
|
version: '6.0'
|
52
|
+
- - "<"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 7.1.x
|
43
55
|
description: Make your PG migrations safe.
|
44
56
|
email:
|
45
57
|
executables: []
|
@@ -58,6 +70,7 @@ files:
|
|
58
70
|
- lib/safe-pg-migrations/helpers/logger.rb
|
59
71
|
- lib/safe-pg-migrations/helpers/satisfied_helper.rb
|
60
72
|
- lib/safe-pg-migrations/helpers/session_setting_management.rb
|
73
|
+
- lib/safe-pg-migrations/helpers/statements_helper.rb
|
61
74
|
- lib/safe-pg-migrations/plugins/blocking_activity_logger.rb
|
62
75
|
- lib/safe-pg-migrations/plugins/idempotent_statements.rb
|
63
76
|
- lib/safe-pg-migrations/plugins/statement_insurer.rb
|