#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;
}
/* }}} */
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)
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;
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) /* {{{ */
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);
);
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;
}
#include <libpq-fe.h>
+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 {
pdo_pgsql_db_handle *H;
PGresult *result;
int current_row;
- char *last_err;
pdo_pgsql_column *cols;
} pdo_pgsql_stmt;
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;