From 74d9ab3518d50ebafb12e8252c01fa904b089481 Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Fri, 6 May 2011 11:44:02 +0200 Subject: Add error support --- odb/pgsql/error.cxx | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ odb/pgsql/error.hxx | 33 ++++++++++++++++++++ odb/pgsql/exceptions.cxx | 35 ++++++++++++++++++++-- odb/pgsql/exceptions.hxx | 30 +++++++++++++++++++ odb/pgsql/makefile | 3 +- 5 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 odb/pgsql/error.cxx create mode 100644 odb/pgsql/error.hxx diff --git a/odb/pgsql/error.cxx b/odb/pgsql/error.cxx new file mode 100644 index 0000000..2dd4f03 --- /dev/null +++ b/odb/pgsql/error.cxx @@ -0,0 +1,78 @@ +// file : odb/pgsql/errors.cxx +// author : Constantin Michael +// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#include +#include + +#include +#include + +using namespace std; + +namespace odb +{ + namespace pgsql + { + void + translate_error (connection& c) + { + PGconn* h (0); // @@ c.handle (); + + assert (CONNECTION_BAD == PQstatus (h)); + + if (const char* m = PQerrorMessage (h)) + throw database_exception (m); + else + throw database_exception ("unknown error"); + } + + void + translate_error (connection& c, PGresult* r) + { + PGconn* h (0); // @@ c.handle (); + + if (!r) + { + if (CONNECTION_BAD == PQstatus (h)) + throw connection_lost (); + else + throw bad_alloc (); + } + + switch (PQresultStatus (r)) + { + case PGRES_BAD_RESPONSE: + { + if (const char* m = PQresultErrorMessage (r)) + throw database_exception (m); + 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)); + + // Deadlock detected. + // + if ("40P01" == s) + throw deadlock (); + + else if (CONNECTION_BAD == PQstatus (h)) + throw connection_lost (); + + else + throw database_exception (s, PQresultErrorMessage (r)); + } + + default: + assert (0); + break; + }; + } + } +} diff --git a/odb/pgsql/error.hxx b/odb/pgsql/error.hxx new file mode 100644 index 0000000..3de9e78 --- /dev/null +++ b/odb/pgsql/error.hxx @@ -0,0 +1,33 @@ +// file : odb/pgsql/errors.hxx +// author : Constantin Michael +// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC +// license : GNU GPL v2; see accompanying LICENSE file + +#ifndef ODB_PGSQL_ERRORS_HXX +#define ODB_PGSQL_ERRORS_HXX + +#include + +#include + +#include + +#include + +namespace odb +{ + namespace pgsql + { + class connection; + + LIBODB_PGSQL_EXPORT void + translate_error (connection&); + + LIBODB_PGSQL_EXPORT void + translate_error (connection& c, PGresult* r); + } +} + +#include + +#endif // ODB_PGSQL_ERRORS_HXX diff --git a/odb/pgsql/exceptions.cxx b/odb/pgsql/exceptions.cxx index bea0870..bec4ba7 100644 --- a/odb/pgsql/exceptions.cxx +++ b/odb/pgsql/exceptions.cxx @@ -3,6 +3,8 @@ // copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file +#include + #include using namespace std; @@ -12,12 +14,41 @@ namespace odb namespace pgsql { // + // database_exception + // + + database_exception:: + database_exception (const string& message) + : message_ (message), what_ (message) + { + } + + database_exception:: + database_exception (const string& sqlstate, + const string& message) + : sqlstate_ (sqlstate), message_ (message) + { + what_ = sqlstate_ + ": " + message_; + } + + database_exception:: + ~database_exception () throw () + { + } + + const char* database_exception:: + what () const throw () + { + return what_.c_str (); + } + + // // cli_exception // cli_exception:: - cli_exception (const std::string& what) - : what_ (what) + cli_exception (const string& w) + : what_ (w) { } diff --git a/odb/pgsql/exceptions.hxx b/odb/pgsql/exceptions.hxx index 0ceb83c..d6cae70 100644 --- a/odb/pgsql/exceptions.hxx +++ b/odb/pgsql/exceptions.hxx @@ -20,6 +20,36 @@ namespace odb { namespace pgsql { + struct LIBODB_PGSQL_EXPORT database_exception: odb::database_exception + { + database_exception (const std::string& message); + + database_exception (const std::string& sqlstate, + const std::string& message); + + ~database_exception () throw (); + + const std::string& + message () const + { + return message_; + } + + const std::string& + sqlstate () const + { + return sqlstate_; + } + + virtual const char* + what () const throw (); + + private: + std::string sqlstate_; + std::string message_; + std::string what_; + }; + struct LIBODB_PGSQL_EXPORT cli_exception: odb::exception { cli_exception (const std::string& what); diff --git a/odb/pgsql/makefile b/odb/pgsql/makefile index 11e8762..bf911db 100644 --- a/odb/pgsql/makefile +++ b/odb/pgsql/makefile @@ -8,7 +8,8 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make cxx := \ database.cxx \ -exceptions.cxx +error.cxx \ +exceptions.cxx cli_tun := details/options.cli cxx_tun := $(cxx) -- cgit v1.1