From b70088d31a8d3e78409f4247c1f2db9092e828e3 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 22 Jul 2011 20:43:35 +0200 Subject: 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). --- odb/pgsql/connection.cxx | 2 ++ odb/pgsql/connection.hxx | 3 +-- odb/pgsql/container-statements.hxx | 1 + odb/pgsql/error.hxx | 4 +--- odb/pgsql/pgsql-fwd.hxx | 21 ++++++++++++++++ odb/pgsql/pgsql-types.hxx | 2 +- odb/pgsql/result-ptr.hxx | 14 +++++++++++ odb/pgsql/statement.cxx | 49 ++++++++++++++++++++++++++------------ odb/pgsql/statement.hxx | 6 ++--- 9 files changed, 77 insertions(+), 25 deletions(-) create mode 100644 odb/pgsql/pgsql-fwd.hxx 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 // std::strcmp #include +#include + #include #include #include 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 #include // std::auto_ptr -#include - #include #include #include #include +#include // PGconn #include 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 #include #include +#include // Oid #include #include 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 #include - #include 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 +// 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 + +// 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 + +#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 // std::size_t -typedef unsigned int Oid; +#include // 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 +// +// 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 #include // istringstream +#include + #include // object_not_persistent #include #include #include +#include #include #include @@ -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 (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 #include // std::size_t -#include - #include #include #include -#include +#include #include @@ -159,7 +157,7 @@ namespace odb binding& data_; - result_ptr result_; + PGresult* result_; std::size_t row_count_; std::size_t current_row_; }; -- cgit v1.1