From 0999dd6532470eb932ff559f621bd0689e70aa9b Mon Sep 17 00:00:00 2001 From: zYne Date: Mon, 13 Nov 2006 18:14:20 +0000 Subject: [PATCH] added Doctrine_Db_Exception drivers --- lib/Doctrine/Db/Firebird/Exception.php | 132 +++++++++++++++++++++++++ lib/Doctrine/Db/Mssql/Exception.php | 72 ++++++++++++++ lib/Doctrine/Db/Mysql/Exception.php | 80 +++++++++++++++ lib/Doctrine/Db/Oracle/Exception.php | 75 ++++++++++++++ lib/Doctrine/Db/Pgsql/Exception.php | 102 +++++++++++++++++++ lib/Doctrine/Db/Sqlite/Exception.php | 75 ++++++++++++++ 6 files changed, 536 insertions(+) create mode 100644 lib/Doctrine/Db/Firebird/Exception.php create mode 100644 lib/Doctrine/Db/Mssql/Exception.php create mode 100644 lib/Doctrine/Db/Mysql/Exception.php create mode 100644 lib/Doctrine/Db/Oracle/Exception.php create mode 100644 lib/Doctrine/Db/Pgsql/Exception.php create mode 100644 lib/Doctrine/Db/Sqlite/Exception.php diff --git a/lib/Doctrine/Db/Firebird/Exception.php b/lib/Doctrine/Db/Firebird/Exception.php new file mode 100644 index 000000000..c3235950c --- /dev/null +++ b/lib/Doctrine/Db/Firebird/Exception.php @@ -0,0 +1,132 @@ +. + */ +Doctrine::autoload('Doctrine_Db_Exception'); +/** + * Doctrine_Db_Firebird_Exception + * + * @package Doctrine + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + * @author Konsta Vesterinen + * @author Lorenzo Alberton (PEAR MDB2 Interbase driver) + * @author Lukas Smith (PEAR MDB2 library) + */ +class Doctrine_Db_Firebird_Exception extends Doctrine_Db_Exception { + /** + * @var array $errorCodeMap an array that is used for determining portable + * error code from a native database error code + */ + protected static $errorCodeMap = array( + -104 => Doctrine_Db::ERR_SYNTAX, + -150 => Doctrine_Db::ERR_ACCESS_VIOLATION, + -151 => Doctrine_Db::ERR_ACCESS_VIOLATION, + -155 => Doctrine_Db::ERR_NOSUCHTABLE, + -157 => Doctrine_Db::ERR_NOSUCHFIELD, + -158 => Doctrine_Db::ERR_VALUE_COUNT_ON_ROW, + -170 => Doctrine_Db::ERR_MISMATCH, + -171 => Doctrine_Db::ERR_MISMATCH, + -172 => Doctrine_Db::ERR_INVALID, + // -204 => // Covers too many errors, need to use regex on msg + -205 => Doctrine_Db::ERR_NOSUCHFIELD, + -206 => Doctrine_Db::ERR_NOSUCHFIELD, + -208 => Doctrine_Db::ERR_INVALID, + -219 => Doctrine_Db::ERR_NOSUCHTABLE, + -297 => Doctrine_Db::ERR_CONSTRAINT, + -303 => Doctrine_Db::ERR_INVALID, + -413 => Doctrine_Db::ERR_INVALID_NUMBER, + -530 => Doctrine_Db::ERR_CONSTRAINT, + -551 => Doctrine_Db::ERR_ACCESS_VIOLATION, + -552 => Doctrine_Db::ERR_ACCESS_VIOLATION, + // -607 => // Covers too many errors, need to use regex on msg + -625 => Doctrine_Db::ERR_CONSTRAINT_NOT_NULL, + -803 => Doctrine_Db::ERR_CONSTRAINT, + -804 => Doctrine_Db::ERR_VALUE_COUNT_ON_ROW, + -904 => Doctrine_Db::ERR_CONNECT_FAILED, + -922 => Doctrine_Db::ERR_NOSUCHDB, + -923 => Doctrine_Db::ERR_CONNECT_FAILED, + -924 => Doctrine_Db::ERR_CONNECT_FAILED + ); + /** + * @var array $errorRegexps an array that is used for determining portable + * error code from a native database error message + */ + protected static $errorRegexps = array( + '/generator .* is not defined/' + => Doctrine_Db::ERR_SYNTAX, // for compat. w ibase_errcode() + '/table.*(not exist|not found|unknown)/i' + => Doctrine_Db::ERR_NOSUCHTABLE, + '/table .* already exists/i' + => Doctrine_Db::ERR_ALREADY_EXISTS, + '/unsuccessful metadata update .* failed attempt to store duplicate value/i' + => Doctrine_Db::ERR_ALREADY_EXISTS, + '/unsuccessful metadata update .* not found/i' + => Doctrine_Db::ERR_NOT_FOUND, + '/validation error for column .* value "\*\*\* null/i' + => Doctrine_Db::ERR_CONSTRAINT_NOT_NULL, + '/violation of [\w ]+ constraint/i' + => Doctrine_Db::ERR_CONSTRAINT, + '/conversion error from string/i' + => Doctrine_Db::ERR_INVALID_NUMBER, + '/no permission for/i' + => Doctrine_Db::ERR_ACCESS_VIOLATION, + '/arithmetic exception, numeric overflow, or string truncation/i' + => Doctrine_Db::ERR_INVALID, + '/table unknown/i' + => Doctrine::ERR_NOSUCHTABLE, + ); + /** + * This method checks if native error code/message can be + * converted into a portable code and then adds this + * portable error code to errorInfo array and returns the modified array + * + * the portable error code is added at the end of array + * + * @param array $errorInfo error info array + * @since 1.0 + * @return array + */ + public function processErrorInfo(array $errorInfo) { + /** + // todo: are the following lines needed? + // memo for the interbase php module hackers: we need something similar + // to mysql_errno() to retrieve error codes instead of this ugly hack + if (preg_match('/^([^0-9\-]+)([0-9\-]+)\s+(.*)$/', $native_msg, $m)) { + $native_code = (int)$m[2]; + } else { + $native_code = null; + } + */ + + foreach(self::$errorRegexps as $regexp => $code) { + if (preg_match($regexp, $errorInfo[2])) { + $errorInfo[3] = $code; + break; + } + } + if(isset(self::$errorCodeMap[$errorInfo[1]])) + $errorInfo[3] = self::$errorCodeMap[$errorInfo[1]]; + + return $errorInfo; + } +} diff --git a/lib/Doctrine/Db/Mssql/Exception.php b/lib/Doctrine/Db/Mssql/Exception.php new file mode 100644 index 000000000..0d9cf012e --- /dev/null +++ b/lib/Doctrine/Db/Mssql/Exception.php @@ -0,0 +1,72 @@ +. + */ +Doctrine::autoload('Doctrine_Db_Exception'); +/** + * Doctrine_Db_Exception + * + * @package Doctrine + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @since 1.0 + * @version $Revision$ + * @category Object Relational Mapping + * @link www.phpdoctrine.com + */ +class Doctrine_Db_Mssql_Exception extends Doctrine_Db_Exception { + /** + * @var array $errorCodeMap an array that is used for determining portable + * error code from a native database error code + */ + protected static $errorCodeMap = array( + 110 => Doctrine_Db::ERR_VALUE_COUNT_ON_ROW, + 155 => Doctrine_Db::ERR_NOSUCHFIELD, + 170 => Doctrine_Db::ERR_SYNTAX, + 207 => Doctrine_Db::ERR_NOSUCHFIELD, + 208 => Doctrine_Db::ERR_NOSUCHTABLE, + 245 => Doctrine_Db::ERR_INVALID_NUMBER, + 515 => Doctrine_Db::ERR_CONSTRAINT_NOT_NULL, + 547 => Doctrine_Db::ERR_CONSTRAINT, + 1913 => Doctrine_Db::ERR_ALREADY_EXISTS, + 2627 => Doctrine_Db::ERR_CONSTRAINT, + 2714 => Doctrine_Db::ERR_ALREADY_EXISTS, + 3701 => Doctrine_Db::ERR_NOSUCHTABLE, + 8134 => Doctrine_Db::ERR_DIVZERO, + ); + /** + * This method checks if native error code/message can be + * converted into a portable code and then adds this + * portable error code to errorInfo array and returns the modified array + * + * the portable error code is added at the end of array + * + * @param array $errorInfo error info array + * @since 1.0 + * @return array + */ + public function processErrorInfo(array $errorInfo) { + $code = $errorInfo[1]; + if(isset(self::$errorCodeMap[$code])) + $errorInfo[3] = self::$errorCodeMap[$code]; + + return $errorInfo; + } +} diff --git a/lib/Doctrine/Db/Mysql/Exception.php b/lib/Doctrine/Db/Mysql/Exception.php new file mode 100644 index 000000000..4be955efa --- /dev/null +++ b/lib/Doctrine/Db/Mysql/Exception.php @@ -0,0 +1,80 @@ +. + */ +Doctrine::autoload('Doctrine_Db_Exception'); +/** + * @package Doctrine + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @version $Revision$ + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + */ +class Doctrine_Db_Exception_Mysql extends Doctrine_Db_Exception { + /** + * @var array $errorCodeMap an array that is used for determining portable + * error code from a native database error code + */ + protected static $errorCodeMap = array( + 1004 => Doctrine_Db::ERR_CANNOT_CREATE, + 1005 => Doctrine_Db::ERR_CANNOT_CREATE, + 1006 => Doctrine_Db::ERR_CANNOT_CREATE, + 1007 => Doctrine_Db::ERR_ALREADY_EXISTS, + 1008 => Doctrine_Db::ERR_CANNOT_DROP, + 1022 => Doctrine_Db::ERR_ALREADY_EXISTS, + 1044 => Doctrine_Db::ERR_ACCESS_VIOLATION, + 1046 => Doctrine_Db::ERR_NODBSELECTED, + 1048 => Doctrine_Db::ERR_CONSTRAINT, + 1049 => Doctrine_Db::ERR_NOSUCHDB, + 1050 => Doctrine_Db::ERR_ALREADY_EXISTS, + 1051 => Doctrine_Db::ERR_NOSUCHTABLE, + 1054 => Doctrine_Db::ERR_NOSUCHFIELD, + 1061 => Doctrine_Db::ERR_ALREADY_EXISTS, + 1062 => Doctrine_Db::ERR_ALREADY_EXISTS, + 1064 => Doctrine_Db::ERR_SYNTAX, + 1091 => Doctrine_Db::ERR_NOT_FOUND, + 1100 => Doctrine_Db::ERR_NOT_LOCKED, + 1136 => Doctrine_Db::ERR_VALUE_COUNT_ON_ROW, + 1142 => Doctrine_Db::ERR_ACCESS_VIOLATION, + 1146 => Doctrine_Db::ERR_NOSUCHTABLE, + 1216 => Doctrine_Db::ERR_CONSTRAINT, + 1217 => Doctrine_Db::ERR_CONSTRAINT, + ); + /** + * This method checks if native error code/message can be + * converted into a portable code and then adds this + * portable error code to errorInfo array and returns the modified array + * + * the portable error code is added at the end of array + * + * @param array $errorInfo error info array + * @since 1.0 + * @return array + */ + public function processErrorInfo(array $errorInfo) { + $code = $errorInfo[1]; + if(isset(self::$errorCodeMap[$code])) + $errorInfo[3] = self::$errorCodeMap[$code]; + + return $errorInfo; + } +} diff --git a/lib/Doctrine/Db/Oracle/Exception.php b/lib/Doctrine/Db/Oracle/Exception.php new file mode 100644 index 000000000..7c451b77e --- /dev/null +++ b/lib/Doctrine/Db/Oracle/Exception.php @@ -0,0 +1,75 @@ +. + */ +Doctrine::autoload('Doctrine_Db_Exception'); +/** + * @package Doctrine + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @version $Revision$ + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + */ +class Doctrine_Db_Oracle_Exception extends Doctrine_Db_Exception { + /** + * @var array $errorCodeMap an array that is used for determining portable + * error code from a native database error code + */ + protected static $errorCodeMap = array( + 1 => Doctrine::ERR_CONSTRAINT, + 900 => Doctrine::ERR_SYNTAX, + 904 => Doctrine::ERR_NOSUCHFIELD, + 913 => Doctrine::ERR_VALUE_COUNT_ON_ROW, + 921 => Doctrine::ERR_SYNTAX, + 923 => Doctrine::ERR_SYNTAX, + 942 => Doctrine::ERR_NOSUCHTABLE, + 955 => Doctrine::ERR_ALREADY_EXISTS, + 1400 => Doctrine::ERR_CONSTRAINT_NOT_NULL, + 1401 => Doctrine::ERR_INVALID, + 1407 => Doctrine::ERR_CONSTRAINT_NOT_NULL, + 1418 => Doctrine::ERR_NOT_FOUND, + 1476 => Doctrine::ERR_DIVZERO, + 1722 => Doctrine::ERR_INVALID_NUMBER, + 2289 => Doctrine::ERR_NOSUCHTABLE, + 2291 => Doctrine::ERR_CONSTRAINT, + 2292 => Doctrine::ERR_CONSTRAINT, + 2449 => Doctrine::ERR_CONSTRAINT, + ); + /** + * This method checks if native error code/message can be + * converted into a portable code and then adds this + * portable error code to errorInfo array and returns the modified array + * + * the portable error code is added at the end of array + * + * @param array $errorInfo error info array + * @since 1.0 + * @return array + */ + public function processErrorInfo(array $errorInfo) { + $code = $errorInfo[1]; + if(isset(self::$errorCodeMap[$code])) + $errorInfo[3] = self::$errorCodeMap[$code]; + + return $errorInfo; + } +} diff --git a/lib/Doctrine/Db/Pgsql/Exception.php b/lib/Doctrine/Db/Pgsql/Exception.php new file mode 100644 index 000000000..dbfaac2a5 --- /dev/null +++ b/lib/Doctrine/Db/Pgsql/Exception.php @@ -0,0 +1,102 @@ +. + */ +Doctrine::autoload('Doctrine_Db_Exception'); +/** + * Doctrine_Connection_Pgsql_Exception + * + * @package Doctrine + * @category Object Relational Mapping + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.phpdoctrine.com + * @author Konsta Vesterinen + * @author Paul Cooper (PEAR MDB2 Pgsql driver) + * @author Lukas Smith (PEAR MDB2 library) + * @since 1.0 + * @version $Revision$ + */ +class Doctrine_Db_Pgsql_Exception extends Doctrine_Db_Exception { + /** + * @var array $errorRegexps an array that is used for determining portable + * error code from a native database error message + */ + protected static $errorRegexps = array( + '/column .* (of relation .*)?does not exist/i' + => Doctrine::ERR_NOSUCHFIELD, + '/(relation|sequence|table).*does not exist|class .* not found/i' + => Doctrine::ERR_NOSUCHTABLE, + '/index .* does not exist/' + => Doctrine::ERR_NOT_FOUND, + '/relation .* already exists/i' + => Doctrine::ERR_ALREADY_EXISTS, + '/(divide|division) by zero$/i' + => Doctrine::ERR_DIVZERO, + '/pg_atoi: error in .*: can\'t parse /i' + => Doctrine::ERR_INVALID_NUMBER, + '/invalid input syntax for( type)? (integer|numeric)/i' + => Doctrine::ERR_INVALID_NUMBER, + '/value .* is out of range for type \w*int/i' + => Doctrine::ERR_INVALID_NUMBER, + '/integer out of range/i' + => Doctrine::ERR_INVALID_NUMBER, + '/value too long for type character/i' + => Doctrine::ERR_INVALID, + '/attribute .* not found|relation .* does not have attribute/i' + => Doctrine::ERR_NOSUCHFIELD, + '/column .* specified in USING clause does not exist in (left|right) table/i' + => Doctrine::ERR_NOSUCHFIELD, + '/parser: parse error at or near/i' + => Doctrine::ERR_SYNTAX, + '/syntax error at/' + => Doctrine::ERR_SYNTAX, + '/column reference .* is ambiguous/i' + => Doctrine::ERR_SYNTAX, + '/permission denied/' + => Doctrine::ERR_ACCESS_VIOLATION, + '/violates not-null constraint/' + => Doctrine::ERR_CONSTRAINT_NOT_NULL, + '/violates [\w ]+ constraint/' + => Doctrine::ERR_CONSTRAINT, + '/referential integrity violation/' + => Doctrine::ERR_CONSTRAINT, + '/more expressions than target columns/i' + => Doctrine::ERR_VALUE_COUNT_ON_ROW, + ); + /** + * This method checks if native error code/message can be + * converted into a portable code and then adds this + * portable error code to errorInfo array and returns the modified array + * + * the portable error code is added at the end of array + * + * @param array $errorInfo error info array + * @since 1.0 + * @return array + */ + public function processErrorInfo(array $errorInfo) { + foreach (self::$errorRegexps as $regexp => $code) { + if (preg_match($regexp, $errorInfo[2])) { + $errorInfo[3] = $code; + break; + } + } + return $errorInfo; + } +} diff --git a/lib/Doctrine/Db/Sqlite/Exception.php b/lib/Doctrine/Db/Sqlite/Exception.php new file mode 100644 index 000000000..8a4e33d9e --- /dev/null +++ b/lib/Doctrine/Db/Sqlite/Exception.php @@ -0,0 +1,75 @@ +. + */ +Doctrine::autoload('Doctrine_Db_Exception'); +/** + * Doctrine_Db_Sqlite_Exception + * + * @package Doctrine + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @author Konsta Vesterinen + * @author Lukas Smith (PEAR MDB2 library) + * @since 1.0 + * @version $Revision$ + * @category Object Relational Mapping + * @link www.phpdoctrine.com + */ +class Doctrine_Db_Sqlite_Exception extends Doctrine_Db_Exception { + /** + * @var array $errorRegexps an array that is used for determining portable + * error code from a native database error message + */ + protected static $errorRegexps = array( + '/^no such table:/' => Doctrine_Db::ERR_NOSUCHTABLE, + '/^no such index:/' => Doctrine_Db::ERR_NOT_FOUND, + '/^(table|index) .* already exists$/' => Doctrine_Db::ERR_ALREADY_EXISTS, + '/PRIMARY KEY must be unique/i' => Doctrine_Db::ERR_CONSTRAINT, + '/is not unique/' => Doctrine_Db::ERR_CONSTRAINT, + '/columns .* are not unique/i' => Doctrine_Db::ERR_CONSTRAINT, + '/uniqueness constraint failed/' => Doctrine_Db::ERR_CONSTRAINT, + '/may not be NULL/' => Doctrine_Db::ERR_CONSTRAINT_NOT_NULL, + '/^no such column:/' => Doctrine_Db::ERR_NOSUCHFIELD, + '/column not present in both tables/i' => Doctrine_Db::ERR_NOSUCHFIELD, + '/^near ".*": syntax error$/' => Doctrine_Db::ERR_SYNTAX, + '/[0-9]+ values for [0-9]+ columns/i' => Doctrine_Db::ERR_VALUE_COUNT_ON_ROW, + ); + + /** + * This method checks if native error code/message can be + * converted into a portable code and then adds this + * portable error code to errorInfo array and returns the modified array + * + * the portable error code is added at the end of array + * + * @param array $errorInfo error info array + * @since 1.0 + * @return array + */ + public function processErrorInfo(array $errorInfo) { + foreach (self::$errorRegexps as $regexp => $code) { + if (preg_match($regexp, $errorInfo[2])) { + $errorInfo[3] = $code; + break; + } + } + + return $errorInfo; + } +}