Permalink
Browse files

catches a database error and rethrow <dbi-database-error> (or <dbi-pr…

…ogramming-error>) in execution-time.
  • Loading branch information...
fukamachi committed May 23, 2012
1 parent abc335d commit 16ef300a04743abd4bc6e1c2557ff07a37390ec2
Showing with 60 additions and 17 deletions.
  1. +17 −5 src/dbd/mysql.lisp
  2. +14 −5 src/dbd/postgres.lisp
  3. +14 −4 src/dbd/sqlite3.lisp
  4. +3 −1 src/error.lisp
  5. +12 −2 src/test.lisp
View
@@ -10,7 +10,14 @@
:dbi.error
:cl-mysql)
(:shadowing-import-from :dbi.driver
- :disconnect))
+ :disconnect)
+ (:import-from :cl-mysql-system
+ :mysql-error
+ :connect-to-server
+ :mysql-error-message
+ :mysql-error-errno
+ :return-or-close
+ :owner-pool))
(in-package :dbd.mysql)
(cl-syntax:use-syntax :annot)
@@ -39,10 +46,15 @@
(call-next-method conn sql :query-class '<dbd-mysql-query>))
(defmethod execute-using-connection ((conn <dbd-mysql-connection>) (query <dbd-mysql-query>) params)
- (let ((result (query (apply (query-prepared query) params)
- :database (connection-handle conn)
- :store nil)))
- (cl-mysql-system::return-or-close (cl-mysql-system::owner-pool result) result)
+ (let ((result
+ (handler-case (query (apply (query-prepared query) params)
+ :database (connection-handle conn)
+ :store nil)
+ (mysql-error (e)
+ (error '<dbi-database-error>
+ :message (mysql-error-message e)
+ :error-code (mysql-error-errno e))))))
+ (return-or-close (owner-pool result) result)
(next-result-set result)
(setf (slot-value query '%result) result)
query))
View
@@ -8,7 +8,11 @@
(:use :cl
:dbi.driver
:dbi.error
- :cl-postgres))
+ :cl-postgres)
+ (:import-from :cl-postgres-error
+ :syntax-error-or-access-violation
+ :database-error-message
+ :database-error-code))
(in-package :dbd.postgres)
(cl-syntax:use-syntax :annot)
@@ -41,10 +45,15 @@
if (and (char= c #\?) (not escaped))
do (format s "$~D" (incf i))
else do (write-char c s))))
- (make-instance '<dbd-postgres-query>
- :connection conn
- :name name
- :prepared (prepare-query (connection-handle conn) name sql))))
+ (handler-case
+ (make-instance '<dbd-postgres-query>
+ :connection conn
+ :name name
+ :prepared (prepare-query (connection-handle conn) name sql))
+ (syntax-error-or-access-violation (e)
+ (error '<dbi-programming-error>
+ :message (database-error-message e)
+ :error-code (database-error-code e))))))
(defmethod execute-using-connection ((conn <dbd-postgres-connection>) (query <dbd-postgres-query>) params)
(exec-prepared (connection-handle conn)
View
@@ -26,9 +26,14 @@
:handle (connect database-name)))
(defmethod prepare ((conn <dbd-sqlite3-connection>) (sql string) &key)
- (make-instance '<dbi-query>
- :connection conn
- :prepared (prepare-statement (connection-handle conn) sql)))
+ (handler-case
+ (make-instance '<dbi-query>
+ :connection conn
+ :prepared (prepare-statement (connection-handle conn) sql))
+ (sqlite-error (e)
+ (error '<dbi-database-error>
+ :message (sqlite-error-message e)
+ :error-code (sqlite-error-code e)))))
(defmethod execute-using-connection ((conn <dbd-sqlite3-connection>) (query <dbi-query>) params)
(reset-statement (query-prepared query))
@@ -39,7 +44,12 @@
query)
(defmethod do-sql ((conn <dbd-sqlite3-connection>) (sql string) &rest params)
- (apply #'execute-non-query (connection-handle conn) sql params))
+ (handler-case
+ (apply #'execute-non-query (connection-handle conn) sql params)
+ (sqlite-error (e)
+ (error '<dbi-database-error>
+ :message (sqlite-error-message e)
+ :error-code (sqlite-error-code e)))))
(defmethod fetch-using-connection ((conn <dbd-sqlite3-connection>) (query <dbi-query>))
@ignore conn
View
@@ -35,7 +35,9 @@ database itself."))
(slot-value condition 'method-name)))))
@export
-(define-condition <dbi-database-error> (<dbi-error>) ()
+(define-condition <dbi-database-error> (<dbi-error>)
+ ((message :initarg :message)
+ (error-code :initarg :error-code))
(:documentation "Exception for errors related to the database."))
@export
View
@@ -14,13 +14,14 @@
(cl-syntax:use-syntax :annot)
+(plan 6)
+
(defparameter *db* nil)
@export
(defun run-driver-tests (driver-name &rest params)
(let ((*db* (apply #'connect driver-name params)))
- (plan 18)
- (run-test-all)))
+ (run-test-package :dbi.test)))
(deftest |connect|
(is-type *db* '<dbi-connection>))
@@ -69,3 +70,12 @@
'(:|id| 3 :|name| "meymao")))
(dbi.error:<dbi-notsupported-error> (condition)
(skip 1 "Not supported"))))
+
+(deftest |statement error|
+ (is-type (handler-case (do-sql *db* "INSERT")
+ (error (e) e))
+ '<dbi-database-error>)
+ (is-type (handler-case (execute (prepare *db* "SELECT SELECT SELECT"))
+ (error (e) e))
+ '<dbi-database-error>)
+ (do-sql *db* "INSERT INTO person (id, name) VALUES (4, 'mizuna')"))

0 comments on commit 16ef300

Please sign in to comment.