aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/pgsql/database.cxx34
-rw-r--r--odb/pgsql/database.hxx8
-rw-r--r--odb/pgsql/error.cxx23
-rw-r--r--odb/pgsql/error.hxx7
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