aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantin Michael <constantin@codesynthesis.com>2011-10-11 09:30:06 +0200
committerConstantin Michael <constantin@codesynthesis.com>2011-10-14 13:12:02 +0200
commit5f78950c5bae2bb0c6228e1596aa51edfd142547 (patch)
tree5783855e491b9bc54381da749259d6a9b2c44913
parent161dc74b596ea0131798e30632acdf3ec5165f9c (diff)
Use an auto_descriptor pointer to manage a bound result LOB
This simplifies resource management in the generated code.
-rw-r--r--odb/oracle/oracle-fwd.hxx3
-rw-r--r--odb/oracle/oracle-types.hxx3
-rw-r--r--odb/oracle/statement.cxx28
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,