From 0fba3bc7e0747e23ca2698e0acc82e80b569e531 Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Tue, 5 Jul 2011 13:02:03 +0200 Subject: Implement PostgreSQL specific fetch operations for select_statement --- odb/pgsql/statement.cxx | 70 +++++++++++++++++++++++++++++++++---------------- odb/pgsql/statement.hxx | 52 ++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 33 deletions(-) diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx index 233519c..b06646e 100644 --- a/odb/pgsql/statement.cxx +++ b/odb/pgsql/statement.cxx @@ -282,7 +282,25 @@ namespace odb native_binding& native_cond, binding& data) : statement (conn, name, stmt, types, types_count), - cond_ (cond), + cond_ (&cond), + native_cond_ (native_cond), + data_ (data), + row_count_ (0), + current_row_ (0) + + { + } + + select_statement:: + select_statement (connection& conn, + const std::string& name, + const std::string& stmt, + const Oid* types, + std::size_t types_count, + native_binding& native_cond, + binding& data) + : statement (conn, name, stmt, types, types_count), + cond_ (0), native_cond_ (native_cond), data_ (data), row_count_ (0), @@ -295,7 +313,9 @@ namespace odb execute () { result_.reset (); - bind_param (native_cond_, cond_); + + if (cond_ != 0) + bind_param (native_cond_, *cond_); result_.reset (PQexecPrepared (conn_.handle (), name_.c_str (), @@ -314,44 +334,50 @@ namespace odb current_row_ = 0; } + void select_statement:: + free_result () + { + result_.reset (); + row_count_ = 0; + current_row_ = 0; + } + + bool select_statement:: + next () + { + if (current_row_ <= row_count_) + ++current_row_; + + return current_row_ <= row_count_; + } + select_statement::result select_statement:: - fetch () + load () { - if (current_row_ >= row_count_) + if (current_row_ > row_count_) return no_data; PGresult* h (result_.get ()); - if (bind_result (data_.bind, data_.count, h, current_row_)) - { - ++current_row_; - return success; - } - - return truncated; + assert (current_row_ > 0); + return bind_result (data_.bind, data_.count, h, current_row_ - 1) ? + success : truncated; } void select_statement:: - refetch () + reload () { - assert (current_row_ < row_count_); + assert (current_row_ > 0); + assert (current_row_ <= row_count_); if (!bind_result (data_.bind, data_.count, result_.get (), - current_row_++, + current_row_ - 1, true)) assert (false); } - void select_statement:: - free_result () - { - result_.reset (); - row_count_ = 0; - current_row_ = 0; - } - // // insert_statement // diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx index 146a34f..09779b4 100644 --- a/odb/pgsql/statement.hxx +++ b/odb/pgsql/statement.hxx @@ -36,14 +36,6 @@ namespace odb void deallocate (); - protected: - statement (connection&, - const std::string& name, - const std::string& stmt, - const Oid* types, - std::size_t types_count); - - protected: // Adapt an ODB binding to a native PostgreSQL parameter binding. // static void @@ -63,6 +55,13 @@ namespace odb bool truncated = false); protected: + statement (connection&, + const std::string& name, + const std::string& stmt, + const Oid* types, + std::size_t types_count); + + protected: connection& conn_; std::string name_; @@ -85,6 +84,14 @@ namespace odb native_binding& native_cond, binding& data); + select_statement (connection& conn, + const std::string& name, + const std::string& stmt, + const Oid* types, + std::size_t types_count, + native_binding& native_cond, + binding& data); + // Common select interface expected by the generated code. // public: @@ -112,24 +119,47 @@ namespace odb // Load next row columns into bound buffers. // result - fetch (); + fetch () + { + return next () ? load () : no_data; + } // Reload truncated columns into bound buffers. // void - refetch (); + refetch () + { + reload (); + } // Free the result set. // void free_result (); + // Finer grained control of PostgreSQL-specific interface that + // splits fetch() into next() and load(). + // + public: + // Return false if there is no more rows. You should call next() + // until it returns false or, alternatively, call free_result (). + // Otherwise the statement will remain unfinished. + // + bool + next (); + + result + load (); + + void + reload (); + private: select_statement (const select_statement&); select_statement& operator= (const select_statement&); private: - binding& cond_; + binding* cond_; native_binding& native_cond_; binding& data_; -- cgit v1.1