diff options
author | Constantin Michael <constantin@codesynthesis.com> | 2011-05-11 10:57:56 +0200 |
---|---|---|
committer | Constantin Michael <constantin@codesynthesis.com> | 2011-05-11 10:57:56 +0200 |
commit | 3cdf7c4e3f6b085b4b386d4da64f3fbf396375a3 (patch) | |
tree | e2f5dd54ed7aca322a4ab6a622cd677a7db7f650 | |
parent | fd0eb17d25ee829557549255ec64f9b9b063ec8b (diff) |
Modify error to allow for libpq resource cleanup
-rw-r--r-- | odb/pgsql/error.cxx | 63 | ||||
-rw-r--r-- | odb/pgsql/error.hxx | 16 |
2 files changed, 54 insertions, 25 deletions
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 <odb/pgsql/error.hxx> #include <odb/pgsql/exceptions.hxx> +#include <odb/pgsql/connection.hxx> 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); } } |