diff options
author | Wez Furlong <wez@php.net> | 2005-01-18 02:42:52 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2005-01-18 02:42:52 +0000 |
commit | 505fbb196661e1627717c9b60b861371f860ae44 (patch) | |
tree | 458aeb001920061fbed387ca83fbfa887a1e9a33 | |
parent | 5089dc049ad968ef4036ee391e1eda05fb585254 (diff) | |
download | php-git-505fbb196661e1627717c9b60b861371f860ae44.tar.gz |
nice and fluffy error handling
-rw-r--r-- | ext/pdo_dblib/db.php | 9 | ||||
-rw-r--r-- | ext/pdo_dblib/dblib_driver.c | 46 | ||||
-rw-r--r-- | ext/pdo_dblib/dblib_stmt.c | 2 | ||||
-rw-r--r-- | ext/pdo_dblib/pdo_dblib.c | 73 | ||||
-rw-r--r-- | ext/pdo_dblib/php_pdo_dblib.h | 1 | ||||
-rw-r--r-- | ext/pdo_dblib/php_pdo_dblib_int.h | 17 |
6 files changed, 144 insertions, 4 deletions
diff --git a/ext/pdo_dblib/db.php b/ext/pdo_dblib/db.php index f069c76391..f9bac04d29 100644 --- a/ext/pdo_dblib/db.php +++ b/ext/pdo_dblib/db.php @@ -5,10 +5,13 @@ dl('php_pdo.dll'); dl('php_pdo_sybase.dll'); +try { + $db = new PDO('sybase:', 'pdo', 'pdo'); +$db->setAttribute(PDO_ATTR_ERRMODE, PDO_ERRMODE_EXCEPTION); debug_zval_dump($db); -$stmt = $db->prepare('sp_helpdb'); +$stmt = $db->prepare('select 10'); debug_zval_dump($stmt); $x = $stmt->execute(); @@ -18,6 +21,10 @@ while (($r = $stmt->fetch())) { print_r($r); } +} catch (Exception $e) { + print $e; +} + $stmt = null; $db = null; echo "All done\n"; diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index aee84e0dbb..0f296dc713 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -32,6 +32,38 @@ #include "php_pdo_dblib_int.h" #include "zend_exceptions.h" +static int dblib_fetch_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC) +{ + pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; + pdo_dblib_err *einfo = &H->err; + pdo_dblib_stmt *S = NULL; + char *message; + char *msg; + + if (stmt) { + S = (pdo_dblib_stmt*)stmt->driver_data; + einfo = &S->err; + } + + if (einfo->dberr == SYBESMSG && einfo->lastmsg) { + msg = einfo->lastmsg; + } else { + msg = einfo->dberr; + } + + spprintf(&message, 0, "%s [%d] (severity %d)", + msg, einfo->dberr, einfo->severity); + + add_next_index_long(info, einfo->dberr); + add_next_index_string(info, message, 0); + add_next_index_long(info, einfo->oserr); + add_next_index_long(info, einfo->severity); + add_next_index_string(info, einfo->oserrstr, 1); + + return 1; +} + + static int dblib_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; @@ -59,6 +91,7 @@ static int dblib_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, S->H = H; stmt->driver_data = S; stmt->methods = &dblib_stmt_methods; + S->err.sqlstate = stmt->error_code; return 1; } @@ -68,6 +101,8 @@ static long dblib_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRM pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; RETCODE ret, resret; + dbsetuserdata(H->link, (BYTE*)&H->err); + if (FAIL == dbcmd(H->link, sql)) { return -1; } @@ -135,7 +170,7 @@ static struct pdo_dbh_methods dblib_methods = { NULL, NULL, NULL, /* last insert */ - NULL, /* fetch error */ + dblib_fetch_error, /* fetch error */ NULL, /* get attr */ NULL, /* check liveness */ }; @@ -157,6 +192,7 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ H = pecalloc(1, sizeof(*H), dbh->is_persistent); H->login = dblogin(); + H->err.sqlstate = dbh->error_code; if (!H->login) { goto cleanup; @@ -198,6 +234,14 @@ cleanup: dbh->methods = &dblib_methods; dbh->driver_data = H; + if (!ret) { + zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, + "SQLSTATE[%s] %s (severity %d)", + DBLIB_G(err).sqlstate, + DBLIB_G(err).dberrstr, + DBLIB_G(err).severity); + } + return ret; } diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index e552c7149e..22e0d6628d 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -73,6 +73,8 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) int i, j; int arows; unsigned int size; + + dbsetuserdata(H->link, &S->err); if (S->rows) { /* clean them up */ diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c index 0cd6a30de9..e89c30b9bf 100644 --- a/ext/pdo_dblib/pdo_dblib.c +++ b/ext/pdo_dblib/pdo_dblib.c @@ -32,6 +32,8 @@ #include "php_pdo_dblib_int.h" #include "zend_exceptions.h" +ZEND_DECLARE_MODULE_GLOBALS(dblib) + function_entry pdo_dblib_functions[] = { {NULL, NULL, NULL} }; @@ -47,7 +49,7 @@ zend_module_entry pdo_dblib_module_entry = { PHP_MINIT(pdo_dblib), PHP_MSHUTDOWN(pdo_dblib), NULL, - NULL, + PHP_RSHUTDOWN(pdo_dblib), PHP_MINFO(pdo_dblib), "0.1-dev", STANDARD_MODULE_PROPERTIES @@ -60,9 +62,38 @@ ZEND_GET_MODULE(pdo_dblib) static int error_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr) { + pdo_dblib_err *einfo; + char *state = "HY000"; TSRMLS_FETCH(); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "dblib error: %s (severity %d)", dberrstr, severity); + einfo = (pdo_dblib_err*)dbgetuserdata(dbproc); + if (!einfo) einfo = &DBLIB_G(err); + + einfo->severity = severity; + einfo->oserr = oserr; + einfo->dberr = dberr; + if (einfo->oserrstr) { + efree(einfo->oserrstr); + } + if (einfo->dberrstr) { + efree(einfo->dberrstr); + } + einfo->oserrstr = estrdup(oserrstr); + einfo->dberrstr = estrdup(dberrstr); + + switch (dberr) { + case SYBESEOF: + case SYBEFCON: state = "01002"; break; + case SYBEMEM: state = "HY001"; break; + case SYBEPWD: state = "28000"; break; + } + strcpy(einfo->sqlstate, state); + +#if 0 + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "dblib error: %d %s (severity %d)", + dberr, dberrstr, severity); +#endif return INT_CANCEL; } @@ -70,13 +101,49 @@ static int error_handler(DBPROCESS *dbproc, int severity, int dberr, static int msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, DBUSMALLINT line) { + pdo_dblib_err *einfo; TSRMLS_FETCH(); + einfo = (pdo_dblib_err*)dbgetuserdata(dbproc); + if (!einfo) einfo = &DBLIB_G(err); + + if (einfo->lastmsg) { + efree(einfo->lastmsg); + } + + einfo->lastmsg = estrdup(msgtext); + +#if 0 php_error_docref(NULL TSRMLS_CC, E_WARNING, "dblib message: %s (severity %d)", msgtext, severity); +#endif return 0; } +static int init_dblib_globals(zend_dblib_globals *g) +{ + memset(g, 0, sizeof(*g)); + g->err.sqlstate = g->sqlstate; + return SUCCESS; +} + +PHP_RSHUTDOWN_FUNCTION(pdo_dblib) +{ + if (DBLIB_G(err).oserrstr) { + efree(DBLIB_G(err).oserrstr); + DBLIB_G(err).oserrstr = NULL; + } + if (DBLIB_G(err).dberrstr) { + efree(DBLIB_G(err).dberrstr); + DBLIB_G(err).dberrstr = NULL; + } + if (DBLIB_G(err).lastmsg) { + efree(DBLIB_G(err).lastmsg); + DBLIB_G(err).lastmsg = NULL; + } + return SUCCESS; +} + PHP_MINIT_FUNCTION(pdo_dblib) { if (FAIL == dbinit()) { @@ -86,6 +153,8 @@ PHP_MINIT_FUNCTION(pdo_dblib) if (FAILURE == php_pdo_register_driver(&pdo_dblib_driver)) { return FAILURE; } + + ZEND_INIT_MODULE_GLOBALS(dblib, init_dblib_globals, NULL); /* TODO: diff --git a/ext/pdo_dblib/php_pdo_dblib.h b/ext/pdo_dblib/php_pdo_dblib.h index 5795b71153..d05ae24bc2 100644 --- a/ext/pdo_dblib/php_pdo_dblib.h +++ b/ext/pdo_dblib/php_pdo_dblib.h @@ -39,6 +39,7 @@ extern zend_module_entry pdo_dblib_module_entry; PHP_MINIT_FUNCTION(pdo_dblib); PHP_MSHUTDOWN_FUNCTION(pdo_dblib); PHP_MINFO_FUNCTION(pdo_dblib); +PHP_RSHUTDOWN_FUNCTION(pdo_dblib); #endif diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h index 481f3805f5..64e86b1fbe 100644 --- a/ext/pdo_dblib/php_pdo_dblib_int.h +++ b/ext/pdo_dblib/php_pdo_dblib_int.h @@ -87,6 +87,8 @@ typedef struct { int dberr; char *oserrstr; char *dberrstr; + char *sqlstate; + char *lastmsg; } pdo_dblib_err; typedef struct { @@ -118,7 +120,22 @@ typedef struct { int nrows; int current; + + pdo_dblib_err err; } pdo_dblib_stmt; +ZEND_BEGIN_MODULE_GLOBALS(dblib) + pdo_dblib_err err; + char sqlstate[6]; +ZEND_END_MODULE_GLOBALS(dblib) + +#ifdef ZTS +# define DBLIB_G(v) TSRMG(dblib_globals_id, zend_dblib_globals *, v) +#else +# define DBLIB_G(v) (dblib_globals.v) +#endif + +ZEND_EXTERN_MODULE_GLOBALS(dblib); + #endif |