diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2011-07-22 20:43:35 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2011-07-22 20:43:35 +0200 |
commit | b70088d31a8d3e78409f4247c1f2db9092e828e3 (patch) | |
tree | 94b391194ea0af567fc2a6872ca1a9d9887ee26b | |
parent | 42394a86aafd45d7a03604ce82d9bce471ad121c (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.cxx | 2 | ||||
-rw-r--r-- | odb/pgsql/connection.hxx | 3 | ||||
-rw-r--r-- | odb/pgsql/container-statements.hxx | 1 | ||||
-rw-r--r-- | odb/pgsql/error.hxx | 4 | ||||
-rw-r--r-- | odb/pgsql/pgsql-fwd.hxx | 21 | ||||
-rw-r--r-- | odb/pgsql/pgsql-types.hxx | 2 | ||||
-rw-r--r-- | odb/pgsql/result-ptr.hxx | 14 | ||||
-rw-r--r-- | odb/pgsql/statement.cxx | 49 | ||||
-rw-r--r-- | odb/pgsql/statement.hxx | 6 |
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_; }; |