aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odb/oracle/oracle-types.cxx38
-rw-r--r--odb/oracle/oracle-types.hxx49
-rw-r--r--odb/oracle/statement.cxx134
3 files changed, 120 insertions, 101 deletions
diff --git a/odb/oracle/oracle-types.cxx b/odb/oracle/oracle-types.cxx
index 9de57cd..9f2ca3e 100644
--- a/odb/oracle/oracle-types.cxx
+++ b/odb/oracle/oracle-types.cxx
@@ -15,6 +15,44 @@ namespace odb
namespace oracle
{
//
+ // lob
+ //
+
+ lob::
+ ~lob ()
+ {
+ if (locator != 0)
+ OCIDescriptorFree (locator, OCI_DTYPE_LOB);
+ }
+
+ lob::
+ lob (lob& x)
+ : locator (x.locator),
+ buffer (x.buffer),
+ position_context (x.position_context)
+ {
+ x.locator = 0;
+ }
+
+ lob& lob::
+ operator= (lob& x)
+ {
+ if (this != &x)
+ {
+ if (locator != 0)
+ OCIDescriptorFree (locator, OCI_DTYPE_LOB);
+
+ locator = x.locator;
+ buffer = x.buffer;
+ position_context = x.position_context;
+
+ x.locator = 0;
+ }
+
+ return *this;
+ }
+
+ //
// datetime
//
diff --git a/odb/oracle/oracle-types.hxx b/odb/oracle/oracle-types.hxx
index 5e08a87..01e5956 100644
--- a/odb/oracle/oracle-types.hxx
+++ b/odb/oracle/oracle-types.hxx
@@ -8,6 +8,8 @@
#include <odb/pre.hxx>
+#include <odb/details/buffer.hxx>
+
#include <odb/oracle/version.hxx>
#include <odb/oracle/oracle-fwd.hxx>
#include <odb/oracle/auto-descriptor.hxx>
@@ -103,11 +105,9 @@ namespace odb
};
buffer_type type; // The type stored by buffer.
- void* buffer; // Data buffer pointer. When result callbacks are in
- // use, this is interpreted as a lob_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. For LOB result
+ void* buffer; // Data buffer pointer. For LOB type bindings, this is
+ // interpreted as an oracle::lob*.
+ ub2* size; // The number of bytes in buffer. For LOB result
// bindings, this is interpreted as the OCIDefine
// handle associated with the LOB result parameter.
ub4 capacity; // The maximum number of bytes that can be stored in
@@ -134,39 +134,22 @@ namespace odb
void* context;
};
+ // The lob structure wraps data required for both parameter and result
+ // LOB type bindings.
//
- // These specialized auto_descriptor classes allows for transparent
- // transferal of descriptors between auto_descriptor instances. This
- // simplifies the implementation of a private copy of the shared image
- // associated with queries.
- //
-
- class LIBODB_ORACLE_EXPORT lob_auto_descriptor:
- public auto_descriptor<OCILobLocator>
+ struct LIBODB_ORACLE_EXPORT lob
{
- typedef auto_descriptor <OCILobLocator> base;
-
- public:
- lob_auto_descriptor (OCILobLocator* l = 0)
- : base (l)
- {
- }
+ lob (): locator (0), buffer (0), position_context (0) {}
- lob_auto_descriptor (lob_auto_descriptor& x)
- : base (x.d_)
- {
- x.d_ = 0;
- }
+ lob (lob&);
+ lob& operator= (lob&);
- lob_auto_descriptor&
- operator= (lob_auto_descriptor& x)
- {
- OCILobLocator* l (x.d_);
- x.d_ = 0;
- reset (l);
+ ~lob ();
- return *this;
- }
+ public:
+ OCILobLocator* locator;
+ details::buffer* buffer;
+ ub4* position_context;
};
//
diff --git a/odb/oracle/statement.cxx b/odb/oracle/statement.cxx
index d056a76..33af160 100644
--- a/odb/oracle/statement.cxx
+++ b/odb/oracle/statement.cxx
@@ -80,9 +80,7 @@ namespace odb
void** indicator)
{
bind& b (*static_cast<bind*> (context));
-
- details::buffer* lob_buffer (
- reinterpret_cast<details::buffer*> (b.buffer));
+ lob* l (static_cast<lob*> (b.buffer));
// Only call the callback if the parameter is not NULL.
//
@@ -90,12 +88,12 @@ namespace odb
{
chunk_position pos;
if (!(*b.callback->param) (b.context->param,
- reinterpret_cast<ub4*> (b.size),
+ l->position_context,
const_cast<const void**> (buffer),
size,
&pos,
- lob_buffer->data (),
- lob_buffer->capacity ()))
+ l->buffer->data (),
+ l->buffer->capacity ()))
return OCI_ERROR;
switch (pos)
@@ -313,7 +311,9 @@ namespace odb
for (ub4 i (1); i < n; ++i, ++b)
{
- void* value (0);
+ void* value;
+ sb4 capacity;
+ ub2* size (0);
bool callback (b->callback != 0);
switch (b->type)
@@ -378,6 +378,8 @@ namespace odb
else
value = &dt->descriptor;
+ capacity = static_cast<sb4> (sizeof (OCIDateTime*));
+
break;
}
case bind::interval_ym:
@@ -433,6 +435,8 @@ namespace odb
else
value = &iym->descriptor;
+ capacity = static_cast<sb4> (sizeof (OCIInterval*));
+
break;
}
case bind::interval_ds:
@@ -491,23 +495,33 @@ namespace odb
else
value = &ids->descriptor;
+ capacity = static_cast<sb4> (sizeof (OCIInterval*));
+
break;
}
case bind::blob:
case bind::clob:
case bind::nclob:
{
- details::buffer& lob_buffer (conn_.lob_buffer ());
+ lob* l (static_cast<lob*> (b->buffer));
+
+ if (l->buffer == 0)
+ {
+ details::buffer& lob_buffer (conn_.lob_buffer ());
- if (lob_buffer.capacity () == 0)
- lob_buffer.capacity (4096);
+ if (lob_buffer.capacity () == 0)
+ lob_buffer.capacity (4096);
- // Generally, we should not modify the binding structure or
- // image since that would break the thread-safety guarantee
- // of the query expression. However, in Oracle, LOBs cannot
- // be used in queries so we can make an exception here.
- //
- b->buffer = &lob_buffer;
+ // Generally, we should not modify the image since that would
+ // break the thread-safety guarantee of the query expression.
+ // However, in Oracle, LOBs cannot be used in queries so we can
+ // make an exception here.
+ //
+ l->buffer = &lob_buffer;
+ }
+
+ assert (callback);
+ value = 0;
// When binding LOB parameters, the capacity must be greater than
// 4000 and less than the maximum LOB length in bytes. If it is
@@ -515,7 +529,7 @@ namespace odb
// to be irrelevant to OCI bind behaviour for LOB parameters when
// used with callbacks.
//
- b->capacity = 4096;
+ capacity = 4096;
break;
}
@@ -530,8 +544,9 @@ namespace odb
assert ((b->type != bind::integer &&
b->type != bind::uinteger) || b->capacity <= 4);
#endif
- if (!callback)
- value = b->buffer;
+ value = callback ? 0 : b->buffer;
+ capacity = static_cast<sb4> (b->capacity);
+ size = b->size;
break;
}
@@ -543,10 +558,10 @@ namespace odb
err,
i,
value,
- static_cast<sb4> (b->capacity),
+ capacity,
param_sqlt_lookup[b->type],
b->indicator,
- b->size,
+ size,
0,
0,
0,
@@ -593,7 +608,8 @@ namespace odb
for (size_t i (1); i <= c; ++i, ++b)
{
- void* value (0);
+ void* value;
+ sb4 capacity;
ub2* size (0);
switch (b->type)
@@ -608,11 +624,7 @@ namespace odb
(dt->flags & descriptor_free));
void* d (0);
- r = OCIDescriptorAlloc (env,
- &d,
- OCI_DTYPE_TIMESTAMP,
- 0,
- 0);
+ r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_TIMESTAMP, 0, 0);
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
@@ -623,6 +635,8 @@ namespace odb
}
value = &dt->descriptor;
+ capacity = static_cast<sb4> (sizeof (OCIDateTime*));
+
break;
}
case bind::interval_ym:
@@ -635,11 +649,7 @@ namespace odb
(iym->flags & descriptor_free));
void* d (0);
- r = OCIDescriptorAlloc (env,
- &d,
- OCI_DTYPE_INTERVAL_YM,
- 0,
- 0);
+ r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_INTERVAL_YM, 0, 0);
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
@@ -650,6 +660,8 @@ namespace odb
}
value = &iym->descriptor;
+ capacity = static_cast<sb4> (sizeof (OCIInterval*));
+
break;
}
case bind::interval_ds:
@@ -662,11 +674,7 @@ namespace odb
(ids->flags & descriptor_free));
void* d (0);
- r = OCIDescriptorAlloc (env,
- &d,
- OCI_DTYPE_INTERVAL_DS,
- 0,
- 0);
+ r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_INTERVAL_DS, 0, 0);
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
@@ -677,16 +685,17 @@ namespace odb
}
value = &ids->descriptor;
+ capacity = static_cast<sb4> (sizeof (OCIInterval*));
+
break;
}
case bind::blob:
case bind::clob:
case bind::nclob:
{
- auto_descriptor<OCILobLocator>* lob (
- static_cast<auto_descriptor<OCILobLocator>*> (b->buffer));
+ lob* l (static_cast<lob*> (b->buffer));
- if (lob->get () == 0)
+ if (l->locator == 0)
{
void* d (0);
r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_LOB, 0, 0);
@@ -694,10 +703,12 @@ namespace odb
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
- lob->reset (static_cast<OCILobLocator*> (d));
+ l->locator = static_cast<OCILobLocator*> (d);
}
- value = &lob->get ();
+ value = &l->locator;
+ capacity = static_cast<sb4> (sizeof (OCILobLocator*));
+
break;
}
default:
@@ -712,6 +723,7 @@ namespace odb
b->capacity <= 4);
#endif
value = b->buffer;
+ capacity = static_cast<sb4> (b->capacity);
size = b->size;
break;
@@ -724,7 +736,7 @@ namespace odb
err,
i,
value,
- static_cast<sb4> (b->capacity),
+ capacity,
result_sqlt_lookup[b->type],
b->indicator,
size,
@@ -794,7 +806,7 @@ namespace odb
for (size_t i (1); i <= c; ++i, ++b)
{
- void* value (0);
+ void* value;
switch (b->type)
{
@@ -805,11 +817,7 @@ namespace odb
if (dt->descriptor == 0)
{
void* d (0);
- r = OCIDescriptorAlloc (env,
- &d,
- OCI_DTYPE_TIMESTAMP,
- 0,
- 0);
+ r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_TIMESTAMP, 0, 0);
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
@@ -827,11 +835,7 @@ namespace odb
if (iym->descriptor == 0)
{
void* d (0);
- r = OCIDescriptorAlloc (env,
- &d,
- OCI_DTYPE_INTERVAL_YM,
- 0,
- 0);
+ r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_INTERVAL_YM, 0, 0);
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
@@ -849,11 +853,7 @@ namespace odb
if (ids->descriptor == 0)
{
void* d (0);
- r = OCIDescriptorAlloc (env,
- &d,
- OCI_DTYPE_INTERVAL_DS,
- 0,
- 0);
+ r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_INTERVAL_DS, 0, 0);
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
@@ -868,10 +868,9 @@ namespace odb
case bind::clob:
case bind::nclob:
{
- auto_descriptor<OCILobLocator>* lob (
- reinterpret_cast<auto_descriptor<OCILobLocator>*> (b->buffer));
+ lob* l (static_cast<lob*> (b->buffer));
- if (lob->get () == 0)
+ if (l->locator == 0)
{
void* d (0);
r = OCIDescriptorAlloc (env, &d, OCI_DTYPE_LOB, 0, 0);
@@ -879,10 +878,10 @@ namespace odb
if (r != OCI_SUCCESS)
throw invalid_oci_handle ();
- lob->reset (static_cast <OCILobLocator*> (d));
+ l->locator = static_cast<OCILobLocator*> (d);
}
- value = &lob->get ();
+ value = &l->locator;
break;
}
default:
@@ -903,7 +902,7 @@ namespace odb
err,
i,
value,
- static_cast<sb4> (b->capacity),
+ static_cast<sb4> (sizeof (void*)),
result_sqlt_lookup[b->type],
b->indicator,
0,
@@ -961,8 +960,7 @@ namespace odb
(b->indicator == 0 || *b->indicator != -1) &&
b->callback->result != 0)
{
- auto_descriptor<OCILobLocator>& locator (
- *reinterpret_cast<auto_descriptor<OCILobLocator>*> (b->buffer));
+ lob* l (static_cast<lob*> (b->buffer));
ub4 position (0); // Position context.
ub1 piece (OCI_FIRST_PIECE);
@@ -987,7 +985,7 @@ namespace odb
{
r = OCILobRead2 (conn_.handle (),
err,
- locator,
+ l->locator,
&read,
0,
1,