pg_ha_migrations 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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