aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-05-13 15:56:57 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-05-13 15:56:57 +0200
commit10a83d0453f65c41c3915c906f2d6cf9d6ff349e (patch)
treeca13498579d9f15c1265eccd3b28755454580cbd
parent3faf8e7a8aa2411f207fa09fe81982615d90a726 (diff)
Add PGresult pointer wrapper
-rw-r--r--odb/pgsql/database.cxx24
-rw-r--r--odb/pgsql/error.cxx78
-rw-r--r--odb/pgsql/error.hxx25
-rw-r--r--odb/pgsql/error.ixx29
-rw-r--r--odb/pgsql/result-ptr.hxx49
-rw-r--r--odb/pgsql/transaction-impl.cxx49
6 files changed, 137 insertions, 117 deletions
diff --git a/odb/pgsql/database.cxx b/odb/pgsql/database.cxx
index ac7a991..721e600 100644
--- a/odb/pgsql/database.cxx
+++ b/odb/pgsql/database.cxx
@@ -4,12 +4,14 @@
// license : GNU GPL v2; see accompanying LICENSE file
#include <sstream>
+#include <cstdlib> // std::atol
#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>
+#include <odb/pgsql/result-ptr.hxx>
#include <odb/pgsql/details/options.hxx>
@@ -217,21 +219,23 @@ namespace odb
connection_type& c (transaction::current ().connection ());
- PGresult* r = PQexec (c.handle (), s);
+ result_ptr r (PQexec (c.handle (), s));
+ PGresult* h (r.get ());
- 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));
+ if (!is_good_result (h))
+ translate_error (c, h);
+ else if (PGRES_TUPLES_OK == PQresultStatus (h))
+ count = static_cast<unsigned long long> (PQntuples (h));
else
{
- istringstream ss (PQcmdTuples (r));
- ss >> count;
+ const char* s (PQcmdTuples (h));
+
+ if (s[0] != '\0' && s[1] == '\0')
+ count = static_cast<unsigned long long> (s[0] - '0');
+ else
+ count = static_cast<unsigned long long> (atol (s));
}
return count;
diff --git a/odb/pgsql/error.cxx b/odb/pgsql/error.cxx
index f65cbee..cb11872 100644
--- a/odb/pgsql/error.cxx
+++ b/odb/pgsql/error.cxx
@@ -17,7 +17,7 @@ namespace odb
namespace pgsql
{
void
- translate_connection_error (connection& c)
+ translate_error (connection& c)
{
PGconn* h (c.handle ());
@@ -30,14 +30,20 @@ namespace odb
}
void
- translate_result_error_ (connection& c,
- ExecStatusType status = PGRES_EMPTY_QUERY,
- const char* sqlstate = 0,
- const char* error_message = 0)
+ translate_error (connection& c,
+ PGresult* r)
{
- PGconn* h (c.handle ());
+ if (!r)
+ {
+ if (CONNECTION_BAD == PQstatus (c.handle ()))
+ throw connection_lost ();
+ else
+ throw bad_alloc ();
+ }
- switch (status)
+ const char* error_message (PQresultErrorMessage (r));
+
+ switch (PQresultStatus (r))
{
case PGRES_BAD_RESPONSE:
{
@@ -49,67 +55,25 @@ namespace odb
case PGRES_FATAL_ERROR:
{
- assert (sqlstate);
+ const char* ss (PQresultErrorField (r, PG_DIAG_SQLSTATE));
+
+ assert (ss);
assert (error_message);
// Deadlock detected.
//
- if (std::string ("40P01") == sqlstate)
+ if (std::string ("40P01") == ss)
throw deadlock ();
- else if (CONNECTION_BAD == PQstatus (h))
+ else if (CONNECTION_BAD == PQstatus (c.handle ()))
throw connection_lost ();
else
- throw database_exception (sqlstate, error_message);
+ throw database_exception (ss, error_message);
}
-
default:
- {
- if (CONNECTION_BAD == PQstatus (h))
- throw connection_lost ();
- else
- throw bad_alloc ();
- }
- };
- }
-
- 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,
- 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);
+ assert (0);
+ break;
}
}
}
diff --git a/odb/pgsql/error.hxx b/odb/pgsql/error.hxx
index d4ea9e1..139a33c 100644
--- a/odb/pgsql/error.hxx
+++ b/odb/pgsql/error.hxx
@@ -21,7 +21,15 @@ namespace odb
class connection;
LIBODB_PGSQL_EXPORT void
- translate_connection_error (connection&);
+ translate_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.
+ //
+ LIBODB_PGSQL_EXPORT void
+ translate_error (connection& c,
+ PGresult* r);
// 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.
@@ -29,22 +37,11 @@ namespace odb
//
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
- // 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_result_error (connection& c,
- PGresult* r = 0,
- ExecStatusType s = PGRES_EMPTY_QUERY,
- bool clear_result = true);
}
}
+#include <odb/pgsql/error.ixx>
+
#include <odb/post.hxx>
#endif // ODB_PGSQL_ERRORS_HXX
diff --git a/odb/pgsql/error.ixx b/odb/pgsql/error.ixx
new file mode 100644
index 0000000..5bbc698
--- /dev/null
+++ b/odb/pgsql/error.ixx
@@ -0,0 +1,29 @@
+// file : odb/pgsql/error.ixx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+namespace odb
+{
+ namespace pgsql
+ {
+ bool
+ inline is_good_result (PGresult* r, ExecStatusType* s)
+ {
+ if (r != 0)
+ {
+ ExecStatusType status (PQresultStatus (r));
+
+ if (s != 0)
+ *s = status;
+
+ return
+ status != PGRES_BAD_RESPONSE &&
+ status != PGRES_NONFATAL_ERROR &&
+ status != PGRES_FATAL_ERROR;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/odb/pgsql/result-ptr.hxx b/odb/pgsql/result-ptr.hxx
new file mode 100644
index 0000000..1772cc9
--- /dev/null
+++ b/odb/pgsql/result-ptr.hxx
@@ -0,0 +1,49 @@
+// file : odb/pgsql/result-ptr.hxx
+// author : Constantin Michael <constantin@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_PGSQL_RESULT_PTR_HXX
+#define ODB_PGSQL_RESULT_PTR_HXX
+
+#include <odb/pre.hxx>
+
+#include <libpq-fe.h>
+
+#include <odb/pgsql/version.hxx>
+
+#include <odb/pgsql/details/export.hxx>
+
+namespace odb
+{
+ namespace pgsql
+ {
+ class LIBODB_PGSQL_EXPORT result_ptr
+ {
+ public:
+ result_ptr (PGresult* r)
+ : r_ (r)
+ {
+ }
+
+ ~result_ptr ()
+ {
+ if (r_)
+ PQclear (r_);
+ }
+
+ PGresult*
+ get ()
+ {
+ return r_;
+ }
+
+ private:
+ PGresult* r_;
+ };
+ }
+}
+
+#include <odb/post.hxx>
+
+#endif // ODB_PGSQL_RESULT_PTR_HXX
diff --git a/odb/pgsql/transaction-impl.cxx b/odb/pgsql/transaction-impl.cxx
index 2d2a988..eb93361 100644
--- a/odb/pgsql/transaction-impl.cxx
+++ b/odb/pgsql/transaction-impl.cxx
@@ -12,6 +12,7 @@
#include <odb/pgsql/error.hxx>
#include <odb/pgsql/exceptions.hxx>
#include <odb/pgsql/transaction-impl.hxx>
+#include <odb/pgsql/result-ptr.hxx>
namespace odb
{
@@ -21,15 +22,11 @@ namespace odb
transaction_impl (database_type& db)
: odb::transaction_impl (db), connection_ (db.connection ())
{
- PGresult* r (PQexec (connection_->handle (), "begin"));
+ result_ptr r (PQexec (connection_->handle (), "begin"));
+ PGresult* h (r.get ());
- if (!r)
- translate_result_error (*connection_);
-
- ExecStatusType s (PQresultStatus (r));
-
- if (PGRES_COMMAND_OK != s)
- translate_result_error (*connection_, r, s);
+ if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
+ translate_error (*connection_, h);
}
transaction_impl::
@@ -40,41 +37,21 @@ namespace odb
void transaction_impl::
commit ()
{
- // connection_->clear ();
-
- PGresult* r (PQexec (connection_->handle (), "commit"));
-
- if (!r)
- translate_result_error (*connection_);
-
- ExecStatusType s (PQresultStatus (r));
+ result_ptr r (PQexec (connection_->handle (), "commit"));
+ PGresult* h (r.get ());
- if (PGRES_COMMAND_OK != s)
- translate_result_error (*connection_, r, s);
-
- // Release the connection.
- //
- // connection_.reset ();
+ if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
+ translate_error (*connection_, h);
}
void transaction_impl::
rollback ()
{
- // connection_->clear ();
-
- PGresult* r (PQexec (connection_->handle (), "rollback"));
-
- if (!r)
- translate_result_error (*connection_);
-
- ExecStatusType s (PQresultStatus (r));
-
- if (PGRES_COMMAND_OK != s)
- translate_result_error (*connection_, r, s);
+ result_ptr r (PQexec (connection_->handle (), "rollback"));
+ PGresult* h (r.get ());
- // Release the connection.
- //
- //connection_.reset ();
+ if (!h || PGRES_COMMAND_OK != PQresultStatus (h))
+ translate_error (*connection_, h);
}
}
}