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

Translate adapter errors that indicate a violated uniqueness constraint to ActiveRecord::RecordNotUnique exception derived from ActiveReecord::StatementInvalid.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
This commit is contained in:
Michael Schuerig 2009-04-05 01:19:29 +02:00 committed by Michael Koziarski
parent 18a97a6601
commit 53a3eaa860
6 changed files with 47 additions and 1 deletions

View file

@ -67,6 +67,10 @@ module ActiveRecord #:nodoc:
class StatementInvalid < ActiveRecordError
end
# Raised when a record cannot be inserted because it would violate a uniqueness constraint.
class RecordNotUnique < StatementInvalid
end
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
# does not match number of expected variables.
#

View file

@ -211,9 +211,14 @@ module ActiveRecord
@last_verification = 0
message = "#{e.class.name}: #{e.message}: #{sql}"
log_info(message, name, 0)
raise ActiveRecord::StatementInvalid, message
raise translate_exception(e, message)
end
def translate_exception(e, message)
# override in derived class
ActiveRecord::StatementInvalid.new(message)
end
def format_log_entry(message, dump = nil)
if ActiveRecord::Base.colorize_logging
if @@row_even

View file

@ -563,6 +563,17 @@ module ActiveRecord
where_sql
end
protected
def translate_exception(exception, message)
case exception.errno
when 1062
RecordNotUnique.new(message)
else
super
end
end
private
def connect
encoding = @config[:encoding]

View file

@ -941,6 +941,15 @@ module ActiveRecord
end
end
def translate_exception(exception, message)
case exception.message
when /duplicate key value violates unique constraint/
RecordNotUnique.new(message)
else
super
end
end
private
# The internal PostgreSQL identifier of the money data type.
MONEY_COLUMN_TYPE_OID = 790 #:nodoc:

View file

@ -431,6 +431,16 @@ module ActiveRecord
'INTEGER PRIMARY KEY NOT NULL'.freeze
end
end
def translate_exception(exception, message)
case exception.message
when /column(s)? .* (is|are) not unique/
RecordNotUnique.new(message)
else
super
end
end
end
class SQLite2Adapter < SQLiteAdapter # :nodoc:

View file

@ -130,4 +130,11 @@ class AdapterTest < ActiveRecord::TestCase
assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
end
end
def test_uniqueness_violations_are_translated_to_specific_exception
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
assert_raises(ActiveRecord::RecordNotUnique) do
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
end
end
end