aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-10-17 08:59:01 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-10-17 08:59:01 +0200
commit693b99238ad003daa9e79c09fc10bcb0289669c0 (patch)
tree70a2c9e6e17ff61a1a60f8e53dc5a0b2c01e1412
parenta35148a92572c6ad3a4bbd107cf3a14ac464dfac (diff)
Allocate LOB manipulation buffer in connection instance instead of in image
-rw-r--r--odb/oracle/connection.hxx9
-rw-r--r--odb/oracle/oracle-types.hxx8
-rw-r--r--odb/oracle/statement.cxx36
3 files changed, 36 insertions, 17 deletions
diff --git a/odb/oracle/connection.hxx b/odb/oracle/connection.hxx
index 1440c25..12add74 100644
--- a/odb/oracle/connection.hxx
+++ b/odb/oracle/connection.hxx
@@ -15,6 +15,7 @@
#include <odb/connection.hxx>
#include <odb/details/shared-ptr.hxx>
+#include <odb/details/buffer.hxx>
#include <odb/oracle/version.hxx>
#include <odb/oracle/forward.hxx>
@@ -81,6 +82,12 @@ namespace odb
return *statement_cache_;
}
+ details::buffer&
+ lob_buffer ()
+ {
+ return lob_buffer_;
+ }
+
private:
connection (const connection&);
connection& operator= (const connection&);
@@ -96,6 +103,8 @@ namespace odb
auto_handle<OCISvcCtx> handle_;
std::auto_ptr<statement_cache_type> statement_cache_;
+
+ details::buffer lob_buffer_;
};
}
}
diff --git a/odb/oracle/oracle-types.hxx b/odb/oracle/oracle-types.hxx
index 091a6d5..1e48129 100644
--- a/odb/oracle/oracle-types.hxx
+++ b/odb/oracle/oracle-types.hxx
@@ -97,12 +97,12 @@ namespace odb
};
buffer_type type; // The type stored by buffer.
- void* buffer; // Data buffer pointer.
+ void* buffer; // Data buffer pointer. When result callbacks are in
+ // use, this is interpreted as an
+ // auto_descriptor<OCILobLocator>*.
ub2* size; // The number of bytes in buffer. When parameter
// callbacks are in use, this is interpreted as a ub4*
- // indicating the current position. When result
- // callbacks are in use, this is interpreted as an
- // auto_descriptor<OCILobLocator>*.
+ // indicating the current position.
ub4 capacity; // The maximum number of bytes that can be stored in
// buffer.
sb2* indicator; // Pointer to an OCI indicator variable.
diff --git a/odb/oracle/statement.cxx b/odb/oracle/statement.cxx
index ff02f06..2f7311d 100644
--- a/odb/oracle/statement.cxx
+++ b/odb/oracle/statement.cxx
@@ -4,6 +4,7 @@
// license : ODB NCUEL; see accompanying LICENSE file
#include <cassert>
+#include <limits>
#include <oci.h>
@@ -178,7 +179,13 @@ namespace odb
err,
o,
callback ? 0 : b->buffer,
- static_cast<sb4> (b->capacity),
+ // When parameter callbacks are in use, set the
+ // allowable data length to the maximum
+ // possible.
+ //
+ callback
+ ? std::numeric_limits<sb4>::max ()
+ : static_cast<sb4> (b->capacity),
param_sqlt_lookup[b->type],
callback ? 0 : b->indicator,
callback ? 0 : b->size,
@@ -207,6 +214,9 @@ namespace odb
if (callback)
{
+ b->buffer = conn_.lob_buffer ().data ();
+ b->capacity = conn_.lob_buffer ().capacity ();
+
r = OCIBindDynamic (h, err, b, &param_callback_proxy, 0, 0);
if (r == OCI_ERROR || r == OCI_INVALID_HANDLE)
@@ -230,12 +240,12 @@ namespace odb
b->type == bind::clob ||
b->type == bind::nclob)
{
- // When binding a LOB result, the bind::size member is reinterpreted
- // as a pointer to an auto_descriptor<OCILobLocator>. If the
- // descriptor has not yet been allocated, it is allocated now.
+ // When binding a LOB result, the bind::buffer member is
+ // reinterpreted as a pointer to an auto_descriptor<OCILobLocator>.
+ // If the descriptor has not yet been allocated, it is allocated now.
//
auto_descriptor<OCILobLocator>* lob (
- reinterpret_cast<auto_descriptor<OCILobLocator>*> (b->size));
+ reinterpret_cast<auto_descriptor<OCILobLocator>*> (b->buffer));
if (lob->get () == 0)
{
@@ -352,12 +362,8 @@ namespace odb
b->type == bind::nclob) &&
*b->indicator != -1 && b->callback->result != 0)
{
- // If b->capacity is 0, we will be stuck in an infinite loop.
- //
- assert (b->capacity != 0);
-
auto_descriptor<OCILobLocator>& locator (
- *reinterpret_cast<auto_descriptor<OCILobLocator>* > (b->size));
+ *reinterpret_cast<auto_descriptor<OCILobLocator>* > (b->buffer));
ub1 piece (OCI_FIRST_PIECE);
@@ -369,6 +375,10 @@ namespace odb
ub8 read (0);
ub1 cs_form (b->type == bind::nclob ? SQLCS_NCHAR : SQLCS_IMPLICIT);
+ // Allocate buffer space if necessary.
+ //
+ conn_.lob_buffer ().capacity (4096);
+
sword r;
do
{
@@ -378,8 +388,8 @@ namespace odb
&read,
0,
1,
- b->buffer,
- b->capacity,
+ conn_.lob_buffer ().data (),
+ conn_.lob_buffer ().capacity (),
piece,
0,
0,
@@ -404,7 +414,7 @@ namespace odb
// returned from a user callback. We simulate this.
//
if (!(*b->callback->result) (b->context->result,
- b->buffer,
+ conn_.lob_buffer ().data (),
static_cast<ub4> (read),
cp))
throw database_exception (24343, "user defined callback error");