pg_ha_migrations 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b472247321efcc716bc1f7c4e497dcbe32058e4d2ce11d8f6d0d9fea7136755
4
- data.tar.gz: 820bf96e3200deb2cffd30ba5534513600d05138f57f7812539cc8b33f96058a
3
+ metadata.gz: 36546429641ce670fa116d251f17993538b3ab60b5014c1917103e45b1fa0f45
4
+ data.tar.gz: 969078be676bc767aa8f325328da8aeda95b6120e620c5d8556bda639c94a3f4
5
5
  SHA512:
6
- metadata.gz: b95318b6bf16ea1f5c9ec2514a6d6cccf912fc051caa9a954c58a038431d9afbbf01a23576f4ceaab1856922dc6e9aee5573743abb619f494c0f6023dcb217a9
7
- data.tar.gz: 8bf47117312865cf57b51d200f3d131c266171a0f9899f39b8aa3f09aad50842555d93007a0b33a00873a7d67ec56a0f9b9027a028bf28338399939cd285ceda
6
+ metadata.gz: d2ee13eed929c6278cf745b6b4e4ecff210858e930f97be67d0db2ff4bd2efc65288cc2c80090343cb6cc3e2097c8e1fcf62955fddf442eced723660793706df
7
+ data.tar.gz: d1f0853d0d47774e889835716f6619097f3e56016e8997a7115e31c34e87dfc80b0871eee128161f4583247265afbfd9aeae752312dad4bb11a5dd5bf0946184
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /gemfiles/*.lock
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
data/.travis.yml CHANGED
@@ -9,3 +9,8 @@ addons:
9
9
  before_install:
10
10
  - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
11
11
  - gem install bundler -v 1.15.4
12
+ gemfile:
13
+ - gemfiles/rails_5.0.gemfile
14
+ - gemfiles/rails_5.1.gemfile
15
+ - gemfiles/rails_5.2.gemfile
16
+ script: "bundle exec rake spec"
data/Appraisals ADDED
@@ -0,0 +1,12 @@
1
+ appraise "rails-5.0" do
2
+ gem "rails", "5.0.7.2"
3
+ end
4
+
5
+ appraise "rails-5.1" do
6
+ gem "rails", "5.1.7"
7
+ end
8
+
9
+ appraise "rails-5.2" do
10
+ gem "rails", "5.2.3"
11
+ end
12
+
data/README.md CHANGED
@@ -127,7 +127,13 @@ unsafe_add_column :table, :column, :type
127
127
  Safely change the default value for a column.
128
128
 
129
129
  ```ruby
130
+ # Constant value:
130
131
  safe_change_column_default :table, :column, "value"
132
+ safe_change_column_default :table, :column, DateTime.new(...)
133
+ # Functional expression evaluated at row insert time:
134
+ safe_change_column_default :table, :column, -> { "NOW()" }
135
+ # Functional expression evaluated at migration time:
136
+ safe_change_column_default :table, :column, -> { "'NOW()'" }
131
137
  ```
132
138
 
133
139
  #### safe\_make\_column\_nullable
@@ -168,6 +174,37 @@ Safely remove an index. Migrations that contain this statement must also include
168
174
  safe_remove_concurrent_index :table, :name => :index_name
169
175
  ```
170
176
 
177
+ #### safe\_add\_unvalidated\_check\_constraint
178
+
179
+ Safely add a `CHECK` constraint. The constraint will not be immediately validated on existing rows to avoid a full table scan while holding an exclusive lock. After adding the constraint, you'll need to use `safe_validate_check_constraint` to validate existing rows.
180
+
181
+ ```ruby
182
+ safe_add_unvalidated_check_constraint :table, "column LIKE 'example%'", name: :constraint_table_on_column_like_example
183
+ ```
184
+
185
+ #### safe\_validate\_check\_constraint
186
+
187
+ Safely validate (without acquiring an exclusive lock) existing rows for a newly added but as-yet unvalidated `CHECK` constraint.
188
+
189
+ ```ruby
190
+ safe_validate_check_constraint :table, name: :constraint_table_on_column_like_example
191
+ ```
192
+
193
+ #### safe\_rename\_constraint
194
+
195
+ Safely rename any (not just `CHECK`) constraint.
196
+
197
+ ```ruby
198
+ safe_rename_constraint :table, from: :constraint_table_on_column_like_typo, to: :constraint_table_on_column_like_example
199
+ ```
200
+
201
+ #### unsafe\_remove\_constraint
202
+
203
+ Drop any (not just `CHECK`) constraint.
204
+
205
+ ```ruby
206
+ unsafe_remove_constraint :table, name: :constraint_table_on_column_like_example
207
+ ```
171
208
 
172
209
  ### Utilities
173
210
 
data/Rakefile CHANGED
@@ -1,8 +1,13 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "appraisal"
3
4
  require_relative File.join("lib", "pg_ha_migrations")
4
5
 
5
6
  RSpec::Core::RakeTask.new(:spec)
6
7
 
8
+ if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
9
+ task :default => :appraisal
10
+ end
11
+
7
12
  task :default => :spec
8
13
 
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_RETRY: "1"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "5.0.7.2"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "5.1.7"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "5.2.3"
6
+
7
+ gemspec path: "../"
@@ -1,13 +1,23 @@
1
1
  module PgHaMigrations
2
2
  class BlockingDatabaseTransactions
3
- LongRunningTransaction = Struct.new(:database, :current_query, :transaction_age, :tables_with_locks) do
3
+ LongRunningTransaction = Struct.new(:database, :current_query, :state, :transaction_age, :tables_with_locks) do
4
4
  def description
5
- "#{database} | tables (#{tables_with_locks.join(', ')}) have been locked for #{transaction_age} | query: #{current_query}"
5
+ locked_tables = tables_with_locks.compact
6
+ [
7
+ database,
8
+ locked_tables.size > 0 ? "tables (#{locked_tables.join(', ')})" : nil,
9
+ "#{idle? ? "currently idle " : ""}transaction open for #{transaction_age}",
10
+ "#{idle? ? "last " : ""}query: #{current_query}"
11
+ ].compact.join(" | ")
6
12
  end
7
13
 
8
14
  def concurrent_index_creation?
9
15
  !!current_query.match(/create\s+index\s+concurrently/i)
10
16
  end
17
+
18
+ def idle?
19
+ state == "idle in transaction"
20
+ end
11
21
  end
12
22
 
13
23
  def self.autovacuum_regex
@@ -15,7 +25,7 @@ module PgHaMigrations
15
25
  end
16
26
 
17
27
  def self.find_blocking_transactions(minimum_transaction_age = "0 seconds")
18
- pid_column, state_column = if ActiveRecord::Base.connection.select_value("SHOW server_version") =~ /9\.1/
28
+ pid_column, query_column = if ActiveRecord::Base.connection.select_value("SHOW server_version") =~ /9\.1/
19
29
  ["procpid", "current_query"]
20
30
  else
21
31
  ["pid", "query"]
@@ -24,26 +34,32 @@ module PgHaMigrations
24
34
  raw_query = <<-SQL
25
35
  SELECT
26
36
  psa.datname as database, -- Will only ever be one database
27
- psa.#{state_column} as current_query,
37
+ psa.#{query_column} as current_query,
38
+ psa.state,
28
39
  clock_timestamp() - psa.xact_start AS transaction_age,
29
40
  array_agg(distinct c.relname) AS tables_with_locks
30
41
  FROM pg_stat_activity psa -- Cluster wide
31
- JOIN pg_locks l ON (psa.#{pid_column} = l.pid) -- Cluster wide
32
- JOIN pg_class c ON (l.relation = c.oid) -- Database wide
33
- JOIN pg_namespace ns ON (c.relnamespace = ns.oid) -- Database wide
34
- WHERE psa.#{pid_column} != pg_backend_pid()
35
- AND ns.nspname != 'pg_catalog'
36
- AND c.relkind = 'r'
37
- AND psa.xact_start < clock_timestamp() - ?::interval
38
- AND psa.#{state_column} !~ ?
39
- AND (
42
+ LEFT JOIN pg_locks l ON (psa.#{pid_column} = l.pid) -- Cluster wide
43
+ LEFT JOIN pg_class c ON ( -- Database wide
44
+ l.locktype = 'relation'
45
+ AND l.relation = c.oid
40
46
  -- Be explicit about this being for a single database -- it's already implicit in
41
47
  -- the relations used, and if we don't restrict this we could get incorrect results
42
48
  -- with oid collisions from pg_namespace and pg_class.
43
- l.database = 0
44
- OR l.database = (SELECT d.oid FROM pg_database d WHERE d.datname = current_database())
49
+ AND l.database = (SELECT d.oid FROM pg_database d WHERE d.datname = current_database())
45
50
  )
46
- GROUP BY psa.datname, psa.#{state_column}, psa.xact_start
51
+ LEFT JOIN pg_namespace ns ON (c.relnamespace = ns.oid) -- Database wide
52
+ WHERE psa.#{pid_column} != pg_backend_pid()
53
+ AND (
54
+ l.locktype != 'relation'
55
+ OR (
56
+ ns.nspname != 'pg_catalog'
57
+ AND c.relkind = 'r'
58
+ )
59
+ )
60
+ AND psa.xact_start < clock_timestamp() - ?::interval
61
+ AND psa.#{query_column} !~ ?
62
+ GROUP BY psa.datname, psa.#{query_column}, psa.state, psa.xact_start
47
63
  SQL
48
64
 
49
65
  query = ActiveRecord::Base.send(:sanitize_sql_for_conditions, [raw_query, minimum_transaction_age, autovacuum_regex])
@@ -0,0 +1,29 @@
1
+ require "active_record/migration/compatibility"
2
+
3
+ module PgHaMigrations
4
+ module ActiveRecordHacks
5
+ module CleanupUnnecessaryOutput
6
+ # This is fixed in Rails 6+, but previously there were several
7
+ # places where #adapter_name was called directly which implicitly
8
+ # delegated to the connection through #method_missing. That
9
+ # delegation though results in wrapping the call in #say_with_time
10
+ # which unnecessarily outputs a bunch of calls to #adapter_name.
11
+ # The easiest way to clean this up retroactively is to just patch
12
+ # in a direct dispatch to the connection's method.
13
+ #
14
+ # See: https://github.com/rails/rails/commit/eb7c71bcd3d0c7e079dffdb11e43fb466eec06aa
15
+ def adapter_name
16
+ connection.adapter_name
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ patchable_module = [
23
+ defined?(ActiveRecord::Migration::Compatibility::V5_2) ? ActiveRecord::Migration::Compatibility::V5_2 : nil,
24
+ defined?(ActiveRecord::Migration::Compatibility::V5_1) ? ActiveRecord::Migration::Compatibility::V5_1 : nil,
25
+ defined?(ActiveRecord::Migration::Compatibility::V5_0) ? ActiveRecord::Migration::Compatibility::V5_0 : nil,
26
+ ].detect { |m| m }
27
+ if patchable_module
28
+ patchable_module.prepend(PgHaMigrations::ActiveRecordHacks::CleanupUnnecessaryOutput)
29
+ end
@@ -45,10 +45,51 @@ module PgHaMigrations::SafeStatements
45
45
  def safe_change_column_default(table_name, column_name, default_value)
46
46
  column = connection.send(:column_for, table_name, column_name)
47
47
 
48
+ # In 5.2 we have an edge whereby passing in a string literal with an expression
49
+ # results in confusing behavior because instead of being executed in the database
50
+ # that expression is turned into a Ruby nil before being sent to the database layer;
51
+ # this seems to be an expected side effect of a change that was targeted at a use
52
+ # case unrelated to migrations: https://github.com/rails/rails/commit/7b2dfdeab6e4ef096e4dc1fe313056f08ccf7dc5
53
+ #
54
+ # On the other hand, the behavior in 5.1 is also confusing because it quotes the
55
+ # expression (instead of maintaining the string as-is), which results in Postgres
56
+ # evaluating the expression once when executing the DDL and setting the default to
57
+ # the constant result of that evaluation rather than setting the default to the
58
+ # expression itself.
59
+ #
60
+ # Therefore we want to disallow passing in an expression directly as a string and
61
+ # require the use of a Proc instead with specific quoting rules to determine exact
62
+ # behavior. It's fairly difficult (without relying on something like the PgQuery gem
63
+ # which requires native extensions built with the Postgres dev packages installed)
64
+ # to determine if a string literal represent an expression or just a constant. So
65
+ # instead of trying to parse the expression, we employ a set of heuristics:
66
+ # - If the column is text-like or binary, then we can allow anything in the default
67
+ # value since a Ruby string there will always coerce directly to the equivalent
68
+ # text/binary value rather than being interpreted as a DDL-time expression.
69
+ # - Otherwise, disallow any Ruby string values and instead require the Ruby object
70
+ # type that maps to the column type.
71
+ #
72
+ # These heuristics eliminate (virtually?) all ambiguity. In theory there's a
73
+ # possiblity that some custom object could be coerced-Ruby side into a SQL string
74
+ # that does something weird here, but that seems an odd enough case that we can
75
+ # safely ignore it.
48
76
  if default_value.present? &&
49
77
  !default_value.is_a?(Proc) &&
50
- quote_default_expression(default_value, column) == "NULL"
51
- raise PgHaMigrations::InvalidMigrationError, "Requested new default value of <#{default_value}>, but that casts to NULL for the type <#{column.type}>. Did you mean to you mean to use a Proc instead?"
78
+ (
79
+ connection.quote_default_expression(default_value, column) == "NULL" ||
80
+ (
81
+ ![:string, :text, :binary].include?(column.sql_type_metadata.type) &&
82
+ default_value.is_a?(String)
83
+ )
84
+ )
85
+ raise PgHaMigrations::InvalidMigrationError, <<~ERROR
86
+ Setting a default value to an expression using a string literal is ambiguous.
87
+
88
+ If you want the default to be:
89
+ * ...a constant scalar value, use the matching Ruby object type instead of a string if possible (e.g., `DateTime.new(...)`).
90
+ * ...an expression evaluated at runtime for each row, then pass a Proc that returns the expression string (e.g., `-> { "NOW()" }`).
91
+ * ...an expression evaluated at migration time, then pass a Proc that returns a quoted expression string (e.g., `-> { "'NOW()'" }`).
92
+ ERROR
52
93
  end
53
94
 
54
95
  safely_acquire_lock_for_table(table_name) do
@@ -76,7 +117,7 @@ module PgHaMigrations::SafeStatements
76
117
  unless options.is_a?(Hash) && options.key?(:name)
77
118
  raise ArgumentError, "Expected safe_remove_concurrent_index to be called with arguments (table_name, :name => ...)"
78
119
  end
79
- unless ActiveRecord::Base.connection.postgresql_version >= 90600
120
+ unless ActiveRecord::Base.connection.postgresql_version >= 9_06_00
80
121
  raise PgHaMigrations::InvalidMigrationError, "Removing an index concurrently is not supported on Postgres 9.1 databases"
81
122
  end
82
123
  index_size = select_value("SELECT pg_size_pretty(pg_relation_size('#{options[:name]}'))")
@@ -88,6 +129,66 @@ module PgHaMigrations::SafeStatements
88
129
  unsafe_execute("SET maintenance_work_mem = '#{PG::Connection.escape_string(gigabytes.to_s)} GB'")
89
130
  end
90
131
 
132
+ def safe_add_unvalidated_check_constraint(table, expression, name:)
133
+ unsafe_add_check_constraint(table, expression, name: name, validate: false)
134
+ end
135
+
136
+ def unsafe_add_check_constraint(table, expression, name:, validate: true)
137
+ raise ArgumentError, "Expected <name> to be present" unless name.present?
138
+
139
+ quoted_table_name = connection.quote_table_name(table)
140
+ quoted_constraint_name = connection.quote_table_name(name)
141
+ sql = "ALTER TABLE #{quoted_table_name} ADD CONSTRAINT #{quoted_constraint_name} CHECK (#{expression}) #{validate ? "" : "NOT VALID"}"
142
+
143
+ safely_acquire_lock_for_table(table) do
144
+ say_with_time "add_check_constraint(#{table.inspect}, #{expression.inspect}, name: #{name.inspect}, validate: #{validate.inspect})" do
145
+ connection.execute(sql)
146
+ end
147
+ end
148
+ end
149
+
150
+ def safe_validate_check_constraint(table, name:)
151
+ raise ArgumentError, "Expected <name> to be present" unless name.present?
152
+
153
+ quoted_table_name = connection.quote_table_name(table)
154
+ quoted_constraint_name = connection.quote_table_name(name)
155
+ sql = "ALTER TABLE #{quoted_table_name} VALIDATE CONSTRAINT #{quoted_constraint_name}"
156
+
157
+ say_with_time "validate_check_constraint(#{table.inspect}, name: #{name.inspect})" do
158
+ connection.execute(sql)
159
+ end
160
+ end
161
+
162
+ def safe_rename_constraint(table, from:, to:)
163
+ raise ArgumentError, "Expected <from> to be present" unless from.present?
164
+ raise ArgumentError, "Expected <to> to be present" unless to.present?
165
+
166
+ quoted_table_name = connection.quote_table_name(table)
167
+ quoted_constraint_from_name = connection.quote_table_name(from)
168
+ quoted_constraint_to_name = connection.quote_table_name(to)
169
+ sql = "ALTER TABLE #{quoted_table_name} RENAME CONSTRAINT #{quoted_constraint_from_name} TO #{quoted_constraint_to_name}"
170
+
171
+ safely_acquire_lock_for_table(table) do
172
+ say_with_time "rename_constraint(#{table.inspect}, from: #{from.inspect}, to: #{to.inspect})" do
173
+ connection.execute(sql)
174
+ end
175
+ end
176
+ end
177
+
178
+ def unsafe_remove_constraint(table, name:)
179
+ raise ArgumentError, "Expected <name> to be present" unless name.present?
180
+
181
+ quoted_table_name = connection.quote_table_name(table)
182
+ quoted_constraint_name = connection.quote_table_name(name)
183
+ sql = "ALTER TABLE #{quoted_table_name} DROP CONSTRAINT #{quoted_constraint_name}"
184
+
185
+ safely_acquire_lock_for_table(table) do
186
+ say_with_time "remove_constraint(#{table.inspect}, name: #{name.inspect})" do
187
+ connection.execute(sql)
188
+ end
189
+ end
190
+ end
191
+
91
192
  def _per_migration_caller
92
193
  @_per_migration_caller ||= Kernel.caller
93
194
  end
@@ -98,6 +199,14 @@ module PgHaMigrations::SafeStatements
98
199
  raise PgHaMigrations::UnsupportedAdapter, "This gem only works with the #{expected_adapter} adapter, found #{actual_adapter} instead" unless actual_adapter == expected_adapter
99
200
  end
100
201
 
202
+ def migrate(direction)
203
+ if respond_to?(:change)
204
+ raise PgHaMigrations::UnsupportedMigrationError, "Tracking changes for automated rollback is not supported; use explicit #up instead."
205
+ end
206
+
207
+ super(direction)
208
+ end
209
+
101
210
  def exec_migration(conn, direction)
102
211
  _check_postgres_adapter!
103
212
  super(conn, direction)
@@ -123,7 +232,7 @@ module PgHaMigrations::SafeStatements
123
232
  end
124
233
 
125
234
  connection.transaction do
126
- adjust_timeout_method = connection.postgresql_version >= 90300 ? :adjust_lock_timeout : :adjust_statement_timeout
235
+ adjust_timeout_method = connection.postgresql_version >= 9_03_00 ? :adjust_lock_timeout : :adjust_statement_timeout
127
236
  begin
128
237
  method(adjust_timeout_method).call(PgHaMigrations::LOCK_TIMEOUT_SECONDS) do
129
238
  connection.execute("LOCK #{quoted_table_name};")
@@ -43,6 +43,7 @@ module PgHaMigrations::UnsafeStatements
43
43
  delegate_unsafe_method_to_migration_base_class :execute
44
44
  delegate_unsafe_method_to_migration_base_class :remove_index
45
45
  delegate_unsafe_method_to_migration_base_class :add_foreign_key
46
+ delegate_unsafe_method_to_migration_base_class :remove_foreign_key
46
47
 
47
48
  disable_or_delegate_default_method :create_table, ":create_table is NOT SAFE! Use safe_create_table instead"
48
49
  disable_or_delegate_default_method :add_column, ":add_column is NOT SAFE! Use safe_add_column instead"
@@ -58,6 +59,7 @@ module PgHaMigrations::UnsafeStatements
58
59
  disable_or_delegate_default_method :execute, ":execute is NOT SAFE! Explicitly call :unsafe_execute to proceed", allow_reentry_from_compatibility_module: true
59
60
  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"
60
61
  disable_or_delegate_default_method :add_foreign_key, ":add_foreign_key is NOT SAFE! Explicitly call :unsafe_add_foreign_key"
62
+ disable_or_delegate_default_method :remove_foreign_key, ":remove_foreign_key is NOT SAFE! Explicitly call :unsafe_remove_foreign_key"
61
63
 
62
64
  def unsafe_create_table(table, options={}, &block)
63
65
  if options[:force] && !PgHaMigrations.config.allow_force_create_table
@@ -1,3 +1,3 @@
1
1
  module PgHaMigrations
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -35,6 +35,10 @@ module PgHaMigrations
35
35
  # as expected or get the schema into an inconsistent state
36
36
  InvalidMigrationError = Class.new(Exception)
37
37
 
38
+ # Unsupported migrations use ActiveRecord::Migration features that
39
+ # we don't support, and therefore will likely have unexpected behavior.
40
+ UnsupportedMigrationError = Class.new(Exception)
41
+
38
42
  # This gem only supports the PostgreSQL adapter at this time.
39
43
  UnsupportedAdapter = Class.new(Exception)
40
44
  end
@@ -47,6 +51,7 @@ require "pg_ha_migrations/dependent_objects_checks"
47
51
  require "pg_ha_migrations/allowed_versions"
48
52
  require "pg_ha_migrations/railtie"
49
53
  require "pg_ha_migrations/hacks/disable_ddl_transaction"
54
+ require "pg_ha_migrations/hacks/cleanup_unnecessary_output"
50
55
 
51
56
  module PgHaMigrations::AutoIncluder
52
57
  def inherited(klass)
@@ -29,13 +29,13 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- spec.add_development_dependency "bundler", "~> 1.15"
33
32
  spec.add_development_dependency "rake", "~> 10.0"
34
33
  spec.add_development_dependency "rspec", "~> 3.0"
35
34
  spec.add_development_dependency "pg"
36
35
  spec.add_development_dependency "db-query-matchers", "~> 0.9.0"
37
- spec.add_development_dependency 'pry'
38
- spec.add_development_dependency 'pry-byebug'
36
+ spec.add_development_dependency "pry"
37
+ spec.add_development_dependency "pry-byebug"
38
+ spec.add_development_dependency "appraisal", "~> 2.2.0"
39
39
 
40
40
  spec.add_dependency "rails", ">= 5.0", "< 5.3"
41
41
  spec.add_dependency "relation_to_struct"
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.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - celeen
@@ -14,22 +14,8 @@ authors:
14
14
  autorequire:
15
15
  bindir: exe
16
16
  cert_chain: []
17
- date: 2019-09-05 00:00:00.000000000 Z
17
+ date: 2020-01-31 00:00:00.000000000 Z
18
18
  dependencies:
19
- - !ruby/object:Gem::Dependency
20
- name: bundler
21
- requirement: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - "~>"
24
- - !ruby/object:Gem::Version
25
- version: '1.15'
26
- type: :development
27
- prerelease: false
28
- version_requirements: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: '1.15'
33
19
  - !ruby/object:Gem::Dependency
34
20
  name: rake
35
21
  requirement: !ruby/object:Gem::Requirement
@@ -114,6 +100,20 @@ dependencies:
114
100
  - - ">="
115
101
  - !ruby/object:Gem::Version
116
102
  version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: appraisal
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 2.2.0
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 2.2.0
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: rails
119
119
  requirement: !ruby/object:Gem::Requirement
@@ -161,6 +161,7 @@ files:
161
161
  - ".rspec"
162
162
  - ".ruby-version"
163
163
  - ".travis.yml"
164
+ - Appraisals
164
165
  - CODE_OF_CONDUCT.md
165
166
  - Gemfile
166
167
  - LICENSE.txt
@@ -168,11 +169,16 @@ files:
168
169
  - Rakefile
169
170
  - bin/console
170
171
  - bin/setup
172
+ - gemfiles/.bundle/config
173
+ - gemfiles/rails_5.0.gemfile
174
+ - gemfiles/rails_5.1.gemfile
175
+ - gemfiles/rails_5.2.gemfile
171
176
  - lib/pg_ha_migrations.rb
172
177
  - lib/pg_ha_migrations/allowed_versions.rb
173
178
  - lib/pg_ha_migrations/blocking_database_transactions.rb
174
179
  - lib/pg_ha_migrations/blocking_database_transactions_reporter.rb
175
180
  - lib/pg_ha_migrations/dependent_objects_checks.rb
181
+ - lib/pg_ha_migrations/hacks/cleanup_unnecessary_output.rb
176
182
  - lib/pg_ha_migrations/hacks/disable_ddl_transaction.rb
177
183
  - lib/pg_ha_migrations/railtie.rb
178
184
  - lib/pg_ha_migrations/safe_statements.rb
@@ -199,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
199
205
  - !ruby/object:Gem::Version
200
206
  version: '0'
201
207
  requirements: []
202
- rubygems_version: 3.0.3
208
+ rubygems_version: 3.0.6
203
209
  signing_key:
204
210
  specification_version: 4
205
211
  summary: Enforces DDL/migration safety in Ruby on Rails project with an emphasis on