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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/Appraisals +12 -0
- data/README.md +37 -0
- data/Rakefile +5 -0
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5.0.gemfile +7 -0
- data/gemfiles/rails_5.1.gemfile +7 -0
- data/gemfiles/rails_5.2.gemfile +7 -0
- data/lib/pg_ha_migrations/blocking_database_transactions.rb +32 -16
- data/lib/pg_ha_migrations/hacks/cleanup_unnecessary_output.rb +29 -0
- data/lib/pg_ha_migrations/safe_statements.rb +113 -4
- data/lib/pg_ha_migrations/unsafe_statements.rb +2 -0
- data/lib/pg_ha_migrations/version.rb +1 -1
- data/lib/pg_ha_migrations.rb +5 -0
- data/pg_ha_migrations.gemspec +3 -3
- metadata +23 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36546429641ce670fa116d251f17993538b3ab60b5014c1917103e45b1fa0f45
|
4
|
+
data.tar.gz: 969078be676bc767aa8f325328da8aeda95b6120e620c5d8556bda639c94a3f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2ee13eed929c6278cf745b6b4e4ecff210858e930f97be67d0db2ff4bd2efc65288cc2c80090343cb6cc3e2097c8e1fcf62955fddf442eced723660793706df
|
7
|
+
data.tar.gz: d1f0853d0d47774e889835716f6619097f3e56016e8997a7115e31c34e87dfc80b0871eee128161f4583247265afbfd9aeae752312dad4bb11a5dd5bf0946184
|
data/.gitignore
CHANGED
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
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
|
|
@@ -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
|
-
|
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,
|
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.#{
|
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 (
|
33
|
-
|
34
|
-
|
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 =
|
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
|
-
|
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
|
-
|
51
|
-
|
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 >=
|
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 >=
|
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
|
data/lib/pg_ha_migrations.rb
CHANGED
@@ -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)
|
data/pg_ha_migrations.gemspec
CHANGED
@@ -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
|
38
|
-
spec.add_development_dependency
|
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.
|
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:
|
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.
|
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
|