aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-07-05 13:02:03 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-07-05 13:02:03 +0200
commit0fba3bc7e0747e23ca2698e0acc82e80b569e531 (patch)
treeb39290a6334adc2b451a9e7fd397c35a09389487
parent283fec23e49a9e62a8717879808343420338d01e (diff)
Implement PostgreSQL specific fetch operations for select_statement
-rw-r--r--odb/pgsql/statement.cxx70
-rw-r--r--odb/pgsql/statement.hxx52
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_;