aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/pgsql/pgsql-types.hxx7
-rw-r--r--odb/pgsql/statement.cxx129
-rw-r--r--odb/pgsql/statement.hxx3
3 files changed, 56 insertions, 83 deletions
diff --git a/odb/pgsql/pgsql-types.hxx b/odb/pgsql/pgsql-types.hxx
index b872e6d..1001702 100644
--- a/odb/pgsql/pgsql-types.hxx
+++ b/odb/pgsql/pgsql-types.hxx
@@ -23,18 +23,13 @@ namespace odb
//
struct bind
{
- // @@ Initial set of buffer types to support numeric,
- // text, and binary data types.
enum buffer_type
{
smallint, // Buffer is short; size, capacity, truncated are unused.
integer, // Buffer is int; size, capacity, truncated are unused.
bigint, // Buffer is long long; size, capacity, truncated are unused.
real, // Buffer is float; size, capacity, truncated are unused.
- dbl, // Buffer is double; size, capacity, truncated are unused.
-
- // @@ Do we require different buffer types for each of these?
- //
+ double_, // Buffer is double; size, capacity, truncated are unused.
numeric, // Buffer is a char array.
text, // Buffer is a char array.
bytea // Buffer is a char array.
diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx
index ab1f34c..c53fec0 100644
--- a/odb/pgsql/statement.cxx
+++ b/odb/pgsql/statement.cxx
@@ -5,6 +5,7 @@
#include <cstdlib> // std::atol
#include <cassert>
+#include <sstream> // istringstream
#include <odb/exceptions.hxx> // object_not_persistent
@@ -57,32 +58,42 @@ namespace odb
}
void statement::
- bind_param (native_binding& n, const bind* p, size_t c)
+ bind_param (native_binding& n, const binding& b)
{
- assert (n.count == c);
+ assert (n.count == b.count);
- for (size_t i (0); i < c; ++i)
+ if (n.version != b.version)
{
- const bind& b (p[i]);
-
- if (b.is_null != 0 && *b.is_null)
+ for (size_t i (0); i < n.count; ++i)
{
- n.values[i] = 0;
- continue;
- }
+ const bind& current_bind (b.bind[i]);
- n.values[i] = reinterpret_cast<char*> (b.buffer);
+ if (current_bind.is_null != 0 && *current_bind.is_null)
+ {
+ n.values[i] = 0;
+ continue;
+ }
- // Use text format for numeric/decimal types and binary format
- // for all others.
- //
- if (b.type == bind::numeric)
- n.formats[i] = 0;
- else
- {
- n.formats[i] = 1;
- n.lengths[i] = static_cast<int> (*b.size);
+ 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);
+ }
}
+
+ n.version = b.version;
+ }
+ else
+ {
+ for (size_t i (0); i < n.count; ++i)
+ n.lengths[i] = static_cast<int> (*b.bind[i].size);
}
}
@@ -143,7 +154,7 @@ namespace odb
buffer_len = 4;
break;
}
- case bind::dbl:
+ case bind::double_:
{
buffer_len = 8;
break;
@@ -208,18 +219,7 @@ namespace odb
execute ()
{
result_.reset ();
-
- if (cond_.version != native_cond_.version)
- {
- bind_param (native_cond_, cond_.bind, cond_.count);
-
- native_cond_.version = cond_.version;
- }
- else
- {
- for (size_t i (0); i < cond_.count; ++i)
- native_cond_.lengths[i] = static_cast<int> (*cond_.bind[i].size);
- }
+ bind_param (native_cond_, cond_);
result_.reset (PQexecPrepared (conn_.handle (),
name_.c_str (),
@@ -307,17 +307,7 @@ namespace odb
bool insert_statement::
execute ()
{
- if (data_.version != native_data_.version)
- {
- bind_param (native_data_, data_.bind, data_.count);
-
- native_data_.version = data_.version;
- }
- else
- {
- for (size_t i (0); i < data_.count; ++i)
- native_data_.lengths[i] = static_cast<int> (*data_.bind[i].size);
- }
+ bind_param (native_data_, data_);
result_ptr r1 (PQexecPrepared (conn_.handle (),
name_.c_str (),
@@ -350,12 +340,16 @@ namespace odb
const char* s (PQgetvalue (h2, 0, 0));
- // @@ Check types for bigserial.
- //
if (s[0] != '\0' && s[1] == '\0')
id_ = static_cast<unsigned long long> (s[0] - '0');
else
- id_ = static_cast<unsigned long long> (atol (s));
+ {
+ // @@ 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);
@@ -392,23 +386,12 @@ namespace odb
void update_statement::
execute ()
{
- if (cond_.version != native_cond_.version ||
- data_.version != native_data_.version)
- {
- // We assume that cond_.bind is a suffix of data_.bind.
- //
- bind_param (native_data_, data_.bind, data_.count);
-
- native_cond_.version = cond_.version;
- native_data_.version = data_.version;
- }
- else
- {
- // We assume that cond_.bind is a suffix of data_.bind.
- //
- for (size_t i (0); i < data_.count; ++i)
- native_data_.lengths[i] = static_cast<int> (*data_.bind[i].size);
- }
+ // We assume that the values, lengths, and formats members of
+ // native_cond_ are suffixes of the corresponding members of
+ // native_data_.
+ //
+ bind_param (native_data_, data_);
+ bind_param (native_cond_, cond_);
result_ptr r (PQexecPrepared (conn_.handle (),
name_.c_str (),
@@ -456,17 +439,7 @@ namespace odb
unsigned long long delete_statement::
execute ()
{
- if (cond_.version != native_cond_.version)
- {
- bind_param (native_cond_, cond_.bind, cond_.count);
-
- native_cond_.version = cond_.version;
- }
- else
- {
- for (size_t i (0); i < cond_.count; ++i)
- native_cond_.lengths[i] = static_cast<int> (*cond_.bind[i].size);
- }
+ bind_param (native_cond_, cond_);
result_ptr r (PQexecPrepared (conn_.handle (),
name_.c_str (),
@@ -486,7 +459,13 @@ namespace odb
if (s[0] != '\0' && s[1] == '\0')
count = static_cast<unsigned long long> (s[0] - '0');
else
- count = static_cast<unsigned long long> (atol (s));
+ {
+ // @@ Using stringstream conversion for now. See if we can optimize
+ // this (atoll possibly, even though it is not standard).
+ //
+ istringstream ss (s);
+ ss >> count;
+ }
return count;
}
diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx
index e4e29f9..4cc98d5 100644
--- a/odb/pgsql/statement.hxx
+++ b/odb/pgsql/statement.hxx
@@ -51,8 +51,7 @@ namespace odb
//
static void
bind_param (native_binding&,
- const bind*,
- std::size_t count);
+ const binding&);
// Populate an ODB binding given a PostgreSQL result. If the truncated
// argument is true, then only truncated columns are extracted. Return