diff --git a/ChangeLog b/ChangeLog index 91f5ff27..cc8ee47a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-01-11 James Henstridge + + * psycopg/connection_int.c (conn_close): fix for new + pq_abort_locked() prototype. + (conn_switch_isolation_level): fix for new pq_abort_locked() + prototype, and use pq_complete_error() to show error message. + (conn_set_client_encoding): same here. + + * psycopg/pqpath.c (pq_execute_command_locked): remove static + modifier. + (pq_complete_error): same here. + (pq_abort_locked): add pgres and error arguments. + (pq_abort): call pq_abort_locked() to reduce code duplication. + 2007-12-23 James Henstridge * psycopg/pqpath.c (pq_execute_command_locked): add an error diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index 94b762b3..da863c3b 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -217,7 +217,14 @@ conn_close(connectionObject *self) /* execute a forced rollback on the connection (but don't check the result, we're going to close the pq connection anyway */ if (self->pgconn) { - pq_abort_locked(self); + PGresult *pgres = NULL; + char *error = NULL; + + if (pq_abort_locked(self, &pgres, &error) < 0) { + IFCLEARPGRES(pgres); + if (error) + free (error); + } PQfinish(self->pgconn); Dprintf("conn_close: PQfinish called"); self->pgconn = NULL; @@ -257,6 +264,8 @@ conn_rollback(connectionObject *self) int conn_switch_isolation_level(connectionObject *self, int level) { + PGresult *pgres = NULL; + char *error = NULL; int res = 0; /* if the current isolation level is equal to the requested one don't switch */ @@ -268,7 +277,7 @@ conn_switch_isolation_level(connectionObject *self, int level) /* if the current isolation level is > 0 we need to abort the current transaction before changing; that all folks! */ if (self->isolation_level != level && self->isolation_level > 0) { - res = pq_abort_locked(self); + res = pq_abort_locked(self, &pgres, &error); } self->isolation_level = level; self->mark++; @@ -278,6 +287,9 @@ conn_switch_isolation_level(connectionObject *self, int level) pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; + if (res < 0) + pq_complete_error(self, &pgres, &error); + return res; } @@ -286,7 +298,8 @@ conn_switch_isolation_level(connectionObject *self, int level) int conn_set_client_encoding(connectionObject *self, char *enc) { - PGresult *pgres; + PGresult *pgres = NULL; + char *error = NULL; char query[48]; int res = 0; @@ -304,30 +317,25 @@ conn_set_client_encoding(connectionObject *self, char *enc) /* abort the current transaction, to set the encoding ouside of transactions */ - res = pq_abort_locked(self); + res = pq_abort_locked(self, &pgres, &error); if (res == 0) { - pgres = PQexec(self->pgconn, query); - - if (pgres == NULL || PQresultStatus(pgres) != PGRES_COMMAND_OK ) { - res = -1; - } - else { + res = pq_execute_command_locked(self, query, &pgres, &error); + if (res == 0) { /* no error, we can proceeed and store the new encoding */ if (self->encoding) free(self->encoding); self->encoding = strdup(enc); + Dprintf("conn_set_client_encoding: set encoding to %s", + self->encoding); } - - IFCLEARPGRES(pgres); } - Dprintf("conn_set_client_encoding: set encoding to %s", self->encoding); pthread_mutex_unlock(&self->lock); Py_END_ALLOW_THREADS; - if (res == -1) - PyErr_Format(OperationalError, "can't set encoding to %s", enc); + if (res < 0) + pq_complete_error(self, &pgres, &error); return res; } diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index b7daba7d..49aac279 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -238,7 +238,7 @@ pq_clear_async(connectionObject *conn) On error, -1 is returned, and the pgres argument will hold the relevant result structure. */ -static int +int pq_execute_command_locked(connectionObject *conn, const char *query, PGresult **pgres, char **error) { @@ -280,7 +280,7 @@ pq_execute_command_locked(connectionObject *conn, const char *query, This function should be called while holding the global interpreter lock. */ -static void +void pq_complete_error(connectionObject *conn, PGresult **pgres, char **error) { Dprintf("pq_complete_error: pgconn = %p, pgres = %p, error = %s", @@ -375,11 +375,9 @@ pq_commit(connectionObject *conn) } int -pq_abort_locked(connectionObject *conn) +pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error) { int retvalue = -1; - PGresult *pgres = NULL; - char *error = NULL; Dprintf("pq_abort_locked: pgconn = %p, isolevel = %ld, status = %d", conn->pgconn, conn->isolation_level, conn->status); @@ -390,14 +388,10 @@ pq_abort_locked(connectionObject *conn) } pq_clear_async(conn); - retvalue = pq_execute_command_locked(conn, "ROLLBACK", &pgres, &error); + retvalue = pq_execute_command_locked(conn, "ROLLBACK", pgres, error); + if (retvalue == 0) + conn->status = CONN_STATUS_READY; - if (retvalue < 0) - pq_set_critical(conn, NULL); - - IFCLEARPGRES(pgres); - if (error) - free(error); return retvalue; } @@ -424,16 +418,13 @@ pq_abort(connectionObject *conn) Py_BEGIN_ALLOW_THREADS; pthread_mutex_lock(&conn->lock); - pq_clear_async(conn); - retvalue = pq_execute_command_locked(conn, "ROLLBACK", &pgres, &error); + retvalue = pq_abort_locked(conn, &pgres, &error); pthread_mutex_unlock(&conn->lock); Py_END_ALLOW_THREADS; if (retvalue < 0) pq_complete_error(conn, &pgres, &error); - else - conn->status = CONN_STATUS_READY; return retvalue; } diff --git a/psycopg/pqpath.h b/psycopg/pqpath.h index d55b0b63..e3cee114 100644 --- a/psycopg/pqpath.h +++ b/psycopg/pqpath.h @@ -33,10 +33,18 @@ extern int pq_fetch(cursorObject *curs); extern int pq_execute(cursorObject *curs, const char *query, int async); extern int pq_commit(connectionObject *conn); -extern int pq_abort_locked(connectionObject *conn); +extern int pq_abort_locked(connectionObject *conn, PGresult **pgres, + char **error); extern int pq_abort(connectionObject *conn); extern int pq_is_busy(connectionObject *conn); + extern void pq_set_critical(connectionObject *conn, const char *msg); extern PyObject *pq_resolve_critical(connectionObject *conn, int close); +extern int pq_execute_command_locked(connectionObject *conn, + const char *query, + PGresult **pgres, char **error); +extern void pq_complete_error(connectionObject *conn, PGresult **pgres, + char **error); + #endif /* !defined(PSYCOPG_PQPATH_H) */