diff options
-rw-r--r-- | odb/pgsql/database.cxx | 34 | ||||
-rw-r--r-- | odb/pgsql/database.hxx | 8 | ||||
-rw-r--r-- | odb/pgsql/error.cxx | 23 | ||||
-rw-r--r-- | odb/pgsql/error.hxx | 7 |
4 files changed, 59 insertions, 13 deletions
diff --git a/odb/pgsql/database.cxx b/odb/pgsql/database.cxx index 080b17f..ac7a991 100644 --- a/odb/pgsql/database.cxx +++ b/odb/pgsql/database.cxx @@ -6,6 +6,7 @@ #include <sstream> #include <odb/pgsql/database.hxx> +#include <odb/pgsql/error.hxx> #include <odb/pgsql/exceptions.hxx> #include <odb/pgsql/connection-factory.hxx> #include <odb/pgsql/transaction.hxx> @@ -208,12 +209,33 @@ namespace odb { } - // @@ Implement on completion of supporting code. - // - // unsigned long long database:: - // execute (const char* s, std::size_t n) - // { - // } + unsigned long long database:: + execute (const char* s, std::size_t) + { + if (!transaction::has_current ()) + throw not_in_transaction (); + + connection_type& c (transaction::current ().connection ()); + + PGresult* r = PQexec (c.handle (), s); + + ExecStatusType status; + unsigned long long count (0); + + if (!r) + translate_result_error (c); + else if (!is_good_result (r, &status)) + translate_result_error (c, r, status); + else if (status == PGRES_TUPLES_OK) + count = static_cast<unsigned long long> (PQntuples (r)); + else + { + istringstream ss (PQcmdTuples (r)); + ss >> count; + } + + return count; + } transaction_impl* database:: begin () diff --git a/odb/pgsql/database.hxx b/odb/pgsql/database.hxx index a45fbb0..a8219d3 100644 --- a/odb/pgsql/database.hxx +++ b/odb/pgsql/database.hxx @@ -83,11 +83,9 @@ namespace odb print_usage (std::ostream&); public: - // @@ Implement on completion of supporting code. - // - // using odb::database::execute; - // virtual unsigned long long - // execute (const char* statement, std::size_t length); + using odb::database::execute; + virtual unsigned long long + execute (const char* statement, std::size_t length); public: virtual transaction_impl* diff --git a/odb/pgsql/error.cxx b/odb/pgsql/error.cxx index ba14b9a..f65cbee 100644 --- a/odb/pgsql/error.cxx +++ b/odb/pgsql/error.cxx @@ -74,6 +74,25 @@ namespace odb }; } + bool + is_good_result (PGresult* r, ExecStatusType* s) + { + if (r != 0) + { + ExecStatusType status (PQresultStatus (r)); + + if (s != 0) + *s = status; + + return + *s != PGRES_BAD_RESPONSE && + *s != PGRES_NONFATAL_ERROR && + *s != PGRES_FATAL_ERROR; + } + + return false; + } + void translate_result_error (connection& c, PGresult* r, @@ -84,8 +103,8 @@ namespace odb translate_result_error_ (c); else { - const char* ss = PQresultErrorField (r, PG_DIAG_SQLSTATE); - const char* m = PQresultErrorMessage (r); + const char* ss (PQresultErrorField (r, PG_DIAG_SQLSTATE)); + const char* m (PQresultErrorMessage (r)); if (clear_result) PQclear (r); diff --git a/odb/pgsql/error.hxx b/odb/pgsql/error.hxx index 7d2138b..d4ea9e1 100644 --- a/odb/pgsql/error.hxx +++ b/odb/pgsql/error.hxx @@ -23,6 +23,13 @@ namespace odb LIBODB_PGSQL_EXPORT void translate_connection_error (connection&); + // Return true if the PGresult is in an error state. If both s and r are + // non-null, the pointed to value will be populated with the result status. + // Otherwise, s is ignored. + // + LIBODB_PGSQL_EXPORT bool + is_good_result (PGresult* r, ExecStatusType* s = 0); + // 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 |