aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-07-22 20:43:35 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-07-22 20:43:35 +0200
commitb70088d31a8d3e78409f4247c1f2db9092e828e3 (patch)
tree94b391194ea0af567fc2a6872ca1a9d9887ee26b
parent42394a86aafd45d7a03604ce82d9bce471ad121c (diff)
Get rid of libpq-fe.h inclusion in public headers
The problem with libpq-fe.h is that it is installed in unpredictable places on different platforms. As a result, a user that uses ODB with PostgreSQL (and who doesn't really know or care about libpq) is forced to make sure their application is able to find and include libpq-fe.h correctly. Luckily for us, we only use a handful of libpq pointers in public headers and the workaround is to forward declare them and use that instead of including libpq-fe.h (which is instead included in source files).
-rw-r--r--odb/pgsql/connection.cxx2
-rw-r--r--odb/pgsql/connection.hxx3
-rw-r--r--odb/pgsql/container-statements.hxx1
-rw-r--r--odb/pgsql/error.hxx4
-rw-r--r--odb/pgsql/pgsql-fwd.hxx21
-rw-r--r--odb/pgsql/pgsql-types.hxx2
-rw-r--r--odb/pgsql/result-ptr.hxx14
-rw-r--r--odb/pgsql/statement.cxx49
-rw-r--r--odb/pgsql/statement.hxx6
9 files changed, 77 insertions, 25 deletions
diff --git a/odb/pgsql/connection.cxx b/odb/pgsql/connection.cxx
index b4790b0..f65cba4 100644
--- a/odb/pgsql/connection.cxx
+++ b/odb/pgsql/connection.cxx
@@ -7,6 +7,8 @@
#include <cstring> // std::strcmp
#include <string>
+#include <libpq-fe.h>
+
#include <odb/pgsql/database.hxx>
#include <odb/pgsql/connection.hxx>
#include <odb/pgsql/error.hxx>
diff --git a/odb/pgsql/connection.hxx b/odb/pgsql/connection.hxx
index 4793248..6914d5b 100644
--- a/odb/pgsql/connection.hxx
+++ b/odb/pgsql/connection.hxx
@@ -11,14 +11,13 @@
#include <vector>
#include <memory> // std::auto_ptr
-#include <libpq-fe.h>
-
#include <odb/forward.hxx>
#include <odb/details/shared-ptr.hxx>
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/forward.hxx>
+#include <odb/pgsql/pgsql-fwd.hxx> // PGconn
#include <odb/pgsql/details/export.hxx>
diff --git a/odb/pgsql/container-statements.hxx b/odb/pgsql/container-statements.hxx
index a1a0e66..252eb77 100644
--- a/odb/pgsql/container-statements.hxx
+++ b/odb/pgsql/container-statements.hxx
@@ -16,6 +16,7 @@
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/binding.hxx>
#include <odb/pgsql/statement.hxx>
+#include <odb/pgsql/pgsql-fwd.hxx> // Oid
#include <odb/pgsql/pgsql-oid.hxx>
#include <odb/pgsql/details/export.hxx>
diff --git a/odb/pgsql/error.hxx b/odb/pgsql/error.hxx
index 139a33c..287b45a 100644
--- a/odb/pgsql/error.hxx
+++ b/odb/pgsql/error.hxx
@@ -11,7 +11,6 @@
#include <libpq-fe.h>
#include <odb/pgsql/version.hxx>
-
#include <odb/pgsql/details/export.hxx>
namespace odb
@@ -28,8 +27,7 @@ namespace odb
// allocation error.
//
LIBODB_PGSQL_EXPORT void
- translate_error (connection& c,
- PGresult* r);
+ 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.
diff --git a/odb/pgsql/pgsql-fwd.hxx b/odb/pgsql/pgsql-fwd.hxx
new file mode 100644
index 0000000..45f085d
--- /dev/null
+++ b/odb/pgsql/pgsql-fwd.hxx
@@ -0,0 +1,21 @@
+// file : odb/pgsql/pgsql-fwd.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC
+// license : GNU GPL v2; see accompanying LICENSE file
+
+#ifndef ODB_PGSQL_PGSQL_FWD_HXX
+#define ODB_PGSQL_PGSQL_FWD_HXX
+
+#include <odb/pre.hxx>
+
+// Forward declaration for some of the types defined in libpq-fe.h. This
+// allows us to avoid having to include libpq-fe.h in public headers.
+//
+typedef unsigned int Oid;
+
+typedef struct pg_conn PGconn;
+typedef struct pg_result PGresult;
+
+#include <odb/post.hxx>
+
+#endif // ODB_PGSQL_PGSQL_FWD_HXX
diff --git a/odb/pgsql/pgsql-types.hxx b/odb/pgsql/pgsql-types.hxx
index 1d83b9f..2ebbc42 100644
--- a/odb/pgsql/pgsql-types.hxx
+++ b/odb/pgsql/pgsql-types.hxx
@@ -10,7 +10,7 @@
#include <cstddef> // std::size_t
-typedef unsigned int Oid;
+#include <odb/pgsql/pgsql-fwd.hxx> // Oid
namespace odb
{
diff --git a/odb/pgsql/result-ptr.hxx b/odb/pgsql/result-ptr.hxx
index 4cfe58d..2c5ee89 100644
--- a/odb/pgsql/result-ptr.hxx
+++ b/odb/pgsql/result-ptr.hxx
@@ -14,6 +14,12 @@
#include <odb/pgsql/details/export.hxx>
+//
+// Note: do not include this header into public headers (i.e., those
+// that may be included, directly or indirectly, by user code) because
+// it includes libpq-fe.h
+//
+
namespace odb
{
namespace pgsql
@@ -47,6 +53,14 @@ namespace odb
r_ = r;
}
+ PGresult*
+ release ()
+ {
+ PGresult* r (r_);
+ r_ = 0;
+ return r;
+ }
+
private:
result_ptr (const result_ptr&);
result_ptr& operator= (const result_ptr&);
diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx
index dde67c9..a9c7d9b 100644
--- a/odb/pgsql/statement.cxx
+++ b/odb/pgsql/statement.cxx
@@ -7,11 +7,14 @@
#include <cassert>
#include <sstream> // istringstream
+#include <libpq-fe.h>
+
#include <odb/exceptions.hxx> // object_not_persistent
#include <odb/pgsql/statement.hxx>
#include <odb/pgsql/connection.hxx>
#include <odb/pgsql/transaction.hxx>
+#include <odb/pgsql/result-ptr.hxx>
#include <odb/pgsql/error.hxx>
#include <odb/pgsql/details/endian-traits.hxx>
@@ -290,6 +293,8 @@ namespace odb
select_statement::
~select_statement ()
{
+ if (result_ != 0)
+ PQclear (result_);
}
select_statement::
@@ -305,6 +310,7 @@ namespace odb
cond_ (&cond),
native_cond_ (native_cond),
data_ (data),
+ result_ (0),
row_count_ (0),
current_row_ (0)
@@ -323,6 +329,7 @@ namespace odb
cond_ (0),
native_cond_ (native_cond),
data_ (data),
+ result_ (0),
row_count_ (0),
current_row_ (0)
@@ -332,32 +339,45 @@ namespace odb
void select_statement::
execute ()
{
- result_.reset ();
+ if (result_ != 0)
+ {
+ PQclear (result_);
+ result_ = 0;
+ }
if (cond_ != 0)
bind_param (native_cond_, *cond_);
- result_.reset (PQexecPrepared (conn_.handle (),
- name_.c_str (),
- native_cond_.count,
- native_cond_.values,
- native_cond_.lengths,
- native_cond_.formats,
- 1));
+ // Use temporary result_ptr to guarantee exception safety.
+ //
+ result_ptr r (PQexecPrepared (conn_.handle (),
+ name_.c_str (),
+ native_cond_.count,
+ native_cond_.values,
+ native_cond_.lengths,
+ native_cond_.formats,
+ 1));
- PGresult* h (result_.get ());
+ PGresult* h (r.get ());
if (!is_good_result (h))
translate_error (conn_, h);
row_count_ = static_cast<size_t> (PQntuples (h));
current_row_ = 0;
+
+ result_ = r.release ();
}
void select_statement::
free_result ()
{
- result_.reset ();
+ if (result_ != 0)
+ {
+ PQclear (result_);
+ result_ = 0;
+ }
+
row_count_ = 0;
current_row_ = 0;
}
@@ -377,11 +397,10 @@ namespace odb
if (current_row_ > row_count_)
return no_data;
- PGresult* h (result_.get ());
-
assert (current_row_ > 0);
- return bind_result (data_.bind, data_.count, h, current_row_ - 1) ?
- success : truncated;
+ return bind_result (data_.bind, data_.count, result_, current_row_ - 1)
+ ? success
+ : truncated;
}
void select_statement::
@@ -392,7 +411,7 @@ namespace odb
if (!bind_result (data_.bind,
data_.count,
- result_.get (),
+ result_,
current_row_ - 1,
true))
assert (false);
diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx
index e248b07..3a25f5e 100644
--- a/odb/pgsql/statement.hxx
+++ b/odb/pgsql/statement.hxx
@@ -11,13 +11,11 @@
#include <string>
#include <cstddef> // std::size_t
-#include <libpq-fe.h>
-
#include <odb/details/shared-ptr.hxx>
#include <odb/pgsql/version.hxx>
#include <odb/pgsql/binding.hxx>
-#include <odb/pgsql/result-ptr.hxx>
+#include <odb/pgsql/pgsql-fwd.hxx>
#include <odb/pgsql/details/export.hxx>
@@ -159,7 +157,7 @@ namespace odb
binding& data_;
- result_ptr result_;
+ PGresult* result_;
std::size_t row_count_;
std::size_t current_row_;
};