aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-05-11 10:57:56 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-05-11 10:57:56 +0200
commit3cdf7c4e3f6b085b4b386d4da64f3fbf396375a3 (patch)
treee2f5dd54ed7aca322a4ab6a622cd677a7db7f650
parentfd0eb17d25ee829557549255ec64f9b9b063ec8b (diff)
Modify error to allow for libpq resource cleanup
-rw-r--r--odb/pgsql/error.cxx63
-rw-r--r--odb/pgsql/error.hxx16
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);
}
}