diff options
-rw-r--r-- | odb/oracle/oracle-fwd.hxx | 3 | ||||
-rw-r--r-- | odb/oracle/oracle-types.hxx | 3 | ||||
-rw-r--r-- | 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 <odb/post.hxx> #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 <odb/oracle/version.hxx> #include <odb/oracle/oracle-fwd.hxx> +#include <odb/oracle/auto-descriptor.hxx> 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<OCILobLocator>*. 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<OCILobLocator>. If the + // descriptor has not yet been allocated, it is allocated now. + // + auto_descriptor<OCILobLocator>* lob ( + reinterpret_cast<auto_descriptor<OCILobLocator>*> (b->size)); + + if (lob->get () == 0) + { + OCILobLocator* h (0); + + sword r (OCIDescriptorAlloc (conn_.database ().environment (), + reinterpret_cast<void**> (&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<OCILobLocator*> (b->size), + lob, sizeof (OCILobLocator*), sqlt_lookup[b->type], b->indicator, |