From 693b99238ad003daa9e79c09fc10bcb0289669c0 Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Mon, 17 Oct 2011 08:59:01 +0200 Subject: Allocate LOB manipulation buffer in connection instance instead of in image --- odb/oracle/connection.hxx | 9 +++++++++ odb/oracle/oracle-types.hxx | 8 ++++---- odb/oracle/statement.cxx | 36 +++++++++++++++++++++++------------- 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 #include +#include #include #include @@ -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 handle_; std::auto_ptr 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*. 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*. + // 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 +#include #include @@ -178,7 +179,13 @@ namespace odb err, o, callback ? 0 : b->buffer, - static_cast (b->capacity), + // When parameter callbacks are in use, set the + // allowable data length to the maximum + // possible. + // + callback + ? std::numeric_limits::max () + : static_cast (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, ¶m_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. 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. + // If the descriptor has not yet been allocated, it is allocated now. // auto_descriptor* lob ( - reinterpret_cast*> (b->size)); + reinterpret_cast*> (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& locator ( - *reinterpret_cast* > (b->size)); + *reinterpret_cast* > (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 (read), cp)) throw database_exception (24343, "user defined callback error"); -- cgit v1.1