From 80cd8ae9230132ecc4113fac3a4f60f4a94951c1 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 24 Nov 2014 14:54:05 +0200 Subject: Allocate descriptors for batches --- odb/oracle/statement.cxx | 313 ++++++++++++++++++++++++++--------------------- 1 file changed, 171 insertions(+), 142 deletions(-) diff --git a/odb/oracle/statement.cxx b/odb/oracle/statement.cxx index a8ff720..fd2ba83 100644 --- a/odb/oracle/statement.cxx +++ b/odb/oracle/statement.cxx @@ -378,6 +378,11 @@ namespace odb } } + // Unbind is only used in queries which means there should be no + // batches. + // + assert (un == 0 || batch == 1); + if (un != 0) udata_ = new unbind[un]; } @@ -404,186 +409,210 @@ namespace odb { case bind::timestamp: { - datetime* dt (static_cast (b->buffer)); - - if (dt->descriptor == 0) + for (size_t i (0); i != batch; ++i) { - void* d (0); - r = OCIDescriptorAlloc (env, - &d, - OCI_DTYPE_TIMESTAMP, - 0, - 0); + datetime* dt ( + static_cast (offset (b->buffer, i, skip))); - if (r != OCI_SUCCESS) - throw invalid_oci_handle (); - - if (dt->flags & descriptor_cache) - { - dt->descriptor = static_cast (d); - dt->environment = env; - dt->error = err; - } + void* pd (0); // Pointer to descriptor. - // If the datetime instance is not responsible for the - // descriptor, then we have to arrange to have it freed - // using the unbind machinery. - // - if ((dt->flags & descriptor_free) == 0) + if (dt->descriptor == 0) { - unbind& u (udata_[usize_++]); - - u.type = bind::timestamp; - u.bind = (dt->flags & descriptor_cache) ? b : 0; - u.value = d; - value = &u.value; + void* d (0); + r = OCIDescriptorAlloc (env, + &d, + OCI_DTYPE_TIMESTAMP, + 0, + 0); + + if (r != OCI_SUCCESS) + throw invalid_oci_handle (); + + if (dt->flags & descriptor_cache) + { + dt->descriptor = static_cast (d); + dt->environment = env; + dt->error = err; + } + + // If the datetime instance is not responsible for the + // descriptor, then we have to arrange to have it freed + // using the unbind machinery. + // + if ((dt->flags & descriptor_free) == 0) + { + unbind& u (udata_[usize_++]); + + u.type = bind::timestamp; + u.bind = (dt->flags & descriptor_cache) ? b : 0; + u.value = d; + pd = &u.value; + } + else + pd = &dt->descriptor; + + // Initialize the descriptor from the cached data. + // + if (b->indicator == 0 || *b->indicator != -1) + r = OCIDateTimeConstruct (env, + err, + static_cast (d), + dt->year_, + dt->month_, + dt->day_, + dt->hour_, + dt->minute_, + dt->second_, + dt->nanosecond_, + 0, + 0); + + if (r != OCI_SUCCESS) + translate_error (err, r); } else - value = &dt->descriptor; + pd = &dt->descriptor; - // Initialize the descriptor from the cached data. - // - if (b->indicator == 0 || *b->indicator != -1) - r = OCIDateTimeConstruct (env, - err, - static_cast (d), - dt->year_, - dt->month_, - dt->day_, - dt->hour_, - dt->minute_, - dt->second_, - dt->nanosecond_, - 0, - 0); - - if (r != OCI_SUCCESS) - translate_error (err, r); + if (i == 0) + value = pd; } - else - value = &dt->descriptor; capacity = static_cast (sizeof (OCIDateTime*)); - break; } case bind::interval_ym: { - interval_ym* iym (static_cast (b->buffer)); - - if (iym->descriptor == 0) + for (size_t i (0); i != batch; ++i) { - void* d (0); - r = OCIDescriptorAlloc (env, - &d, - OCI_DTYPE_INTERVAL_YM, - 0, - 0); - - if (r != OCI_SUCCESS) - throw invalid_oci_handle (); + interval_ym* iym ( + static_cast (offset (b->buffer, i, skip))); - if (iym->flags & descriptor_cache) - { - iym->descriptor = static_cast (d); - iym->environment = env; - iym->error = err; - } + void* pd (0); // Pointer to descriptor. - // If the interval_ym instance is not responsible for the - // descriptor, then we have to arrange to have it freed - // using the unbind machinery. - // - if ((iym->flags & descriptor_free) == 0) + if (iym->descriptor == 0) { - unbind& u (udata_[usize_++]); - - u.type = bind::interval_ym; - u.bind = (iym->flags & descriptor_cache) ? b : 0; - u.value = d; - value = &u.value; + void* d (0); + r = OCIDescriptorAlloc (env, + &d, + OCI_DTYPE_INTERVAL_YM, + 0, + 0); + + if (r != OCI_SUCCESS) + throw invalid_oci_handle (); + + if (iym->flags & descriptor_cache) + { + iym->descriptor = static_cast (d); + iym->environment = env; + iym->error = err; + } + + // If the interval_ym instance is not responsible for the + // descriptor, then we have to arrange to have it freed + // using the unbind machinery. + // + if ((iym->flags & descriptor_free) == 0) + { + unbind& u (udata_[usize_++]); + + u.type = bind::interval_ym; + u.bind = (iym->flags & descriptor_cache) ? b : 0; + u.value = d; + pd = &u.value; + } + else + pd = &iym->descriptor; + + // Initialize the descriptor from the cached data. + // + if (b->indicator == 0 || *b->indicator != -1) + r = OCIIntervalSetYearMonth (env, + err, + iym->year_, + iym->month_, + static_cast (d)); + + if (r != OCI_SUCCESS) + translate_error (err, r); } else - value = &iym->descriptor; + pd = &iym->descriptor; - // Initialize the descriptor from the cached data. - // - if (b->indicator == 0 || *b->indicator != -1) - r = OCIIntervalSetYearMonth (env, - err, - iym->year_, - iym->month_, - static_cast (d)); - - if (r != OCI_SUCCESS) - translate_error (err, r); + if (i == 0) + value = pd; } - else - value = &iym->descriptor; capacity = static_cast (sizeof (OCIInterval*)); - break; } case bind::interval_ds: { - interval_ds* ids (static_cast (b->buffer)); - - if (ids->descriptor == 0) + for (size_t i (0); i != batch; ++i) { - void* d (0); - r = OCIDescriptorAlloc (env, - &d, - OCI_DTYPE_INTERVAL_DS, - 0, - 0); + interval_ds* ids ( + static_cast (offset (b->buffer, i, skip))); - if (r != OCI_SUCCESS) - throw invalid_oci_handle (); - - if (ids->flags & descriptor_cache) - { - ids->descriptor = static_cast (d); - ids->environment = env; - ids->error = err; - } + void* pd (0); // Pointer to descriptor. - // If the interval_ds instance is not responsible for the - // descriptor, then we have to arrange to have it freed - // using the unbind machinery. - // - if ((ids->flags & descriptor_free) == 0) + if (ids->descriptor == 0) { - unbind& u (udata_[usize_++]); - - u.type = bind::interval_ds; - u.bind = (ids->flags & descriptor_cache) ? b : 0; - u.value = d; - value = &u.value; + void* d (0); + r = OCIDescriptorAlloc (env, + &d, + OCI_DTYPE_INTERVAL_DS, + 0, + 0); + + if (r != OCI_SUCCESS) + throw invalid_oci_handle (); + + if (ids->flags & descriptor_cache) + { + ids->descriptor = static_cast (d); + ids->environment = env; + ids->error = err; + } + + // If the interval_ds instance is not responsible for the + // descriptor, then we have to arrange to have it freed + // using the unbind machinery. + // + if ((ids->flags & descriptor_free) == 0) + { + unbind& u (udata_[usize_++]); + + u.type = bind::interval_ds; + u.bind = (ids->flags & descriptor_cache) ? b : 0; + u.value = d; + pd = &u.value; + } + else + pd = &ids->descriptor; + + // Initialize the descriptor from the cached data. + // + if (b->indicator == 0 || *b->indicator != -1) + r = OCIIntervalSetDaySecond (env, + err, + ids->day_, + ids->hour_, + ids->minute_, + ids->second_, + ids->nanosecond_, + static_cast (d)); + + if (r != OCI_SUCCESS) + translate_error (err, r); } else - value = &ids->descriptor; - - // Initialize the descriptor from the cached data. - // - if (b->indicator == 0 || *b->indicator != -1) - r = OCIIntervalSetDaySecond (env, - err, - ids->day_, - ids->hour_, - ids->minute_, - ids->second_, - ids->nanosecond_, - static_cast (d)); + pd = &ids->descriptor; - if (r != OCI_SUCCESS) - translate_error (err, r); + if (i == 0) + value = pd; } - else - value = &ids->descriptor; capacity = static_cast (sizeof (OCIInterval*)); - break; } case bind::blob: -- cgit v1.1