From 5f78950c5bae2bb0c6228e1596aa51edfd142547 Mon Sep 17 00:00:00 2001 From: Constantin Michael Date: Tue, 11 Oct 2011 09:30:06 +0200 Subject: Use an auto_descriptor pointer to manage a bound result LOB This simplifies resource management in the generated code. --- odb/oracle/oracle-fwd.hxx | 3 +++ odb/oracle/oracle-types.hxx | 3 ++- odb/oracle/statement.cxx | 28 +++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/odb/oracle/oracle-fwd.hxx b/odb/oracle/oracle-fwd.hxx index bc400d1..813414c 100644 --- a/odb/oracle/oracle-fwd.hxx +++ b/odb/oracle/oracle-fwd.hxx @@ -24,6 +24,9 @@ typedef struct OCIStmt OCIStmt; typedef struct OCIAuthInfo OCIAuthInfo; typedef struct OCITrans OCITrans; +typedef struct OCIParam OCIParam; +typedef struct OCILobLocator OCILobLocator; + #include #endif // ODB_ORACLE_ORACLE_FWD_HXX diff --git a/odb/oracle/oracle-types.hxx b/odb/oracle/oracle-types.hxx index 1f2c8a0..33e0f33 100644 --- a/odb/oracle/oracle-types.hxx +++ b/odb/oracle/oracle-types.hxx @@ -10,6 +10,7 @@ #include #include +#include namespace odb { @@ -92,7 +93,7 @@ namespace odb // 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 - // OCILobLocator*. + // auto_descriptor*. 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 5d992b7..ab0068c 100644 --- a/odb/oracle/statement.cxx +++ b/odb/oracle/statement.cxx @@ -207,11 +207,37 @@ 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. + // + auto_descriptor* lob ( + reinterpret_cast*> (b->size)); + + if (lob->get () == 0) + { + OCILobLocator* h (0); + + sword r (OCIDescriptorAlloc (conn_.database ().environment (), + reinterpret_cast (&h), + OCI_DTYPE_LOB, + 0, + 0)); + + // OCIDescriptorAlloc will return OCI_SUCCESS on success, or + // OCI_INVALID_HANDLE on an out-of-memory condition. + // + if (r != OCI_SUCCESS) + throw bad_alloc (); + + lob->reset (h); + } + sword r (OCIDefineByPos (stmt_, &h, err, i, - reinterpret_cast (b->size), + lob, sizeof (OCILobLocator*), sqlt_lookup[b->type], b->indicator, -- cgit v1.1