1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

pg, disable_referential_integrity only catches AR errors.

This change was prompted by 598b841.
This commit is contained in:
Yves Senn 2015-03-11 14:34:53 +01:00
parent 598b841882
commit 0c7c6286f6
2 changed files with 25 additions and 3 deletions

View file

@ -14,7 +14,7 @@ module ActiveRecord
transaction(requires_new: true) do transaction(requires_new: true) do
execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";")) execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
end end
rescue => e rescue ActiveRecord::ActiveRecordError => e
original_exception = e original_exception = e
end end
@ -37,7 +37,7 @@ Rails needs superuser privileges to disable referential integrity.
transaction(requires_new: true) do transaction(requires_new: true) do
execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";")) execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
end end
rescue rescue ActiveRecord::ActiveRecordError
end end
else else
yield yield

View file

@ -6,9 +6,13 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::TestCase
include ConnectionHelper include ConnectionHelper
IS_REFERENTIAL_INTEGRITY_SQL = lambda do |sql|
sql.match(/DISABLE TRIGGER ALL/) || sql.match(/ENABLE TRIGGER ALL/)
end
module MissingSuperuserPrivileges module MissingSuperuserPrivileges
def execute(sql) def execute(sql)
if sql.match(/DISABLE TRIGGER ALL/) || sql.match(/ENABLE TRIGGER ALL/) if IS_REFERENTIAL_INTEGRITY_SQL.call(sql)
super "BROKEN;" rescue nil # put transaction in broken state super "BROKEN;" rescue nil # put transaction in broken state
raise ActiveRecord::StatementInvalid, 'PG::InsufficientPrivilege' raise ActiveRecord::StatementInvalid, 'PG::InsufficientPrivilege'
else else
@ -17,6 +21,16 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::TestCase
end end
end end
module ProgrammerMistake
def execute(sql)
if IS_REFERENTIAL_INTEGRITY_SQL.call(sql)
raise ArgumentError, 'something is not right.'
else
super
end
end
end
def setup def setup
@connection = ActiveRecord::Base.connection @connection = ActiveRecord::Base.connection
end end
@ -81,6 +95,14 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::TestCase
end end
end end
def test_only_catch_active_record_errors_others_bubble_up
@connection.extend ProgrammerMistake
assert_raises ArgumentError do
@connection.disable_referential_integrity {}
end
end
private private
def assert_transaction_is_not_broken def assert_transaction_is_not_broken