From 3cdf7c4e3f6b085b4b386d4da64f3fbf396375a3 Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Wed, 11 May 2011 10:57:56 +0200 Subject: Modify error to allow for libpq resource cleanup --- odb/pgsql/error.cxx | 63 ++++++++++++++++++++++++++++++++++------------------- odb/pgsql/error.hxx | 16 +++++++++++--- 2 files changed, 54 insertions(+), 25 deletions(-) (limited to 'odb/pgsql') diff --git a/odb/pgsql/error.cxx b/odb/pgsql/error.cxx index 2dd4f03..ba14b9a 100644 --- a/odb/pgsql/error.cxx +++ b/odb/pgsql/error.cxx @@ -8,6 +8,7 @@ #include #include +#include using namespace std; @@ -16,9 +17,9 @@ namespace odb namespace pgsql { void - translate_error (connection& c) + translate_connection_error (connection& c) { - PGconn* h (0); // @@ c.handle (); + PGconn* h (c.handle ()); assert (CONNECTION_BAD == PQstatus (h)); @@ -29,50 +30,68 @@ namespace odb } void - translate_error (connection& c, PGresult* r) + translate_result_error_ (connection& c, + ExecStatusType status = PGRES_EMPTY_QUERY, + const char* sqlstate = 0, + const char* error_message = 0) { - PGconn* h (0); // @@ c.handle (); + PGconn* h (c.handle ()); - if (!r) - { - if (CONNECTION_BAD == PQstatus (h)) - throw connection_lost (); - else - throw bad_alloc (); - } - - switch (PQresultStatus (r)) + switch (status) { case PGRES_BAD_RESPONSE: { - if (const char* m = PQresultErrorMessage (r)) - throw database_exception (m); + if (error_message != 0) + throw database_exception (error_message); else throw database_exception ("bad server response"); } case PGRES_FATAL_ERROR: { - // PG_DIAG_SQLSTATE field is always present. - // - string s (PQresultErrorField (r, PG_DIAG_SQLSTATE)); + assert (sqlstate); + assert (error_message); // Deadlock detected. // - if ("40P01" == s) + if (std::string ("40P01") == sqlstate) throw deadlock (); else if (CONNECTION_BAD == PQstatus (h)) throw connection_lost (); else - throw database_exception (s, PQresultErrorMessage (r)); + throw database_exception (sqlstate, error_message); } default: - assert (0); - break; + { + if (CONNECTION_BAD == PQstatus (h)) + throw connection_lost (); + else + throw bad_alloc (); + } }; } + + void + translate_result_error (connection& c, + PGresult* r, + ExecStatusType s, + bool clear_result) + { + if (!r) + translate_result_error_ (c); + else + { + const char* ss = PQresultErrorField (r, PG_DIAG_SQLSTATE); + const char* m = PQresultErrorMessage (r); + + if (clear_result) + PQclear (r); + + translate_result_error_ (c, s, ss, m); + } + } } } diff --git a/odb/pgsql/error.hxx b/odb/pgsql/error.hxx index 3de9e78..7d2138b 100644 --- a/odb/pgsql/error.hxx +++ b/odb/pgsql/error.hxx @@ -21,10 +21,20 @@ namespace odb class connection; LIBODB_PGSQL_EXPORT void - translate_error (connection&); - + translate_connection_error (connection&); + + // Translate an error condition involving a PGresult*. If r is null, it is + // assumed that the error was caused due to a bad connection or a memory + // allocation error. All remaining parameters except c are ignored. If r + // is non-null, the error is translated using the provided result status, + // s. Error descriptions are obtained using r. If clear_result is true, + // the resources associated with r are released via PQclear(). + // LIBODB_PGSQL_EXPORT void - translate_error (connection& c, PGresult* r); + translate_result_error (connection& c, + PGresult* r = 0, + ExecStatusType s = PGRES_EMPTY_QUERY, + bool clear_result = true); } } -- cgit v1.1