From 38eb52b8a7db2a88c4baaeeaf68ef09f64a7cd49 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Thu, 20 May 2004 17:43:56 +0000 Subject: [PATCH] Make doer() work. Make error reporting system work. --- ext/pdo_pgsql/pgsql_driver.c | 77 ++++++++++++++++++++++++++----- ext/pdo_pgsql/pgsql_statement.c | 5 +- ext/pdo_pgsql/php_pdo_pgsql_int.h | 16 +++++-- 3 files changed, 78 insertions(+), 20 deletions(-) diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index b80935c199..67db6fd64e 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -30,16 +30,51 @@ #include "php_pdo_pgsql.h" #include "php_pdo_pgsql_int.h" -int _pdo_pgsql_error(char *what, char *errmsg, const char *file, int line TSRMLS_DC) /* {{{ */ +int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *file, int line TSRMLS_DC) /* {{{ */ { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "(%s:%d) %s", file, line, errmsg); - return 1; + pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; + enum pdo_error_type *pdo_err = stmt ? &stmt->error_code : &dbh->error_code; + pdo_pgsql_error_info *einfo = &H->einfo; + char *errmsg = PQerrorMessage(H->server); + + einfo->errcode = errcode; + einfo->file = file; + einfo->line = line; + + if (einfo->errmsg) { + efree(einfo->errmsg); + einfo->errmsg = NULL; + } + + switch (errcode) { + case PGRES_EMPTY_QUERY: + *pdo_err = PDO_ERR_SYNTAX; + break; + + default: + *pdo_err = PDO_ERR_CANT_MAP; + break; + } + + if (errmsg) { + einfo->errmsg = estrdup(errmsg); + } + + return errcode; } /* }}} */ -int pgsql_handle_error(pdo_dbh_t *dbh, pdo_pgsql_db_handle *H, int errcode) /* {{{ */ +static int pdo_pgsql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info TSRMLS_DC) /* {{{ */ { - return 0; + pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; + pdo_pgsql_error_info *einfo = &H->einfo; + + if (einfo->errcode) { + add_next_index_long(info, einfo->errcode); + add_next_index_string(info, einfo->errmsg, 1); + } + + return 1; } /* }}} */ @@ -67,11 +102,24 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, return 1; } -static int pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC) +static long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC) { pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; + PGresult *res; + + if (!(res = PQexec(H->server, sql))) { + /* fatal error */ + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR); + return 0; + } else { + ExecStatusType qs = PQresultStatus(res); + if (qs != PGRES_COMMAND_OK && qs != PGRES_TUPLES_OK) { + pdo_pgsql_error(dbh, qs); + return 0; + } + } - return 0; + return 1; } static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC) @@ -79,7 +127,7 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; *quoted = emalloc(2*unquotedlen + 3); (*quoted)[0] = '"'; - *quotedlen = PQescapeString(*quoted + 1, unquoted, unquotedlen); + *quotedlen = PQescapeString(*quoted + 1, unquoted, unquotedlen); (*quoted)[*quotedlen + 1] = '"'; (*quoted)[*quotedlen + 2] = '\0'; *quotedlen += 2; @@ -91,7 +139,13 @@ static struct pdo_dbh_methods pgsql_methods = { pgsql_handle_closer, pgsql_handle_preparer, pgsql_handle_doer, - pgsql_handle_quoter + pgsql_handle_quoter, + NULL, + NULL, + NULL, + NULL, + NULL, + pdo_pgsql_fetch_error_func }; static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */ @@ -102,7 +156,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ struct pdo_data_src_parser vars[] = { { "host", "", 0 }, { "port", "", 0 }, - { "dbname", "", 0 }, + { "dbname", "", 0 }, }; php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 3); @@ -126,8 +180,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ ); if (PQstatus(H->server) != CONNECTION_OK) { - H->last_err = PQerrorMessage(H->server); - pdo_pgsql_error("pdo_pgsql_handle_factory", H->last_err); + pdo_pgsql_error(dbh, PGRES_FATAL_ERROR); goto cleanup; } diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index ad3780749a..4e2e2b702c 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -68,8 +68,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) status = PQresultStatus(S->result); if (status != PGRES_COMMAND_OK && status != PGRES_TUPLES_OK) { - H->last_err = PQerrorMessage(H->server); - pdo_pgsql_error("pgsql_stmt_execute", H->last_err); + pdo_pgsql_error_stmt(stmt, status); return 0; } @@ -126,7 +125,7 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned /* We have already increased count by 1 in pgsql_stmt_fetch() */ *ptr = PQgetvalue(S->result, S->current_row - 1, colno); - *len = strlen(*ptr); + *len = PQgetlength(S->result, S->current_row - 1, colno); return 1; } diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index 91a4d3451c..7d0be93586 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -25,12 +25,19 @@ #include +typedef struct { + const char *file; + int line; + unsigned int errcode; + char *errmsg; +} pdo_pgsql_error_info; + /* stuff we use in a pgsql database handle */ typedef struct { PGconn *server; - char *last_err; unsigned attached:1; unsigned _reserved:31; + pdo_pgsql_error_info einfo; } pdo_pgsql_db_handle; typedef struct { @@ -41,7 +48,6 @@ typedef struct { pdo_pgsql_db_handle *H; PGresult *result; int current_row; - char *last_err; pdo_pgsql_column *cols; } pdo_pgsql_stmt; @@ -54,9 +60,9 @@ typedef struct { extern pdo_driver_t pdo_pgsql_driver; -extern int _pdo_pgsql_error(char *what, char *errmsg, const char *file, int line TSRMLS_DC); -#define pdo_pgsql_error(w,s) _pdo_pgsql_error(w, s, __FILE__, __LINE__ TSRMLS_CC) -extern int pgsql_handle_error(pdo_dbh_t *dbh, pdo_pgsql_db_handle *H, int errcode); +extern int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char *file, int line TSRMLS_DC); +#define pdo_pgsql_error(d,e) _pdo_pgsql_error(d, NULL, e, __FILE__, __LINE__ TSRMLS_CC) +#define pdo_pgsql_error_stmt(s,e) _pdo_pgsql_error(s->dbh, s, e, __FILE__, __LINE__ TSRMLS_CC) extern struct pdo_stmt_methods pgsql_stmt_methods; -- 2.50.1