aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-05-26 19:00:45 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-05-26 19:00:45 +0200
commit92122851eba43ade23e404dd5562bf1389bd60b5 (patch)
treebe2e2b92ca0643fc5ec084895558771881170eb2
parenteb23859d1fea6c465595b1db975864361319c723 (diff)
Correct statement
-rw-r--r--odb/pgsql/statement.cxx115
-rw-r--r--odb/pgsql/statement.hxx1
2 files changed, 45 insertions, 71 deletions
diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx
index 5e9007d..e223b4e 100644
--- a/odb/pgsql/statement.cxx
+++ b/odb/pgsql/statement.cxx
@@ -21,6 +21,8 @@ namespace odb
{
namespace pgsql
{
+ using namespace details;
+
//
// statement
//
@@ -63,38 +65,28 @@ namespace odb
{
assert (n.count == b.count);
- if (n.version != b.version)
+ for (size_t i (0); i < n.count; ++i)
{
- for (size_t i (0); i < n.count; ++i)
- {
- const bind& current_bind (b.bind[i]);
+ const bind& current_bind (b.bind[i]);
- if (current_bind.is_null != 0 && *current_bind.is_null)
- {
- n.values[i] = 0;
- continue;
- }
+ if (current_bind.is_null != 0 && *current_bind.is_null)
+ {
+ n.values[i] = 0;
+ continue;
+ }
- n.values[i] = reinterpret_cast<char*> (current_bind.buffer);
+ n.values[i] = reinterpret_cast<char*> (current_bind.buffer);
- // Use text format for numeric/decimal types and binary format
- // for all others.
- //
- if (current_bind.type == bind::numeric)
- n.formats[i] = 0;
- else
- {
- n.formats[i] = 1;
- n.lengths[i] = static_cast<int> (*current_bind.size);
- }
+ // Use text format for numeric/decimal types and binary format
+ // for all others.
+ //
+ if (current_bind.type == bind::numeric)
+ n.formats[i] = 0;
+ else
+ {
+ n.formats[i] = 1;
+ n.lengths[i] = static_cast<int> (*current_bind.size);
}
-
- n.version = b.version;
- }
- else
- {
- for (size_t i (0); i < n.count; ++i)
- n.lengths[i] = static_cast<int> (*b.bind[i].size);
}
}
@@ -129,45 +121,42 @@ namespace odb
continue;
}
+ const char* s (PQgetvalue (result, static_cast<int> (row), i));
+
switch (b.type)
{
case bind::smallint:
{
*static_cast<short*> (b.buffer) = endian_traits::ntoh (
- *reinterpret_cast<short*> (
- PQgetvalue (result, static_cast<int> (row), i)));
+ *reinterpret_cast<const short*> (s));
break;
}
case bind::integer:
{
*static_cast<int*> (b.buffer) = endian_traits::ntoh (
- *reinterpret_cast<int*> (
- PQgetvalue (result, static_cast<int> (row), i)));
+ *reinterpret_cast<const int*> (s));
break;
}
case bind::bigint:
{
*static_cast<long long*> (b.buffer) =
- endian_traits::ntoh (*reinterpret_cast<long long*> (
- PQgetvalue (result, static_cast<int> (row), i)));
+ endian_traits::ntoh (*reinterpret_cast<const long long*> (s));
break;
}
case bind::real:
{
*static_cast<float*> (b.buffer) = endian_traits::ntoh (
- *reinterpret_cast<float*> (
- PQgetvalue (result, static_cast<int> (row), i)));
+ *reinterpret_cast<const float*> (s));
break;
}
case bind::double_:
{
*static_cast<double*> (b.buffer) = endian_traits::ntoh (
- *reinterpret_cast<double*> (
- PQgetvalue (result, static_cast<int> (row), i)));
+ *reinterpret_cast<const double*> (s));
break;
}
@@ -188,13 +177,11 @@ namespace odb
continue;
}
- memcpy (b.buffer,
- PQgetvalue (result, static_cast<int> (row), i),
- *b.size);
+ memcpy (b.buffer, s, *b.size);
break;
}
- };
+ }
}
return r;
@@ -221,7 +208,10 @@ namespace odb
: statement (conn, name, stmt, types, types_count),
cond_ (cond),
native_cond_ (native_cond),
- data_ (data)
+ data_ (data),
+ row_count_ (0),
+ current_row_ (0)
+
{
}
@@ -244,28 +234,21 @@ namespace odb
if (!is_good_result (h))
translate_error (conn_, h);
- // Clear the result if it is empty so that fetch () and refetch ()
- // behave correctly.
- //
- else if (PQntuples (h) <= 0)
- result_.reset ();
-
+ row_count_ = static_cast<size_t> (PQntuples (h));
current_row_ = 0;
}
select_statement::result select_statement::
fetch ()
{
- PGresult* h (result_.get ());
-
- if (h == 0)
+ if (current_row_ >= row_count_)
return no_data;
+ PGresult* h (result_.get ());
+
if (bind_result (data_.bind, data_.count, h, current_row_))
{
- if (PQntuples (h) <= static_cast<int> (++current_row_))
- result_.reset ();
-
+ ++current_row_;
return success;
}
@@ -275,7 +258,7 @@ namespace odb
void select_statement::
refetch ()
{
- assert (result_.get () != 0);
+ assert (current_row_ < row_count_);
if (!bind_result (data_.bind,
data_.count,
@@ -342,26 +325,16 @@ namespace odb
translate_error (conn_, h1);
}
- result_ptr r2 (PQexec (conn_.handle (), "select lastval ()"));
+ result_ptr r2 (PQexecParams (conn_.handle (),
+ "select lastval ()",
+ 0, 0, 0, 0, 0, 1));
PGresult* h2 (r2.get ());
if (!is_good_result (h2))
translate_error (conn_, h2);
- const char* s (PQgetvalue (h2, 0, 0));
-
- if (s[0] != '\0' && s[1] == '\0')
- id_ = static_cast<unsigned long long> (s[0] - '0');
- else
- {
- // @@ Using stringstream conversion for now. See if we can optimize
- // this (atoll possibly, even though it is not standard).
- //
- istringstream ss (s);
- ss >> id_;
- }
-
- assert (id_ != 0);
+ id_ = endian_traits::ntoh (*reinterpret_cast<long long*> (
+ PQgetvalue (h2, 0, 0)));
return true;
}
@@ -405,7 +378,7 @@ namespace odb
result_ptr r (PQexecPrepared (conn_.handle (),
name_.c_str (),
- native_data_.count,
+ native_data_.count + native_cond_.count,
native_data_.values,
native_data_.lengths,
native_data_.formats,
diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx
index 4cc98d5..a135643 100644
--- a/odb/pgsql/statement.hxx
+++ b/odb/pgsql/statement.hxx
@@ -124,6 +124,7 @@ namespace odb
binding& data_;
result_ptr result_;
+ std::size_t row_count_;
std::size_t current_row_;
};