activerecord-pg-extensions 0.2.1 → 0.4.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: 5c618a82f7b01b308540312e68b6764d975cb6e9594d619996a5ce7502a0b72c
4
- data.tar.gz: d5b9179b9b7d2761c360092e1ff9e1c8ce27f6f49c39cb7e0e9a4f1b0d7ed97f
3
+ metadata.gz: 3494201ce01b5c6d5104ae9ddb7f993310223ecc94bd902b2484ce6b6a4e525b
4
+ data.tar.gz: acd5b4c842cbfc275b2a86f009c048e7916709803f3d72c9ed40f42095c47a7d
5
5
  SHA512:
6
- metadata.gz: edf57be20052135e65634cb992948ce612a4a5d107d6fc5e8e3de50a420cc7de8afe61a4311981a2e4684060f25ee9ceb97a6997ee22cb80c09ea6c94b2dda24
7
- data.tar.gz: ad6a7c3da37ed59d2a110d25217e2e7dba90fec35b448f3446d91a43874c86c32eb7672f783acb0e69561d9353b950df75e78d683800b594c1d1a0193f16a9c8
6
+ metadata.gz: 91625c727722fb91aa1860960a3f9c5ba7ba4dcab0a0cf459e6b8301a7fa734ff91882f5ae31ac4cb492218eaf17205ed97e54236cf8760d55b6c33b4cd3f7dc
7
+ data.tar.gz: fbe3e4a073f7f646438b07f1226e5c654a744c3efb421ea38b9c7b7adc5cf9e173fbab479780f765cc41f3c9144294d1ac16fe7f140e68bcdf44128a0bcafd68
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2021-09-29
4
+
5
+ - Deprecate with_statement_timeout
6
+ - Add statement_timeout, lock_timeout, and idle_in_transaction_session_timeout
7
+ ## [0.2.3] - 2021-06-23
8
+
9
+ - Fix extension_available?
10
+
11
+ ## [0.2.2] - 2021-06-22
12
+
13
+ - Fix bug in Ruby 2.6 calling format wrong.
14
+
3
15
  ## [0.2.1] - 2021-06-22
4
16
 
5
17
  - Ensure numeric is in the PG type map for Rails 6.0. So that lsn_diff will
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ # @deprecated just use QueryCanceled
5
+ QueryTimeout = QueryCanceled
6
+ end
@@ -6,20 +6,36 @@ module ActiveRecord
6
6
  # to executing, in order to reduce the amount of time the actual DDL takes to
7
7
  # execute (and thus how long it needs the lock)
8
8
  module PessimisticMigrations
9
- # does a query first to warm the db cache, to make the actual constraint adding fast
9
+ # adds a temporary check constraint to reduce locking when changing to NOT NULL, and we're not in a transaction
10
10
  def change_column_null(table, column, nullness, default = nil)
11
- # no point in pre-warming the cache to avoid locking if we're already in a transaction
11
+ # no point in doing extra work to avoid locking if we're already in a transaction
12
12
  return super if nullness != false || open_transactions.positive?
13
+ return if columns(table).find { |c| c.name == column.to_s }&.null == false
14
+
15
+ temp_constraint_name = "chk_rails_#{table}_#{column}_not_null"
16
+ scope = quoted_scope(temp_constraint_name)
17
+ # check for temp constraint
18
+ valid = select_value(<<~SQL, "SCHEMA")
19
+ SELECT convalidated FROM pg_constraint INNER JOIN pg_namespace ON pg_namespace.oid=connamespace WHERE conname=#{scope[:name]} AND nspname=#{scope[:schema]}
20
+ SQL
21
+ if valid.nil?
22
+ add_check_constraint(table,
23
+ "#{quote_column_name(column)} IS NOT NULL",
24
+ name: temp_constraint_name,
25
+ validate: false)
26
+ end
27
+ begin
28
+ validate_constraint(table, temp_constraint_name)
29
+ rescue ActiveRecord::StatementInvalid => e
30
+ raise ActiveRecord::NotNullViolation.new(sql: e.sql, binds: e.binds) if e.cause.is_a?(PG::CheckViolation)
31
+
32
+ raise
33
+ end
13
34
 
14
35
  transaction do
15
- # make sure the query ignores indexes, because the actual ALTER TABLE will also ignore
16
- # indexes
17
- execute("SET LOCAL enable_indexscan=off")
18
- execute("SET LOCAL enable_bitmapscan=off")
19
- execute("SELECT COUNT(*) FROM #{quote_table_name(table)} WHERE #{quote_column_name(column)} IS NULL")
20
- raise ActiveRecord::Rollback
36
+ super
37
+ remove_check_constraint(table, name: temp_constraint_name)
21
38
  end
22
- super
23
39
  end
24
40
 
25
41
  # several improvements:
@@ -47,6 +47,7 @@ module ActiveRecord
47
47
  sql << " VERSION #{quote(version)}" if version
48
48
  sql << " CASCADE" if cascade
49
49
  execute(sql)
50
+ reload_type_map
50
51
  @extensions&.delete(extension.to_s)
51
52
  end
52
53
 
@@ -61,6 +62,7 @@ module ActiveRecord
61
62
  sql << " TO #{quote(version)}" if version && version != true
62
63
  sql << " SET SCHEMA #{schema}" if schema
63
64
  execute(sql)
65
+ reload_type_map
64
66
  @extensions&.delete(extension.to_s)
65
67
  end
66
68
 
@@ -73,13 +75,14 @@ module ActiveRecord
73
75
  sql << extensions.join(", ")
74
76
  sql << " CASCADE" if cascade
75
77
  execute(sql)
78
+ reload_type_map
76
79
  @extensions&.except!(*extensions.map(&:to_s))
77
80
  end
78
81
 
79
82
  # check if a particular extension can be installed
80
83
  def extension_available?(extension, version = nil)
81
84
  sql = +"SELECT 1 FROM "
82
- sql << version ? "pg_available_extensions" : "pg_available_extension_versions"
85
+ sql << (version ? "pg_available_extension_versions" : "pg_available_extensions")
83
86
  sql << " WHERE name=#{quote(extension)}"
84
87
  sql << " AND version=#{quote(version)}" if version
85
88
  select_value(sql).to_i == 1
@@ -233,6 +236,56 @@ module ActiveRecord
233
236
  select_value("SELECT pg_is_in_recovery()")
234
237
  end
235
238
 
239
+ def set(configuration_parameter, value, local: false)
240
+ value = value.nil? ? "DEFAULT" : quote(value)
241
+ execute("SET#{' LOCAL' if local} #{configuration_parameter} TO #{value}")
242
+ end
243
+
244
+ def reset(configuration_parameter)
245
+ execute("RESET #{configuration_parameter}")
246
+ end
247
+
248
+ TIMEOUTS = %i[lock_timeout statement_timeout idle_in_transaction_session_timeout].freeze
249
+
250
+ TIMEOUTS.each do |kind|
251
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
252
+ def #{kind}
253
+ current_transaction.#{kind}
254
+ end
255
+
256
+ def #{kind}=(timeout)
257
+ raise ArgumentError, "Timeouts can only be set inside of a transaction" unless current_transaction.open?
258
+
259
+ current_transaction.send(:#{kind}=, timeout)
260
+ end
261
+ RUBY
262
+ end
263
+
264
+ # @deprecated: manage the transaction yourself and set statement_timeout directly
265
+ #
266
+ # otherwise, if you're already in a transaction, or you nest with_statement_timeout,
267
+ # the value will unexpectedly "stick" even after the block returns
268
+ def with_statement_timeout(timeout)
269
+ timeout = 30 if timeout.nil? || timeout == true
270
+
271
+ transaction do
272
+ self.statement_timeout = timeout
273
+ yield
274
+ end
275
+ end
276
+
277
+ unless ::Rails.version >= "6.1"
278
+ def add_check_constraint(table_name, expression, name:, validate: true)
279
+ sql = +"ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{quote_column_name(name)} CHECK (#{expression})" # rubocop:disable Layout/LineLength
280
+ sql << " NOT VALID" unless validate
281
+ execute(sql)
282
+ end
283
+
284
+ def remove_check_constraint(table_name, name:)
285
+ execute("ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_column_name(name)}")
286
+ end
287
+ end
288
+
236
289
  private
237
290
 
238
291
  if ::Rails.version < "6.1"
@@ -259,7 +312,7 @@ module ActiveRecord
259
312
  end
260
313
 
261
314
  known_coder_types = coders_by_name.keys.map { |n| quote(n) }
262
- query = <<~SQL.format(known_coder_types.join(", "))
315
+ query = format(<<~SQL, *known_coder_types.join(", "))
263
316
  SELECT t.oid, t.typname
264
317
  FROM pg_type as t
265
318
  WHERE t.typname IN (%s)
@@ -8,9 +8,13 @@ module ActiveRecord
8
8
  class Railtie < Rails::Railtie
9
9
  initializer "pg_extensions.extend_ar", after: "active_record.initialize_database" do
10
10
  ActiveSupport.on_load(:active_record) do
11
+ require "active_record/pg_extensions/errors"
11
12
  require "active_record/pg_extensions/postgresql_adapter"
13
+ require "active_record/pg_extensions/transaction"
12
14
 
13
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(PostgreSQLAdapter)
15
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(PostgreSQLAdapter)
16
+ ::ActiveRecord::ConnectionAdapters::NullTransaction.prepend(NullTransaction)
17
+ ::ActiveRecord::ConnectionAdapters::Transaction.prepend(Transaction)
14
18
  # if they've already require 'all', then inject now
15
19
  defined?(All) && All.inject
16
20
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module PGExtensions
5
+ # Contains general additions to Transaction
6
+ module Transaction
7
+ PostgreSQLAdapter::TIMEOUTS.each do |kind|
8
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
9
+ def #{kind}(local: false)
10
+ return @#{kind} if local
11
+ @#{kind} || parent_transaction.#{kind}
12
+ end
13
+
14
+ private def #{kind}=(timeout)
15
+ return if @#{kind} == timeout
16
+
17
+ @#{kind} = timeout
18
+ return unless materialized?
19
+ connection.set(#{kind.inspect}, "\#{timeout}s", local: true)
20
+ end
21
+ RUBY
22
+ end
23
+
24
+ def materialize!
25
+ PostgreSQLAdapter::TIMEOUTS.each do |kind|
26
+ next if (timeout = send(kind, local: true)).nil?
27
+
28
+ connection.set(kind, "#{timeout}s", local: true)
29
+ end
30
+ super
31
+ end
32
+ end
33
+
34
+ # Contains general additions to NullTransaction
35
+ module NullTransaction
36
+ PostgreSQLAdapter::TIMEOUTS.each do |kind|
37
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
38
+ def #{kind}
39
+ nil
40
+ end
41
+ RUBY
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module PGExtensions
5
- VERSION = "0.2.1"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
@@ -6,32 +6,61 @@ describe ActiveRecord::PGExtensions::PessimisticMigrations do
6
6
  end
7
7
 
8
8
  describe "#change_column_null" do
9
+ # Rails 6.1 doesn't quote the constraint name when adding a check constraint??
10
+ def quote_constraint_name(name)
11
+ Rails.version >= "6.1" ? name : connection.quote_column_name(name)
12
+ end
13
+
9
14
  it "does nothing extra when changing a column to nullable" do
10
15
  connection.change_column_null(:table, :column, true)
11
16
  expect(connection.executed_statements).to eq ['ALTER TABLE "table" ALTER COLUMN "column" DROP NOT NULL']
12
17
  end
13
18
 
14
- it "pre-warms the cache" do
19
+ it "does nothing if we're in a transaction" do
20
+ connection.transaction do
21
+ connection.change_column_null(:table, :column, true)
22
+ end
23
+ expect(connection.executed_statements).to eq ["BEGIN",
24
+ 'ALTER TABLE "table" ALTER COLUMN "column" DROP NOT NULL',
25
+ "COMMIT"]
26
+ end
27
+
28
+ it "skips entirely if the column is already NOT NULL" do
29
+ expect(connection).to receive(:columns).with(:table).and_return([double(name: "column", null: false)])
15
30
  connection.change_column_null(:table, :column, false)
16
- expect(connection.executed_statements).to eq(
17
- ["BEGIN",
18
- "SET LOCAL enable_indexscan=off",
19
- "SET LOCAL enable_bitmapscan=off",
20
- 'SELECT COUNT(*) FROM "table" WHERE "column" IS NULL',
21
- "ROLLBACK",
22
- 'ALTER TABLE "table" ALTER COLUMN "column" SET NOT NULL']
23
- )
31
+ expect(connection.executed_statements).to eq([])
24
32
  end
25
33
 
26
- it "does nothing extra if a transaction is already active" do
27
- connection.transaction do
28
- connection.change_column_null(:table, :column, false)
29
- end
30
- expect(connection.executed_statements).to eq(
31
- ["BEGIN",
32
- 'ALTER TABLE "table" ALTER COLUMN "column" SET NOT NULL',
33
- "COMMIT"]
34
- )
34
+ it "adds and removes a check constraint" do
35
+ expect(connection).to receive(:columns).and_return([])
36
+ allow(connection).to receive(:check_constraint_for!).and_return(double(name: "chk_rails_table_column_not_null"))
37
+ connection.change_column_null(:table, :column, false)
38
+
39
+ expect(connection.executed_statements).to eq [
40
+ "SELECT convalidated FROM pg_constraint INNER JOIN pg_namespace ON pg_namespace.oid=connamespace WHERE conname='chk_rails_table_column_not_null' AND nspname=ANY (current_schemas(false))\n", # rubocop:disable Layout/LineLength
41
+ %{ALTER TABLE "table" ADD CONSTRAINT #{quote_constraint_name('chk_rails_table_column_not_null')} CHECK ("column" IS NOT NULL) NOT VALID}, # rubocop:disable Layout/LineLength
42
+ 'ALTER TABLE "table" VALIDATE CONSTRAINT "chk_rails_table_column_not_null"',
43
+ "BEGIN",
44
+ 'ALTER TABLE "table" ALTER COLUMN "column" SET NOT NULL',
45
+ 'ALTER TABLE "table" DROP CONSTRAINT "chk_rails_table_column_not_null"',
46
+ "COMMIT"
47
+ ]
48
+ end
49
+
50
+ it "verifies an existing check constraint" do
51
+ expect(connection).to receive(:columns).and_return([])
52
+ allow(connection).to receive(:check_constraint_for!).and_return(double(name: "chk_rails_table_column_not_null"))
53
+ expect(connection).to receive(:select_value).and_return(false)
54
+ connection.change_column_null(:table, :column, false)
55
+
56
+ expect(connection.executed_statements).to eq [
57
+ # stubbed out <check constraint valid>
58
+ 'ALTER TABLE "table" VALIDATE CONSTRAINT "chk_rails_table_column_not_null"',
59
+ "BEGIN",
60
+ 'ALTER TABLE "table" ALTER COLUMN "column" SET NOT NULL',
61
+ 'ALTER TABLE "table" DROP CONSTRAINT "chk_rails_table_column_not_null"',
62
+ "COMMIT"
63
+ ]
35
64
  end
36
65
  end
37
66
 
@@ -92,8 +121,8 @@ describe ActiveRecord::PGExtensions::PessimisticMigrations do
92
121
  expect(connection).to receive(:remove_index).with(:users, name: "index_users_on_name", algorithm: :concurrently)
93
122
 
94
123
  connection.add_index :users, :name, algorithm: :concurrently
95
- expect(connection.executed_statements).to eq(
96
- ['CREATE INDEX CONCURRENTLY "index_users_on_name" ON "users" ("name")']
124
+ expect(connection.executed_statements).to match(
125
+ [match(/\ACREATE +INDEX CONCURRENTLY "index_users_on_name" ON "users" +\("name"\)\z/)]
97
126
  )
98
127
  end
99
128
 
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe ActiveRecord::ConnectionAdapters::PostgreSQLAdapter do
4
+ before do
5
+ allow(connection).to receive(:reload_type_map)
6
+ end
7
+
4
8
  describe "#set_constraints" do
5
9
  around do |example|
6
10
  connection.dont_execute(&example)
@@ -131,6 +135,20 @@ describe ActiveRecord::ConnectionAdapters::PostgreSQLAdapter do
131
135
  it "does not allow dropping no extensions" do
132
136
  expect { connection.drop_extension }.to raise_error(ArgumentError)
133
137
  end
138
+
139
+ describe "#extension_available?" do
140
+ it "works with no version constraint" do
141
+ connection.extension_available?(:postgis)
142
+ expect(connection.executed_statements).to eq ["SELECT 1 FROM pg_available_extensions WHERE name='postgis'"]
143
+ end
144
+
145
+ it "works with a version constraint" do
146
+ connection.extension_available?(:postgis, "2.0")
147
+ expect(connection.executed_statements).to eq(
148
+ ["SELECT 1 FROM pg_available_extension_versions WHERE name='postgis' AND version='2.0'"]
149
+ )
150
+ end
151
+ end
134
152
  end
135
153
  end
136
154
 
@@ -245,9 +263,195 @@ describe ActiveRecord::ConnectionAdapters::PostgreSQLAdapter do
245
263
  end
246
264
 
247
265
  describe "#select_value" do
248
- it "has casts numeric types" do
266
+ it "casts numeric types" do
249
267
  expect(connection.select_value("SELECT factorial(2)")).to eq 2
250
268
  end
251
269
  end
252
270
  end
271
+
272
+ describe "#with_statement_timeout" do
273
+ around do |example|
274
+ # these specs were written before we supported deferring setting timeouts
275
+ # until the transaction materializes
276
+ connection.disable_lazy_transactions!
277
+ example.call
278
+ connection.enable_lazy_transactions!
279
+ end
280
+
281
+ it "stops long-running queries" do
282
+ expect do
283
+ connection.with_statement_timeout(0.01) do
284
+ connection.execute("SELECT pg_sleep(3)")
285
+ end
286
+ end.to raise_error(ActiveRecord::QueryCanceled)
287
+ end
288
+
289
+ it "re-raises other errors" do
290
+ expect do
291
+ connection.with_statement_timeout(1) do
292
+ connection.execute("bad sql")
293
+ end
294
+ end.to(raise_error { |e| expect(e.cause).to be_a(PG::SyntaxError) })
295
+ end
296
+
297
+ context "without executing" do
298
+ around do |example|
299
+ connection.dont_execute(&example)
300
+ end
301
+
302
+ it "converts integer to ms" do
303
+ connection.with_statement_timeout(30) { nil }
304
+ expect(connection.executed_statements).to eq(
305
+ [
306
+ "BEGIN",
307
+ "SET LOCAL statement_timeout TO '30s'",
308
+ "COMMIT"
309
+ ]
310
+ )
311
+ end
312
+
313
+ it "converts float to ms" do
314
+ connection.with_statement_timeout(5.5) { nil }
315
+ expect(connection.executed_statements).to eq(
316
+ [
317
+ "BEGIN",
318
+ "SET LOCAL statement_timeout TO '5.5s'",
319
+ "COMMIT"
320
+ ]
321
+ )
322
+ end
323
+
324
+ it "converts ActiveSupport::Duration to ms" do
325
+ connection.with_statement_timeout(5.seconds) { nil }
326
+ expect(connection.executed_statements).to eq(
327
+ [
328
+ "BEGIN",
329
+ "SET LOCAL statement_timeout TO '5s'",
330
+ "COMMIT"
331
+ ]
332
+ )
333
+ end
334
+
335
+ it "allows true" do
336
+ connection.with_statement_timeout(true) { nil }
337
+ expect(connection.executed_statements).to eq(
338
+ [
339
+ "BEGIN",
340
+ "SET LOCAL statement_timeout TO '30s'",
341
+ "COMMIT"
342
+ ]
343
+ )
344
+ end
345
+ end
346
+ end
347
+
348
+ describe "#statement_timeout=" do
349
+ around do |example|
350
+ connection.dont_execute(&example)
351
+ end
352
+
353
+ it "raises if a transaction isn't active" do
354
+ expect { connection.statement_timeout = 30 }.to raise_error(ArgumentError)
355
+ end
356
+
357
+ it "does nothing if the transaction never materializes" do
358
+ connection.transaction do
359
+ connection.statement_timeout = 30
360
+ expect(connection.statement_timeout).to eq 30
361
+ end
362
+ expect(connection.statement_timeout).to be_nil
363
+
364
+ expect(connection.executed_statements).to be_empty
365
+ end
366
+
367
+ it "sets the timeout if the transaction is materialized" do
368
+ connection.transaction do
369
+ connection.select_value("SELECT 1")
370
+ connection.statement_timeout = 30
371
+ expect(connection.statement_timeout).to eq 30
372
+ end
373
+ expect(connection.statement_timeout).to be_nil
374
+
375
+ expect(connection.executed_statements).to eq(
376
+ ["BEGIN",
377
+ "SELECT 1",
378
+ "SET LOCAL statement_timeout TO '30s'",
379
+ "COMMIT"]
380
+ )
381
+ end
382
+
383
+ it "sets the timeout if the transaction materializes" do
384
+ connection.transaction do
385
+ connection.statement_timeout = 30
386
+ connection.select_value("SELECT 1")
387
+ expect(connection.statement_timeout).to eq 30
388
+ end
389
+ expect(connection.statement_timeout).to be_nil
390
+
391
+ expect(connection.executed_statements).to eq(
392
+ ["BEGIN",
393
+ "SET LOCAL statement_timeout TO '30s'",
394
+ "SELECT 1",
395
+ "COMMIT"]
396
+ )
397
+ end
398
+
399
+ it "works with nested transactions" do
400
+ connection.transaction do
401
+ connection.statement_timeout = 30
402
+ connection.transaction(requires_new: true) do
403
+ connection.statement_timeout = 15
404
+ connection.select_value("SELECT 1")
405
+ expect(connection.statement_timeout).to eq 15
406
+ end
407
+ expect(connection.statement_timeout).to eq 30
408
+ end
409
+ expect(connection.statement_timeout).to be_nil
410
+
411
+ expect(connection.executed_statements).to eq(
412
+ ["BEGIN",
413
+ "SET LOCAL statement_timeout TO '30s'",
414
+ "SAVEPOINT active_record_1",
415
+ "SET LOCAL statement_timeout TO '15s'",
416
+ "SELECT 1",
417
+ "RELEASE SAVEPOINT active_record_1",
418
+ "COMMIT"]
419
+ )
420
+ end
421
+ end
422
+
423
+ unless Rails.version >= "6.1"
424
+ describe "#add_check_constraint" do
425
+ around do |example|
426
+ connection.dont_execute(&example)
427
+ end
428
+
429
+ it "works" do
430
+ connection.add_check_constraint(:table, "column IS NOT NULL", name: :my_constraint)
431
+ expect(connection.executed_statements).to eq(
432
+ ['ALTER TABLE "table" ADD CONSTRAINT "my_constraint" CHECK (column IS NOT NULL)']
433
+ )
434
+ end
435
+
436
+ it "defers validation" do
437
+ connection.add_check_constraint(:table, "column IS NOT NULL", name: :my_constraint, validate: false)
438
+ expect(connection.executed_statements).to eq(
439
+ ['ALTER TABLE "table" ADD CONSTRAINT "my_constraint" CHECK (column IS NOT NULL) NOT VALID']
440
+ )
441
+ end
442
+ end
443
+
444
+ describe "#remove_check_constraint" do
445
+ around do |example|
446
+ connection.dont_execute(&example)
447
+ end
448
+
449
+ it "works" do
450
+ connection.remove_check_constraint(:table, name: :my_constraint)
451
+ expect(connection.executed_statements).to eq(
452
+ ['ALTER TABLE "table" DROP CONSTRAINT "my_constraint"']
453
+ )
454
+ end
455
+ end
456
+ end
253
457
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-pg-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-22 00:00:00.000000000 Z
11
+ date: 2021-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -50,6 +50,20 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '6.2'
53
+ - !ruby/object:Gem::Dependency
54
+ name: appraisal
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.4'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '2.4'
53
67
  - !ruby/object:Gem::Dependency
54
68
  name: byebug
55
69
  requirement: !ruby/object:Gem::Requirement
@@ -161,10 +175,12 @@ files:
161
175
  - config/database.yml
162
176
  - lib/active_record/pg_extensions.rb
163
177
  - lib/active_record/pg_extensions/all.rb
178
+ - lib/active_record/pg_extensions/errors.rb
164
179
  - lib/active_record/pg_extensions/extension.rb
165
180
  - lib/active_record/pg_extensions/pessimistic_migrations.rb
166
181
  - lib/active_record/pg_extensions/postgresql_adapter.rb
167
182
  - lib/active_record/pg_extensions/railtie.rb
183
+ - lib/active_record/pg_extensions/transaction.rb
168
184
  - lib/active_record/pg_extensions/version.rb
169
185
  - lib/activerecord-pg-extensions.rb
170
186
  - spec/pessimistic_migrations_spec.rb
@@ -190,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
206
  - !ruby/object:Gem::Version
191
207
  version: '0'
192
208
  requirements: []
193
- rubygems_version: 3.2.15
209
+ rubygems_version: 3.2.24
194
210
  signing_key:
195
211
  specification_version: 4
196
212
  summary: Several extensions to ActiveRecord's PostgreSQLAdapter.