pg_ha_migrations 1.7.0 → 2.0.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.
@@ -1,10 +1,6 @@
1
1
  module PgHaMigrations::UnsafeStatements
2
2
  def self.disable_or_delegate_default_method(method_name, error_message, allow_reentry_from_compatibility_module: false)
3
3
  define_method(method_name) do |*args, &block|
4
- if PgHaMigrations.config.check_for_dependent_objects
5
- disallow_migration_method_if_dependent_objects!(method_name, arguments: args)
6
- end
7
-
8
4
  if PgHaMigrations.config.disable_default_migration_methods
9
5
  # Most migration methods are only ever called by a migration and
10
6
  # therefore aren't re-entrant or callable from another migration
@@ -12,7 +8,7 @@ module PgHaMigrations::UnsafeStatements
12
8
  # implementations in `ActiveRecord::Migration::Compatibility` so
13
9
  # we have to explicitly handle that case by allowing execution of
14
10
  # the original implementation by its original name.
15
- unless allow_reentry_from_compatibility_module && caller[0] =~ /lib\/active_record\/migration\/compatibility.rb/
11
+ unless allow_reentry_from_compatibility_module && caller[0] =~ /lib\/active_record\/migration\/compatibility.rb/
16
12
  raise PgHaMigrations::UnsafeMigrationError, error_message
17
13
  end
18
14
  end
@@ -22,51 +18,88 @@ module PgHaMigrations::UnsafeStatements
22
18
  ruby2_keywords method_name
23
19
  end
24
20
 
25
- def self.delegate_unsafe_method_to_migration_base_class(method_name)
21
+ def self.delegate_unsafe_method_to_migration_base_class(method_name, with_lock: true)
26
22
  define_method("unsafe_#{method_name}") do |*args, &block|
27
23
  if PgHaMigrations.config.check_for_dependent_objects
28
24
  disallow_migration_method_if_dependent_objects!(method_name, arguments: args)
29
25
  end
30
26
 
31
- execute_ancestor_statement(method_name, *args, &block)
27
+ if with_lock
28
+ safely_acquire_lock_for_table(args.first) do
29
+ execute_ancestor_statement(method_name, *args, &block)
30
+ end
31
+ else
32
+ execute_ancestor_statement(method_name, *args, &block)
33
+ end
32
34
  end
33
35
  ruby2_keywords "unsafe_#{method_name}"
34
36
  end
35
37
 
38
+ def self.delegate_raw_method_to_migration_base_class(method_name)
39
+ define_method("raw_#{method_name}") do |*args, &block|
40
+ execute_ancestor_statement(method_name, *args, &block)
41
+ end
42
+ ruby2_keywords "raw_#{method_name}"
43
+ end
44
+
45
+ # Direct dispatch to underlying Rails method as unsafe_<method_name> with dependent object check / safe lock acquisition
46
+ delegate_unsafe_method_to_migration_base_class :add_check_constraint
36
47
  delegate_unsafe_method_to_migration_base_class :add_column
37
- delegate_unsafe_method_to_migration_base_class :change_table
38
- delegate_unsafe_method_to_migration_base_class :drop_table
39
- delegate_unsafe_method_to_migration_base_class :rename_table
40
- delegate_unsafe_method_to_migration_base_class :rename_column
41
48
  delegate_unsafe_method_to_migration_base_class :change_column
42
49
  delegate_unsafe_method_to_migration_base_class :change_column_default
43
- delegate_unsafe_method_to_migration_base_class :remove_column
44
- delegate_unsafe_method_to_migration_base_class :execute
45
- delegate_unsafe_method_to_migration_base_class :remove_index
46
- delegate_unsafe_method_to_migration_base_class :add_foreign_key
47
- delegate_unsafe_method_to_migration_base_class :remove_foreign_key
48
- delegate_unsafe_method_to_migration_base_class :add_check_constraint
50
+ delegate_unsafe_method_to_migration_base_class :drop_table
51
+ delegate_unsafe_method_to_migration_base_class :execute, with_lock: false # too generic for locking
49
52
  delegate_unsafe_method_to_migration_base_class :remove_check_constraint
53
+ delegate_unsafe_method_to_migration_base_class :remove_column
54
+ delegate_unsafe_method_to_migration_base_class :rename_column
55
+ delegate_unsafe_method_to_migration_base_class :rename_table
50
56
 
51
- disable_or_delegate_default_method :create_table, ":create_table is NOT SAFE! Use safe_create_table instead"
57
+ # Direct dispatch to underlying Rails method as raw_<method_name> without dependent object check / locking
58
+ delegate_raw_method_to_migration_base_class :add_check_constraint
59
+ delegate_raw_method_to_migration_base_class :add_column
60
+ delegate_raw_method_to_migration_base_class :add_foreign_key
61
+ delegate_raw_method_to_migration_base_class :add_index
62
+ delegate_raw_method_to_migration_base_class :change_column
63
+ delegate_raw_method_to_migration_base_class :change_column_default
64
+ delegate_raw_method_to_migration_base_class :change_column_null
65
+ delegate_raw_method_to_migration_base_class :change_table
66
+ delegate_raw_method_to_migration_base_class :create_table
67
+ delegate_raw_method_to_migration_base_class :drop_table
68
+ delegate_raw_method_to_migration_base_class :execute
69
+ delegate_raw_method_to_migration_base_class :remove_check_constraint
70
+ delegate_raw_method_to_migration_base_class :remove_column
71
+ delegate_raw_method_to_migration_base_class :remove_foreign_key
72
+ delegate_raw_method_to_migration_base_class :remove_index
73
+ delegate_raw_method_to_migration_base_class :rename_column
74
+ delegate_raw_method_to_migration_base_class :rename_table
75
+
76
+ # Raises error if disable_default_migration_methods is true
77
+ # Otherwise, direct dispatch to underlying Rails method without dependent object check / locking
78
+ disable_or_delegate_default_method :add_check_constraint, ":add_check_constraint is NOT SAFE! Use :safe_add_unvalidated_check_constraint and then :safe_validate_check_constraint instead"
52
79
  disable_or_delegate_default_method :add_column, ":add_column is NOT SAFE! Use safe_add_column instead"
53
- disable_or_delegate_default_method :change_table, ":change_table is NOT SAFE! Use a combination of safe and explicit unsafe migration methods instead"
54
- disable_or_delegate_default_method :drop_table, ":drop_table is NOT SAFE! Explicitly call :unsafe_drop_table to proceed"
55
- disable_or_delegate_default_method :rename_table, ":rename_table is NOT SAFE! Explicitly call :unsafe_rename_table to proceed"
56
- disable_or_delegate_default_method :rename_column, ":rename_column is NOT SAFE! Explicitly call :unsafe_rename_column to proceed"
80
+ disable_or_delegate_default_method :add_foreign_key, ":add_foreign_key is NOT SAFE! Explicitly call :unsafe_add_foreign_key"
81
+ disable_or_delegate_default_method :add_index, ":add_index is NOT SAFE! Use safe_add_concurrent_index instead"
57
82
  disable_or_delegate_default_method :change_column, ":change_column is NOT SAFE! Use a combination of safe and explicit unsafe migration methods instead"
58
83
  disable_or_delegate_default_method :change_column_default, ":change_column_default is NOT SAFE! Use safe_change_column_default instead"
59
84
  disable_or_delegate_default_method :change_column_null, ":change_column_null is NOT (guaranteed to be) SAFE! Either use :safe_make_column_nullable or explicitly call :unsafe_make_column_not_nullable to proceed"
60
- disable_or_delegate_default_method :remove_column, ":remove_column is NOT SAFE! Explicitly call :unsafe_remove_column to proceed"
61
- disable_or_delegate_default_method :add_index, ":add_index is NOT SAFE! Use safe_add_concurrent_index instead"
85
+ disable_or_delegate_default_method :change_table, ":change_table is NOT SAFE! Use a combination of safe and explicit unsafe migration methods instead"
86
+ disable_or_delegate_default_method :create_table, ":create_table is NOT SAFE! Use safe_create_table instead"
87
+ disable_or_delegate_default_method :drop_table, ":drop_table is NOT SAFE! Explicitly call :unsafe_drop_table to proceed"
62
88
  disable_or_delegate_default_method :execute, ":execute is NOT SAFE! Explicitly call :unsafe_execute to proceed", allow_reentry_from_compatibility_module: true
63
- disable_or_delegate_default_method :remove_index, ":remove_index is NOT SAFE! Use safe_remove_concurrent_index instead for Postgres 9.6 databases; Explicitly call :unsafe_remove_index to proceed on Postgres 9.1"
64
- disable_or_delegate_default_method :add_foreign_key, ":add_foreign_key is NOT SAFE! Explicitly call :unsafe_add_foreign_key"
65
- disable_or_delegate_default_method :remove_foreign_key, ":remove_foreign_key is NOT SAFE! Explicitly call :unsafe_remove_foreign_key"
66
- disable_or_delegate_default_method :add_check_constraint, ":add_check_constraint is NOT SAFE! Use :safe_add_unvalidated_check_constraint and then :safe_validate_check_constraint instead"
67
89
  disable_or_delegate_default_method :remove_check_constraint, ":remove_check_constraint is NOT SAFE! Explicitly call :unsafe_remove_check_constraint to proceed"
90
+ disable_or_delegate_default_method :remove_column, ":remove_column is NOT SAFE! Explicitly call :unsafe_remove_column to proceed"
91
+ disable_or_delegate_default_method :remove_foreign_key, ":remove_foreign_key is NOT SAFE! Explicitly call :unsafe_remove_foreign_key"
92
+ disable_or_delegate_default_method :remove_index, ":remove_index is NOT SAFE! Use safe_remove_concurrent_index instead for Postgres 9.6 databases; Explicitly call :unsafe_remove_index to proceed on Postgres 9.1"
93
+ disable_or_delegate_default_method :rename_column, ":rename_column is NOT SAFE! Explicitly call :unsafe_rename_column to proceed"
94
+ disable_or_delegate_default_method :rename_table, ":rename_table is NOT SAFE! Explicitly call :unsafe_rename_table to proceed"
95
+
96
+ # Note that unsafe_* methods defined below do not run dependent object checks
97
+
98
+ def unsafe_change_table(*args, &block)
99
+ raise PgHaMigrations::UnsafeMigrationError.new(":change_table is too generic to even allow an unsafe variant. Use a combination of safe and explicit unsafe migration methods instead")
100
+ end
68
101
 
69
- def unsafe_create_table(table, options={}, &block)
102
+ def unsafe_create_table(table, **options, &block)
70
103
  if options[:force] && !PgHaMigrations.config.allow_force_create_table
71
104
  raise PgHaMigrations::UnsafeMigrationError.new(":force is NOT SAFE! Explicitly call unsafe_drop_table first if you want to recreate an existing table")
72
105
  end
@@ -74,13 +107,108 @@ module PgHaMigrations::UnsafeStatements
74
107
  execute_ancestor_statement(:create_table, table, **options, &block)
75
108
  end
76
109
 
77
- def unsafe_add_index(table, column_names, options = {})
110
+ def unsafe_add_index(table, column_names, **options)
78
111
  if ((ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR >= 2) || ActiveRecord::VERSION::MAJOR > 5) &&
79
112
  column_names.is_a?(String) && /\W/.match?(column_names) && options.key?(:opclass)
80
113
  raise PgHaMigrations::InvalidMigrationError, "ActiveRecord drops the :opclass option when supplying a string containing an expression or list of columns; instead either supply an array of columns or include the opclass in the string for each column"
81
114
  end
82
115
 
83
- execute_ancestor_statement(:add_index, table, column_names, **options)
116
+ validated_table = PgHaMigrations::Table.from_table_name(table)
117
+
118
+ validated_index = if options[:name]
119
+ PgHaMigrations::Index.new(options[:name], validated_table)
120
+ else
121
+ PgHaMigrations::Index.from_table_and_columns(validated_table, column_names)
122
+ end
123
+
124
+ options[:name] = validated_index.name
125
+
126
+ if options[:algorithm] == :concurrently
127
+ execute_ancestor_statement(:add_index, table, column_names, **options)
128
+ else
129
+ safely_acquire_lock_for_table(table, mode: :share) do
130
+ execute_ancestor_statement(:add_index, table, column_names, **options)
131
+ end
132
+ end
133
+ end
134
+
135
+ def unsafe_remove_index(table, column = nil, **options)
136
+ if options[:algorithm]== :concurrently
137
+ execute_ancestor_statement(:remove_index, table, column, **options)
138
+ else
139
+ safely_acquire_lock_for_table(table) do
140
+ execute_ancestor_statement(:remove_index, table, column, **options)
141
+ end
142
+ end
143
+ end
144
+
145
+ def unsafe_add_foreign_key(from_table, to_table, **options)
146
+ safely_acquire_lock_for_table(from_table, to_table, mode: :share_row_exclusive) do
147
+ execute_ancestor_statement(:add_foreign_key, from_table, to_table, **options)
148
+ end
149
+ end
150
+
151
+ def unsafe_remove_foreign_key(from_table, to_table = nil, **options)
152
+ calculated_to_table = options.fetch(:to_table, to_table)
153
+
154
+ if calculated_to_table.nil?
155
+ raise PgHaMigrations::InvalidMigrationError.new("The :to_table positional arg / kwarg is required for lock acquisition")
156
+ end
157
+
158
+ safely_acquire_lock_for_table(from_table, calculated_to_table) do
159
+ execute_ancestor_statement(:remove_foreign_key, from_table, to_table, **options)
160
+ end
161
+ end
162
+
163
+ def unsafe_rename_enum_value(name, old_value, new_value)
164
+ if ActiveRecord::Base.connection.postgresql_version < 10_00_00
165
+ raise PgHaMigrations::InvalidMigrationError, "Renaming an enum value is not supported on Postgres databases before version 10"
166
+ end
167
+
168
+ raw_execute("ALTER TYPE #{PG::Connection.quote_ident(name.to_s)} RENAME VALUE '#{PG::Connection.escape_string(old_value)}' TO '#{PG::Connection.escape_string(new_value)}'")
169
+ end
170
+
171
+ def unsafe_make_column_not_nullable(table, column, **options) # options arg is only present for backwards compatiblity
172
+ quoted_table_name = connection.quote_table_name(table)
173
+ quoted_column_name = connection.quote_column_name(column)
174
+
175
+ safely_acquire_lock_for_table(table) do
176
+ raw_execute("ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quoted_column_name} SET NOT NULL")
177
+ end
178
+ end
179
+
180
+ def unsafe_remove_constraint(table, name:)
181
+ raise ArgumentError, "Expected <name> to be present" unless name.present?
182
+
183
+ quoted_table_name = connection.quote_table_name(table)
184
+ quoted_constraint_name = connection.quote_table_name(name)
185
+ sql = "ALTER TABLE #{quoted_table_name} DROP CONSTRAINT #{quoted_constraint_name}"
186
+
187
+ safely_acquire_lock_for_table(table) do
188
+ say_with_time "remove_constraint(#{table.inspect}, name: #{name.inspect})" do
189
+ connection.execute(sql)
190
+ end
191
+ end
192
+ end
193
+
194
+ def unsafe_partman_update_config(table, **options)
195
+ invalid_options = options.keys - PgHaMigrations::PARTMAN_UPDATE_CONFIG_OPTIONS
196
+
197
+ raise ArgumentError, "Unrecognized argument(s): #{invalid_options}" unless invalid_options.empty?
198
+
199
+ PgHaMigrations::PartmanConfig.schema = _quoted_partman_schema
200
+
201
+ config = PgHaMigrations::PartmanConfig.find(_fully_qualified_table_name_for_partman(table))
202
+
203
+ config.assign_attributes(**options)
204
+
205
+ inherit_privileges_changed = config.inherit_privileges_changed?
206
+
207
+ say_with_time "partman_update_config(#{table.inspect}, #{options.map { |k,v| "#{k}: #{v.inspect}" }.join(", ")})" do
208
+ config.save!
209
+ end
210
+
211
+ safe_partman_reapply_privileges(table) if inherit_privileges_changed
84
212
  end
85
213
 
86
214
  ruby2_keywords def execute_ancestor_statement(method_name, *args, &block)
@@ -1,3 +1,3 @@
1
1
  module PgHaMigrations
2
- VERSION = "1.7.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -2,6 +2,8 @@ require "pg_ha_migrations/version"
2
2
  require "rails"
3
3
  require "active_record"
4
4
  require "active_record/migration"
5
+ require "active_record/connection_adapters/postgresql/utils"
6
+ require "active_support/core_ext/numeric/bytes"
5
7
  require "relation_to_struct"
6
8
  require "ruby2_keywords"
7
9
 
@@ -17,9 +19,9 @@ module PgHaMigrations
17
19
  def self.config
18
20
  @config ||= Config.new(
19
21
  true,
20
- false,
21
22
  true,
22
23
  false,
24
+ true,
23
25
  true
24
26
  )
25
27
  end
@@ -30,6 +32,17 @@ module PgHaMigrations
30
32
 
31
33
  LOCK_TIMEOUT_SECONDS = 5
32
34
  LOCK_FAILURE_RETRY_DELAY_MULTLIPLIER = 5
35
+ SMALL_TABLE_THRESHOLD_BYTES = 10.megabytes
36
+
37
+ PARTITION_TYPES = %i[range list hash]
38
+
39
+ PARTMAN_UPDATE_CONFIG_OPTIONS = %i[
40
+ infinite_time_partitions
41
+ inherit_privileges
42
+ premake
43
+ retention
44
+ retention_keep_table
45
+ ]
33
46
 
34
47
  # Safe versus unsafe in this context specifically means the following:
35
48
  # - Safe operations will not block for long periods of time.
@@ -52,11 +65,18 @@ module PgHaMigrations
52
65
 
53
66
  # This gem only supports the PostgreSQL adapter at this time.
54
67
  UnsupportedAdapter = Class.new(StandardError)
68
+
69
+ # Some methods need to inspect the attributes of a table. In such cases,
70
+ # this error will be raised if the table does not exist
71
+ UndefinedTableError = Class.new(StandardError)
55
72
  end
56
73
 
74
+ require "pg_ha_migrations/constraint"
75
+ require "pg_ha_migrations/relation"
57
76
  require "pg_ha_migrations/blocking_database_transactions"
58
77
  require "pg_ha_migrations/blocking_database_transactions_reporter"
59
78
  require "pg_ha_migrations/partman_config"
79
+ require "pg_ha_migrations/lock_mode"
60
80
  require "pg_ha_migrations/unsafe_statements"
61
81
  require "pg_ha_migrations/safe_statements"
62
82
  require "pg_ha_migrations/dependent_objects_checks"
@@ -64,6 +84,7 @@ require "pg_ha_migrations/allowed_versions"
64
84
  require "pg_ha_migrations/railtie"
65
85
  require "pg_ha_migrations/hacks/disable_ddl_transaction"
66
86
  require "pg_ha_migrations/hacks/cleanup_unnecessary_output"
87
+ require "pg_ha_migrations/hacks/add_index_on_only"
67
88
 
68
89
  module PgHaMigrations::AutoIncluder
69
90
  def inherited(klass)
@@ -32,12 +32,12 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "rake", ">= 12.3.3"
33
33
  spec.add_development_dependency "rspec", "~> 3.0"
34
34
  spec.add_development_dependency "pg"
35
- spec.add_development_dependency "db-query-matchers", "~> 0.11.0"
35
+ spec.add_development_dependency "db-query-matchers", "~> 0.14"
36
36
  spec.add_development_dependency "pry"
37
37
  spec.add_development_dependency "pry-byebug"
38
- spec.add_development_dependency "appraisal", "~> 2.2.0"
38
+ spec.add_development_dependency "appraisal", "~> 2.5"
39
39
 
40
- spec.add_dependency "rails", ">= 6.1", "< 7.1"
40
+ spec.add_dependency "rails", ">= 7.1", "< 8.1"
41
41
  spec.add_dependency "relation_to_struct", ">= 1.5.1"
42
42
  spec.add_dependency "ruby2_keywords"
43
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_ha_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - celeen
@@ -11,10 +11,9 @@ authors:
11
11
  - kexline4710
12
12
  - mgates
13
13
  - redneckbeard
14
- autorequire:
15
14
  bindir: exe
16
15
  cert_chain: []
17
- date: 2023-08-10 00:00:00.000000000 Z
16
+ date: 2025-04-17 00:00:00.000000000 Z
18
17
  dependencies:
19
18
  - !ruby/object:Gem::Dependency
20
19
  name: rake
@@ -64,14 +63,14 @@ dependencies:
64
63
  requirements:
65
64
  - - "~>"
66
65
  - !ruby/object:Gem::Version
67
- version: 0.11.0
66
+ version: '0.14'
68
67
  type: :development
69
68
  prerelease: false
70
69
  version_requirements: !ruby/object:Gem::Requirement
71
70
  requirements:
72
71
  - - "~>"
73
72
  - !ruby/object:Gem::Version
74
- version: 0.11.0
73
+ version: '0.14'
75
74
  - !ruby/object:Gem::Dependency
76
75
  name: pry
77
76
  requirement: !ruby/object:Gem::Requirement
@@ -106,34 +105,34 @@ dependencies:
106
105
  requirements:
107
106
  - - "~>"
108
107
  - !ruby/object:Gem::Version
109
- version: 2.2.0
108
+ version: '2.5'
110
109
  type: :development
111
110
  prerelease: false
112
111
  version_requirements: !ruby/object:Gem::Requirement
113
112
  requirements:
114
113
  - - "~>"
115
114
  - !ruby/object:Gem::Version
116
- version: 2.2.0
115
+ version: '2.5'
117
116
  - !ruby/object:Gem::Dependency
118
117
  name: rails
119
118
  requirement: !ruby/object:Gem::Requirement
120
119
  requirements:
121
120
  - - ">="
122
121
  - !ruby/object:Gem::Version
123
- version: '6.1'
122
+ version: '7.1'
124
123
  - - "<"
125
124
  - !ruby/object:Gem::Version
126
- version: '7.1'
125
+ version: '8.1'
127
126
  type: :runtime
128
127
  prerelease: false
129
128
  version_requirements: !ruby/object:Gem::Requirement
130
129
  requirements:
131
130
  - - ">="
132
131
  - !ruby/object:Gem::Version
133
- version: '6.1'
132
+ version: '7.1'
134
133
  - - "<"
135
134
  - !ruby/object:Gem::Version
136
- version: '7.1'
135
+ version: '8.1'
137
136
  - !ruby/object:Gem::Dependency
138
137
  name: relation_to_struct
139
138
  requirement: !ruby/object:Gem::Requirement
@@ -186,17 +185,22 @@ files:
186
185
  - bin/setup
187
186
  - docker-compose.yml
188
187
  - gemfiles/.bundle/config
189
- - gemfiles/rails_6.1.gemfile
190
- - gemfiles/rails_7.0.gemfile
188
+ - gemfiles/rails_7.1.gemfile
189
+ - gemfiles/rails_7.2.gemfile
190
+ - gemfiles/rails_8.0.gemfile
191
191
  - lib/pg_ha_migrations.rb
192
192
  - lib/pg_ha_migrations/allowed_versions.rb
193
193
  - lib/pg_ha_migrations/blocking_database_transactions.rb
194
194
  - lib/pg_ha_migrations/blocking_database_transactions_reporter.rb
195
+ - lib/pg_ha_migrations/constraint.rb
195
196
  - lib/pg_ha_migrations/dependent_objects_checks.rb
197
+ - lib/pg_ha_migrations/hacks/add_index_on_only.rb
196
198
  - lib/pg_ha_migrations/hacks/cleanup_unnecessary_output.rb
197
199
  - lib/pg_ha_migrations/hacks/disable_ddl_transaction.rb
200
+ - lib/pg_ha_migrations/lock_mode.rb
198
201
  - lib/pg_ha_migrations/partman_config.rb
199
202
  - lib/pg_ha_migrations/railtie.rb
203
+ - lib/pg_ha_migrations/relation.rb
200
204
  - lib/pg_ha_migrations/safe_statements.rb
201
205
  - lib/pg_ha_migrations/unsafe_statements.rb
202
206
  - lib/pg_ha_migrations/version.rb
@@ -206,7 +210,6 @@ homepage: ''
206
210
  licenses:
207
211
  - MIT
208
212
  metadata: {}
209
- post_install_message:
210
213
  rdoc_options: []
211
214
  require_paths:
212
215
  - lib
@@ -221,8 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
224
  - !ruby/object:Gem::Version
222
225
  version: '0'
223
226
  requirements: []
224
- rubygems_version: 3.2.3
225
- signing_key:
227
+ rubygems_version: 3.6.2
226
228
  specification_version: 4
227
229
  summary: Enforces DDL/migration safety in Ruby on Rails project with an emphasis on
228
230
  explicitly choosing trade-offs and avoiding unnecessary magic.