OCILIB (C Driver for Oracle) 3.9.2
D:/Perso/dev/ocilib/ocilib/src/statement.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: statement.c, v 3.9.2 2011-07-13 00:00 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_BindFreeAll
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 boolean OCI_BindFreeAll
00046 (
00047     OCI_Statement *stmt
00048 )
00049 {
00050     int i;
00051 
00052     OCI_CHECK(stmt == NULL, FALSE);
00053 
00054     /* free user binds */
00055 
00056     if (stmt->ubinds != NULL)
00057     {
00058         for(i = 0; i < stmt->nb_ubinds; i++)
00059         {
00060             OCI_BindFree(stmt->ubinds[i]);
00061         }
00062 
00063         OCI_FREE(stmt->ubinds);
00064     }
00065 
00066     /* free register binds */
00067 
00068     if (stmt->rbinds != NULL)
00069     {
00070         for(i = 0; i < stmt->nb_rbinds; i++)
00071         {
00072             OCI_BindFree(stmt->rbinds[i]);
00073         }
00074 
00075         OCI_FREE(stmt->rbinds);
00076     }
00077 
00078     stmt->nb_ubinds = 0;
00079     stmt->nb_rbinds = 0;
00080 
00081     return TRUE;
00082 }
00083 
00084 /* --------------------------------------------------------------------------------------------- *
00085  * OCI_BindCheck
00086  * --------------------------------------------------------------------------------------------- */
00087 
00088 boolean OCI_BindCheck
00089 (
00090     OCI_Statement *stmt
00091 )
00092 {
00093     boolean res   = TRUE;
00094     OCI_Bind *bnd = NULL;
00095     sb2 *ind      = NULL;
00096     ub4 i, j;
00097 
00098     OCI_CHECK(stmt == NULL, FALSE)
00099     OCI_CHECK(stmt->ubinds == NULL, TRUE);
00100 
00101     for(i = 0; i < stmt->nb_ubinds; i++)
00102     {
00103         bnd = stmt->ubinds[i];
00104         ind = (sb2 *) bnd->buf.inds;
00105 
00106         if (bnd->type == OCI_CDT_CURSOR)
00107         {
00108             OCI_Statement *bnd_stmt = (OCI_Statement *) bnd->buf.data;
00109 
00110             OCI_StatementReset(bnd_stmt);
00111 
00112             bnd_stmt->hstate = OCI_OBJECT_ALLOCATED_BIND_STMT;
00113         
00114             /* allocate stmt handle */
00115 
00116             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) bnd_stmt->con->env,
00117                                                   (dvoid **) (void *) &bnd_stmt->stmt,
00118                                                   (ub4) OCI_HTYPE_STMT,
00119                                                   (size_t) 0, (dvoid **) NULL));
00120 
00121             if (res == TRUE)
00122             {
00123                 ub4 size = 0;
00124 
00125                 size = bnd_stmt->prefetch_size ? bnd_stmt->prefetch_size : OCI_PREFETCH_SIZE;
00126                 res  = (res && OCI_SetPrefetchSize(bnd_stmt, size));
00127                 
00128                 size = bnd_stmt->fetch_size ? bnd_stmt->fetch_size : OCI_FETCH_SIZE;
00129                 res  = (res && OCI_SetFetchSize(bnd_stmt, size));
00130             }
00131         }
00132 
00133         if (bnd->direction & OCI_BDM_IN)
00134         {
00135             /* for strings, re-initialize length array with buffer default size */
00136 
00137             if (bnd->type == OCI_CDT_TEXT)
00138             {
00139                 unsigned int i;
00140 
00141                 for (i=0; i < bnd->buf.count; i++)
00142                 {
00143                     *(ub2*)(((ub1 *)bnd->buf.lens) + (sizeof(ub2) * (size_t) i)) = (ub2) bnd->size;
00144                 }
00145             }
00146 
00147             /* extra work for internal allocated binds buffers */
00148 
00149             if (bnd->is_array == FALSE)
00150             {
00151                 /* - For big integer (64 bits), we use an OCINumber.
00152 
00153                    - Oracle date/time type is the only non scalar type
00154                      implemented by oracle through a public structure instead
00155                      of using a handle. So we need to copy the value
00156                 */
00157 
00158                 if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00159                 {
00160                     res = OCI_NumberSet(stmt->con,
00161                                         (OCINumber *) bnd->buf.data,
00162                                         (void *) bnd->input,
00163                                         (uword) sizeof(big_int),
00164                                         bnd->subtype);
00165                 }
00166                 else if (bnd->alloc == TRUE)
00167                 {
00168                     if (bnd->type == OCI_CDT_DATETIME)
00169                     {
00170                         if (bnd->input != NULL)
00171                         {
00172                             memcpy((void *) bnd->buf.data,
00173                                    ((OCI_Date *) bnd->input)->handle, sizeof(OCIDate));
00174                         }
00175                     }
00176 
00177                 #ifdef OCI_CHECK_DATASTRINGS
00178 
00179                     else if (bnd->type == OCI_CDT_TEXT)
00180                     {
00181                         /* need conversion if bind buffer was allocated */
00182 
00183                         int osize = -1;
00184 
00185                         OCI_GetOutputString(bnd->input, bnd->buf.data, &osize,
00186                                             sizeof(dtext), sizeof(odtext));
00187                     }
00188 
00189                 #endif
00190 
00191                     else
00192                     {
00193                         if (bnd->input != NULL)
00194                         {
00195                             bnd->buf.data[0] = ((OCI_Datatype *) bnd->input)->handle;
00196                         }
00197                     }
00198                 }
00199 
00200                 /* for handles, check anyway the value for null data */
00201 
00202                 if ((bnd->type != OCI_CDT_NUMERIC) &&
00203                     (bnd->type != OCI_CDT_TEXT   ) &&
00204                     (bnd->type != OCI_CDT_RAW    ))
00205                 {
00206                     if (ind != NULL && *ind != -1)
00207                     {
00208                         *ind = OCI_IND(bnd->buf.data);
00209                     }
00210                 }
00211 
00212                 /* update bind object indicator pointer with object indicator */
00213 
00214                 if (bnd->type == OCI_CDT_OBJECT)
00215                 {
00216                     bnd->buf.obj_inds[0] = ((OCI_Object *) bnd->input)->tab_ind;
00217                 }
00218 
00219                 if (res == FALSE)
00220                 {
00221                     break;
00222                 }
00223             }
00224             else
00225             {
00226                 for (j = 0; j < bnd->buf.count; j++, ind++)
00227                 {
00228 
00229                     /* - For big integer (64 bits), we use an OCINumber.
00230 
00231                        - Oracle date/time type is the only non scalar type
00232                          implemented by oracle through a public structure instead
00233                          of using a handle. So we need to copy the value
00234                     */
00235 
00236                     if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00237                     {
00238 
00239                         res = OCI_NumberSet(stmt->con,
00240                                             (OCINumber *) ((ub1 *) bnd->buf.data +
00241                                             (size_t) (j*bnd->size)),
00242                                             (void *) (((ub1 *) bnd->input) +
00243                                             (((size_t)j)*sizeof(big_int))),
00244                                             (uword) sizeof(big_int), bnd->subtype);
00245                     }
00246                     else if (bnd->alloc == TRUE)
00247                     {
00248                         if (bnd->type == OCI_CDT_DATETIME)
00249                         {
00250                             if (bnd->input[j] != NULL)
00251                             {
00252                                 memcpy(((ub1 *) bnd->buf.data) + (size_t) (j*bnd->size),
00253                                        ((OCI_Date *) bnd->input[j])->handle, sizeof(OCIDate));
00254                             }
00255                         }
00256 
00257                     #ifdef OCI_CHECK_DATASTRINGS
00258 
00259                         else if (bnd->type == OCI_CDT_TEXT)
00260                         {
00261                             /* need conversion if bind buffer was allocated */
00262 
00263                             int osize   = -1;
00264                             int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
00265                             int offset2 = bnd->size;
00266 
00267                             OCI_GetOutputString(((ub1 *) bnd->input)    + (j*offset1),
00268                                                 ((ub1 *) bnd->buf.data) + (j*offset2),
00269                                                 &osize, sizeof(dtext), sizeof(odtext));
00270 
00271                             /* set zero terminal null character */
00272 
00273                             {
00274                                 odtext *str = (odtext *) (((ub1 *) bnd->buf.data) + (j*offset2));
00275 
00276                                 if (osize> 0)
00277                                 {
00278                                     str[osize/sizeof(odtext)] = 0;
00279                                 }
00280                                 else
00281                                 {
00282                                     str[0] = 0;
00283                                 }
00284                             }
00285                         }
00286 
00287                     #endif
00288 
00289                         else
00290                         {
00291                             if (bnd->input[j] != NULL)
00292                             {
00293                                 bnd->buf.data[j] = ((OCI_Datatype *) bnd->input[j])->handle;
00294                             }
00295                         }
00296                     }
00297 
00298                     /* for handles, check anyway the value for null data */
00299 
00300                     if ((bnd->type != OCI_CDT_NUMERIC) &&
00301                         (bnd->type != OCI_CDT_TEXT   ) &&
00302                         (bnd->type != OCI_CDT_RAW    ))
00303                     {
00304                         if (ind != NULL && *ind != -1)
00305                         {
00306                             *ind = OCI_IND((((OCI_Datatype *) bnd->input[j])->handle));
00307                         }
00308                     }
00309 
00310                     /* update bind object indicator pointer with object indicator */
00311 
00312                     if (bnd->type == OCI_CDT_OBJECT)
00313                     {
00314                         bnd->buf.obj_inds[j] = ((OCI_Object *) bnd->input[j])->tab_ind;
00315                     }
00316 
00317                     if (res == FALSE)
00318                     {
00319                         break;
00320                     }
00321                 }
00322             }
00323         }
00324     }
00325 
00326     return res;
00327 }
00328 
00329 /* --------------------------------------------------------------------------------------------- *
00330  * OCI_BindReset
00331  * --------------------------------------------------------------------------------------------- */
00332 
00333 boolean OCI_BindReset
00334 (
00335     OCI_Statement *stmt
00336 )
00337 {
00338     ub4 i, j;
00339     boolean res = TRUE;
00340 
00341     OCI_CHECK(stmt == NULL, FALSE)
00342     OCI_CHECK(stmt->ubinds == NULL, FALSE);
00343 
00344     /* avoid unused param warning from compiler */
00345 
00346     i = j = 0;
00347 
00348     for(i = 0; i < stmt->nb_ubinds; i++)
00349     {
00350         OCI_Bind *bnd = stmt->ubinds[i];
00351 
00352         if (bnd->type == OCI_CDT_CURSOR)
00353         {
00354             OCI_Statement *bnd_stmt = (OCI_Statement *) bnd->buf.data;
00355 
00356             bnd_stmt->status = OCI_STMT_PREPARED  | OCI_STMT_PARSED | 
00357                                OCI_STMT_DESCRIBED | OCI_STMT_EXECUTED;
00358 
00359             bnd_stmt->type   = OCI_CST_SELECT;
00360         }
00361 
00362         if (bnd->direction & OCI_BDM_OUT)
00363         {
00364             /* only reset bind indicators if bind was not a PL/SQL bind
00365                that can have oupout values
00366             */
00367 
00368             if (stmt->type != OCI_CST_BEGIN && stmt->type != OCI_CST_DECLARE)
00369             {
00370                 memset(bnd->buf.inds, 0, ((size_t) bnd->buf.count) * sizeof(sb2));
00371             }
00372             else
00373             {
00374                 /* extra work for internal allocated binds buffers with PL/SQL */
00375 
00376                 if (bnd->is_array == FALSE)
00377                 {
00378                     /* - For big integer (64 bits), we use an OCINumber.
00379 
00380                        - Oracle date/time type is the only non scalar type
00381                          implemented by oracle through a public structure instead
00382                          of using a handle. So we need to copy the value
00383                     */
00384 
00385                     if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00386                     {
00387                         res = OCI_NumberGet(stmt->con,
00388                                             (OCINumber *) bnd->buf.data,
00389                                             (void *) bnd->input,
00390                                             (uword) sizeof(big_int),
00391                                             bnd->subtype);
00392                     }
00393                     else if (bnd->alloc == TRUE)
00394                     {
00395 
00396                         if (bnd->type == OCI_CDT_DATETIME)
00397                         {
00398                             if (bnd->input != NULL)
00399                             {
00400                                 memcpy(((OCI_Date *) bnd->input)->handle,
00401                                        (void *) bnd->buf.data, sizeof(OCIDate));
00402                             }
00403                         }
00404 
00405                         /* update object indicator with bind object indicator
00406                          *pointer */
00407 
00408                         if (bnd->type == OCI_CDT_OBJECT)
00409                         {
00410                             if (bnd->input != NULL)
00411                             {
00412                                 ((OCI_Object *) bnd->input)->tab_ind = bnd->buf.obj_inds[0];
00413                             }
00414                         }
00415                     }
00416                 }
00417                 else
00418                 {
00419                     for (j = 0; j < bnd->buf.count; j++)
00420                     {
00421 
00422                         /* - For big integer (64 bits), we use an OCINumber.
00423 
00424                            - Oracle date/time type is the only non scalar type
00425                              implemented by oracle through a public structure instead
00426                              of using a handle. So we need to copy the value
00427                         */
00428 
00429                         if ((bnd->type == OCI_CDT_NUMERIC) && (bnd->code == SQLT_VNU))
00430                         {
00431 
00432                             res = OCI_NumberGet(stmt->con,
00433                                                 (OCINumber *) ((ub1 *) bnd->buf.data +
00434                                                 (size_t) (j*bnd->size)),
00435                                                 (void *) (((ub1 *) bnd->input) +
00436                                                 (((size_t)j)*sizeof(big_int))),
00437                                                 (uword) sizeof(big_int), bnd->subtype);
00438                         }
00439                         else if (bnd->alloc == TRUE)
00440                         {
00441                             if (bnd->type == OCI_CDT_DATETIME)
00442                             {
00443                                 if (bnd->input[j] != NULL)
00444                                 {
00445                                     memcpy(((OCI_Date *) bnd->input[j])->handle,
00446                                            ((ub1 *) bnd->buf.data) + (size_t) (j*bnd->size),
00447                                            sizeof(OCIDate));
00448                                 }
00449                             }
00450 
00451                             /* update bind object indicator pointer with object
00452                              *indicator */
00453 
00454                             if (bnd->type == OCI_CDT_OBJECT)
00455                             {
00456                                 if (bnd->input != NULL)
00457                                 {
00458                                     ((OCI_Object *) bnd->input[j])->tab_ind = bnd->buf.obj_inds[j];
00459                                 }
00460                             }
00461                         }
00462                     }
00463                 }
00464             }
00465 
00466         #ifdef OCI_CHECK_DATASTRINGS
00467 
00468             if (bnd->type == OCI_CDT_TEXT)
00469             {
00470                 for (j = 0; j < bnd->buf.count; j++)
00471                 {
00472                     /* need conversion if bind buffer was allocated */
00473 
00474                     int osize   = -1;
00475                     int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
00476                     int offset2 = bnd->size;
00477 
00478                     if (bnd->buf.lens != NULL)
00479                     {
00480                         osize = (int) ((ub2 *) bnd->buf.lens)[j];
00481                     }
00482 
00483                     if (bnd->size == (sb4) osize)
00484                     {
00485                         osize -= sizeof(odtext);
00486                     }
00487 
00488                     OCI_GetOutputString(((ub1 *) bnd->buf.data) + (j*offset2),
00489                                         ((ub1 *) bnd->input)    + (j*offset1),
00490                                         &osize, sizeof(odtext), sizeof(dtext));
00491 
00492                     /* set zero terminal null character (sometimes it is not set
00493                        by OCI and causes problems if the string has been modified
00494                        and its length reduced */
00495 
00496                     {
00497                         dtext *str = (dtext *) (((ub1 *) bnd->input) + (j*offset1));
00498 
00499                         if (osize> 0)
00500                         {
00501                             str[osize/sizeof(dtext)] = 0;
00502                         }
00503                     }
00504                 }
00505             }
00506             
00507         #endif
00508 
00509         }
00510     }
00511 
00512     return res;
00513 }
00514 
00515 /* --------------------------------------------------------------------------------------------- *
00516  * OCI_BindData
00517  * --------------------------------------------------------------------------------------------- */
00518 
00519 boolean OCI_BindData
00520 (
00521     OCI_Statement *stmt,
00522     void          *data,
00523     ub4            size,
00524     const mtext   *name,
00525     ub1            type,
00526     unsigned int   code,
00527     unsigned int   mode,
00528     unsigned int   subtype,
00529     OCI_TypeInfo  *typinf,
00530     unsigned int   nbelem
00531 )
00532 {
00533     boolean res      = TRUE;
00534     OCI_Bind *bnd    = NULL;
00535     ub4 exec_mode    = OCI_DEFAULT;
00536     boolean is_pltbl = FALSE;
00537     boolean is_array = FALSE;
00538     boolean reused   = FALSE;
00539     ub4 *pnbelem     = NULL;
00540     int index        = 0;
00541     int prev_index   = -1;
00542     size_t nballoc   = (size_t) nbelem;
00543 
00544     /* check index if necessary */
00545 
00546     if (res == TRUE)
00547     {
00548         if (stmt->bind_mode == OCI_BIND_BY_POS)
00549         {
00550             index = (int) mtstol(&name[1], NULL, 10);
00551 
00552             if (index <= 0 || index > OCI_BIND_MAX)
00553             {
00554                 OCI_ExceptionOutOfBounds(stmt->con, index);
00555                 res = FALSE;
00556             }
00557         }
00558     }
00559 
00560     /* check if the bind name has already been used */
00561 
00562     if (res == TRUE)
00563     {
00564         if (mode == OCI_BIND_INPUT)
00565         {
00566             prev_index = OCI_BindGetIndex(stmt, name);
00567 
00568             if (prev_index > 0)
00569             {
00570                 if (stmt->bind_reuse == FALSE)
00571                 {
00572                     OCI_ExceptionBindAlreadyUsed(stmt, name);
00573                     res = FALSE;
00574                 }
00575                 else
00576                 {
00577                     bnd = stmt->ubinds[prev_index-1];
00578 
00579                     if (bnd->type != type)
00580                     {
00581                         OCI_ExceptionRebindBadDatatype(stmt, name);
00582                         res = FALSE;
00583                     }
00584                     else
00585                     {
00586                         reused = TRUE;
00587                     }
00588                 }
00589 
00590                 index = prev_index;
00591             }
00592         }
00593     }
00594 
00595     /* check if we can handle another bind */
00596 
00597     if (res == TRUE)
00598     {
00599         if (mode == OCI_BIND_INPUT)
00600         {
00601             if (stmt->nb_ubinds >= OCI_BIND_MAX)
00602             {
00603                 OCI_ExceptionMaxBind(stmt);
00604                 res = FALSE;
00605             }
00606 
00607             /* allocate user bind array if necessary */
00608 
00609             if (stmt->ubinds == NULL)
00610             {
00611                 stmt->ubinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
00612                                                           sizeof(*stmt->ubinds),
00613                                                           (size_t) OCI_BIND_MAX,
00614                                                           TRUE);
00615             }
00616 
00617             res = (stmt->ubinds != NULL);
00618         }
00619         else
00620         {
00621             if (stmt->nb_rbinds >= OCI_BIND_MAX)
00622             {
00623                 OCI_ExceptionMaxBind(stmt);
00624                 res = FALSE;
00625             }
00626 
00627             /* allocate register bind array if necessary */
00628 
00629             if (stmt->rbinds == NULL)
00630             {
00631                 stmt->rbinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
00632                                                           sizeof(*stmt->rbinds),
00633                                                           (size_t) OCI_BIND_MAX,
00634                                                           TRUE);
00635             }
00636 
00637             res = (stmt->rbinds != NULL);
00638         }
00639     }
00640 
00641     /* checks done */
00642 
00643     if (res == TRUE)
00644     {
00645         /* check out the number of elements that the bind variable will hold */
00646 
00647         if (nbelem > 0)
00648         {
00649             /* is it a pl/sql table bind ? */
00650 
00651             if (stmt->type == OCI_CST_BEGIN || stmt->type == OCI_CST_DECLARE)
00652             {
00653                 is_pltbl = TRUE;
00654                 is_array = TRUE;
00655             }
00656         }
00657         else
00658         {
00659             nbelem   = stmt->nb_iters;
00660             is_array = stmt->bind_array;
00661         }
00662     }
00663 
00664     if (res == TRUE)
00665     {
00666         if (nballoc < stmt->nb_iters_init)
00667         {
00668             nballoc = (size_t) stmt->nb_iters_init;
00669         }
00670     }
00671 
00672     /* create hash table for mapping bind names / index */
00673 
00674     if (res == TRUE)
00675     {
00676         if (stmt->map == NULL)
00677         {
00678             stmt->map = OCI_HashCreate(OCI_HASH_DEFAULT_SIZE, OCI_HASH_INTEGER);
00679 
00680             res = (stmt->map != NULL);
00681         }
00682     }
00683 
00684     /* allocate bind object */
00685 
00686     if (res == TRUE)
00687     {
00688         if (bnd == NULL)
00689         {
00690             bnd = (OCI_Bind *) OCI_MemAlloc(OCI_IPC_BIND, sizeof(*bnd), (size_t) 1, TRUE);
00691         }
00692 
00693         res = (bnd != NULL);
00694     }
00695 
00696     /* allocate indicators array */
00697 
00698     if (res == TRUE)
00699     {
00700         if (bnd->buf.inds == NULL)
00701         {
00702             bnd->buf.inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
00703                                                   sizeof(sb2), nballoc, TRUE);
00704         }
00705 
00706         res = (bnd->buf.inds != NULL);
00707     }
00708 
00709     /* allocate object indicators pointer array */
00710 
00711     if (res == TRUE)
00712     {
00713         if ((type == OCI_CDT_OBJECT) && (bnd->buf.obj_inds == NULL))
00714         {
00715             bnd->buf.obj_inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
00716                                                       sizeof(void *), nballoc, TRUE);
00717 
00718             res = (bnd->buf.obj_inds != NULL);
00719         }
00720     }
00721 
00722     /* check need for PL/SQL table extra info */
00723 
00724     if ((res == TRUE) && (is_pltbl == TRUE))
00725     {
00726         bnd->nbelem = nbelem;
00727         pnbelem     = &bnd->nbelem;
00728 
00729         /* allocate array of returned codes */
00730 
00731         if (res == TRUE)
00732         {
00733             if (bnd->plrcds == NULL)
00734             {
00735                 bnd->plrcds = (ub2 *) OCI_MemAlloc(OCI_IPC_PLS_RCODE_ARRAY,
00736                                                    sizeof(ub2), nballoc, TRUE);
00737             }
00738 
00739             res = (bnd->plrcds != NULL);
00740         }
00741     }
00742 
00743     /* for handle based datatypes, we need to allocate an array of handles for
00744        bind calls because OCILIB uses external arrays of OCILIB Objects */
00745 
00746     if ((res == TRUE) && (mode == OCI_BIND_INPUT))
00747     {
00748         if (stmt->bind_alloc_mode == OCI_BAM_EXTERNAL)
00749         {
00750             if (type != OCI_CDT_RAW      &&
00751                 type != OCI_CDT_LONG     &&
00752                 type != OCI_CDT_CURSOR   &&
00753 
00754             #ifndef OCI_CHECK_DATASTRINGS
00755 
00756                 type != OCI_CDT_TEXT     &&
00757 
00758             #endif
00759 
00760                 (type != OCI_CDT_NUMERIC || code == SQLT_VNU)
00761                 )
00762             {
00763                 bnd->alloc = TRUE;
00764 
00765                 if ((reused == TRUE) && (bnd->buf.data != NULL) && (bnd->size != (sb4) size))
00766                 {
00767                     OCI_FREE(bnd->buf.data);
00768                 }
00769 
00770                 if (bnd->buf.data == NULL)
00771                 {
00772                     bnd->buf.data = (void **) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY, (size_t) size,
00773                                                            (size_t) nballoc, TRUE);
00774                 }
00775 
00776                 res = (bnd->buf.data != NULL);
00777             }
00778             else
00779             {
00780                 bnd->buf.data = (void **) data;
00781             }
00782         }
00783     }
00784 
00785     /* setup data length array */
00786 
00787     if ((res == TRUE) && ((type == OCI_CDT_RAW) || (type == OCI_CDT_TEXT)))
00788     {
00789         if (bnd->buf.lens == NULL)
00790         {
00791             bnd->buf.lens = (void *) OCI_MemAlloc(OCI_IPC_LEN_ARRAY, sizeof(ub2), nballoc, TRUE);
00792         }
00793 
00794         res = (bnd->buf.lens != NULL);
00795 
00796         /* initialize length array with buffer default size */
00797 
00798         if (res == TRUE)
00799         {
00800             unsigned int i;
00801 
00802             for (i=0; i < nbelem; i++)
00803             {
00804                 *(ub2*)(((ub1 *)bnd->buf.lens) + sizeof(ub2) * (size_t) i) = (ub2) size;
00805             }
00806         }
00807     }
00808 
00809     /* initialize bind object */
00810 
00811     if (res == TRUE)
00812     {
00813         /* initialize bind attributes */
00814 
00815         bnd->stmt      = stmt;
00816         bnd->input     = (void **) data;
00817         bnd->type      = type;
00818         bnd->size      = size;
00819         bnd->code      = (ub2) code;
00820         bnd->subtype   = (ub1) subtype;
00821         bnd->is_array  = is_array;
00822         bnd->csfrm     = OCI_CSF_NONE;
00823         bnd->direction = OCI_BDM_IN_OUT;
00824 
00825         if (bnd->name == NULL)
00826         {
00827             bnd->name = mtsdup(name);
00828         }
00829 
00830         /* initialize buffer */
00831 
00832         bnd->buf.count   = nbelem;
00833         bnd->buf.sizelen = sizeof(ub2);
00834 
00835         /* internal allocation if needed */
00836 
00837         if ((data == NULL) && (stmt->bind_alloc_mode == OCI_BAM_INTERNAL))
00838         {
00839             res = OCI_BindAllocData(bnd);
00840         }
00841 
00842         /* if we bind an OCI_Long or any output bind, we need to change the
00843            execution mode to provide data at execute time */
00844 
00845         if (bnd->type == OCI_CDT_LONG)
00846         {
00847             stmt->long_size = size;
00848             exec_mode       = OCI_DATA_AT_EXEC;
00849         }
00850         else if (mode == OCI_BIND_OUTPUT)
00851         {
00852             exec_mode = OCI_DATA_AT_EXEC;
00853         }
00854     }
00855 
00856     /* OCI binding */
00857 
00858     if (res == TRUE)
00859     {
00860         if (stmt->bind_mode == OCI_BIND_BY_POS)
00861         {
00862             OCI_CALL1
00863             (
00864                 res, stmt->con, stmt,
00865 
00866                 OCIBindByPos(stmt->stmt, (OCIBind **) &bnd->buf.handle,
00867                              stmt->con->err, (ub4) index, (void *) bnd->buf.data,
00868                              bnd->size, bnd->code, bnd->buf.inds,  bnd->buf.lens,
00869                              bnd->plrcds, (ub4) (is_pltbl == TRUE ? nbelem : 0),
00870                              pnbelem, exec_mode)
00871             )
00872         }
00873         else
00874         {
00875             void * ostr = NULL;
00876             int osize   = -1;
00877 
00878             ostr = OCI_GetInputMetaString(bnd->name, &osize);
00879 
00880             OCI_CALL1
00881             (
00882                 res, stmt->con, stmt,
00883 
00884                 OCIBindByName(stmt->stmt, (OCIBind **) &bnd->buf.handle,
00885                               stmt->con->err, (OraText *) ostr, (sb4) osize,
00886                               (void *) bnd->buf.data, bnd->size, bnd->code,
00887                               bnd->buf.inds, bnd->buf.lens, bnd->plrcds,
00888                               (ub4) (is_pltbl == TRUE ? nbelem : 0),
00889                               pnbelem, exec_mode)
00890             )
00891 
00892             OCI_ReleaseMetaString(ostr);
00893         }
00894 
00895         if (code == SQLT_NTY || code == SQLT_REF)
00896         {
00897             OCI_CALL1
00898             (
00899                 res, stmt->con, stmt,
00900 
00901                 OCIBindObject((OCIBind *) bnd->buf.handle, stmt->con->err,
00902                               (OCIType *) typinf->tdo, (void **) bnd->buf.data,
00903                               (ub4 *) NULL, (void **) bnd->buf.obj_inds,
00904                               (ub4 *) bnd->buf.inds)
00905             )
00906         }
00907 
00908         if (mode == OCI_BIND_OUTPUT)
00909         {
00910             /* register output placeholder */
00911 
00912             OCI_CALL1
00913             (
00914                 res, stmt->con, stmt,
00915 
00916                 OCIBindDynamic((OCIBind *) bnd->buf.handle, stmt->con->err,
00917                                (dvoid *) bnd, OCI_ProcInBind,
00918                                (dvoid *) bnd, OCI_ProcOutBind)
00919             )
00920         }
00921     }
00922 
00923     /* set charset form */
00924 
00925     if (res == TRUE)
00926     {
00927         if ((bnd->type == OCI_CDT_LOB) && (bnd->subtype == OCI_NCLOB))
00928         {
00929             ub1 csfrm = SQLCS_NCHAR;
00930 
00931             OCI_CALL1
00932             (
00933                 res, bnd->stmt->con, bnd->stmt,
00934 
00935                 OCIAttrSet((dvoid *) bnd->buf.handle,
00936                            (ub4    ) OCI_HTYPE_BIND,
00937                            (dvoid *) &csfrm,
00938                            (ub4    ) sizeof(csfrm),
00939                            (ub4    ) OCI_ATTR_CHARSET_FORM,
00940                            bnd->stmt->con->err)
00941             )
00942         }
00943     }
00944 
00945     /* set charset ID */
00946 
00947     if (res == TRUE)
00948     {
00949         if ((bnd->type == OCI_CDT_TEXT)  ||
00950             ((bnd->type == OCI_CDT_LOB)   && (bnd->subtype != OCI_BLOB))  ||
00951             ((bnd->type == OCI_CDT_LONG)  && (bnd->subtype != OCI_BLONG)))
00952         {
00953 
00954         #ifdef OCI_CHARSET_MIXED
00955 
00956             /* setup Unicode mode for user data on mixed builds */
00957             {
00958                 ub2 csid = OCI_UTF16ID;
00959 
00960                 OCI_CALL1
00961                 (
00962                     res, bnd->stmt->con, bnd->stmt,
00963 
00964                     OCIAttrSet((dvoid *) bnd->buf.handle,
00965                                (ub4    ) OCI_HTYPE_BIND,
00966                                (dvoid *) &csid,
00967                                (ub4    ) sizeof(csid),
00968                                (ub4    ) OCI_ATTR_CHARSET_ID,
00969                                bnd->stmt->con->err)
00970                 )
00971             }
00972 
00973         #endif
00974 
00975         }
00976     }
00977 
00978 /*
00979     this call was removed in v3.6.0
00980     It will be restored in future version, but need more testing on all builds
00981 
00982     if (bnd->type == OCI_CDT_TEXT)
00983     {
00984         OCI_CALL1
00985         (
00986             res, stmt->con, stmt,
00987 
00988             OCIAttrSet((dvoid *) bnd->buf.handle, (ub4) OCI_HTYPE_BIND,
00989                        (dvoid *) &bnd->size, (ub4) sizeof(bnd->size),
00990                        (ub4) OCI_ATTR_MAXDATA_SIZE,  bnd->stmt->con->err)
00991         )
00992     }
00993 */
00994 
00995     /* on success, we :
00996          - add the bind handle to the bind array
00997          - add the bind index to the map
00998     */
00999 
01000     if (res == TRUE)
01001     {
01002         if (mode == OCI_BIND_INPUT)
01003         {
01004             if (reused == FALSE)
01005             {
01006                 stmt->ubinds[stmt->nb_ubinds++] = bnd;
01007 
01008                 /* for user binds, add a positive index */
01009 
01010                 OCI_HashAddInt(stmt->map, name, stmt->nb_ubinds);
01011             }
01012         }
01013         else
01014         {
01015             /* for register binds, add a negative index */
01016 
01017             stmt->rbinds[stmt->nb_rbinds++] = bnd;
01018 
01019             index = (int) stmt->nb_rbinds;
01020 
01021             OCI_HashAddInt(stmt->map, name, -index);
01022         }
01023     }
01024 
01025     if (res == FALSE)
01026     {
01027         if ((bnd != NULL) && (prev_index  == -1))
01028         {
01029             OCI_BindFree(bnd);
01030         }
01031     }
01032 
01033     OCI_RESULT(res);
01034 
01035     return res;
01036 }
01037 
01038 /* --------------------------------------------------------------------------------------------- *
01039  * OCI_BindGetIndex
01040  * --------------------------------------------------------------------------------------------- */
01041 
01042 int OCI_BindGetIndex
01043 (
01044     OCI_Statement *stmt,
01045     const mtext   *name
01046 )
01047 {
01048     OCI_HashEntry *he = NULL;
01049     int index         = -1;
01050 
01051     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, -1);
01052     OCI_CHECK_PTR(OCI_IPC_STRING, name, -1);
01053 
01054     if (stmt->map != NULL)
01055     {
01056         he = OCI_HashLookup(stmt->map, name, FALSE);
01057 
01058         while (he != NULL)
01059         {
01060             /* no more entries or key matched => so we got it ! */
01061 
01062             if (he->next == NULL || mtscasecmp(he->key, name) == 0)
01063             {
01064                 /* in order to sue the same map for user binds and
01065                    register binds :
01066                       - user binds are stored as positive values
01067                       - registers binds are stored as negatives values
01068                 */
01069 
01070                 index = he->values->value.num;
01071 
01072                 if (index < 0)
01073                 {
01074                     index = -index;
01075                 }
01076 
01077                 break;
01078             }
01079         }
01080     }
01081 
01082     return index;
01083 }
01084 
01085 /* --------------------------------------------------------------------------------------------- *
01086  * OCI_FetchIntoUserVariables
01087  * --------------------------------------------------------------------------------------------- */
01088 
01089 boolean OCI_FetchIntoUserVariables
01090 (
01091     OCI_Statement *stmt,
01092     va_list        args
01093 )
01094 {
01095     OCI_Resultset *rs = NULL;
01096     boolean res       = FALSE;
01097     int i, n;
01098 
01099     /* get resultset */
01100 
01101     rs = OCI_GetResultset(stmt);
01102 
01103     /* fetch data */
01104 
01105     if (rs != NULL)
01106     {
01107         res = OCI_FetchNext(rs);
01108     }
01109 
01110     if (res == TRUE)
01111     {
01112         /* loop on column list for updating user given placeholders */
01113 
01114         for (i = 1, n = OCI_GetColumnCount(rs); i <= n && res == TRUE; i++)
01115         {
01116             OCI_Column *col = OCI_GetColumn(rs, i);
01117 
01118             int type = va_arg(args, int);
01119 
01120             switch (type)
01121             {
01122                 case OCI_ARG_SHORT:
01123                 {
01124                     short src, *dst;
01125 
01126                     src = OCI_GetShort(rs, i);
01127                     dst = va_arg(args, short *);
01128 
01129                     if (dst != NULL)
01130                     {
01131                         *dst = src;
01132                     }
01133 
01134                     break;
01135                 }
01136                 case OCI_ARG_USHORT:
01137                 {
01138                     unsigned short src, *dst;
01139 
01140                     src = OCI_GetUnsignedShort(rs, i);
01141                     dst = va_arg(args, unsigned short *);
01142 
01143                     if (dst != NULL)
01144                     {
01145                         *dst = src;
01146                     }
01147 
01148                     break;
01149                 }
01150                 case OCI_ARG_INT:
01151                 {
01152                     int src, *dst;
01153 
01154                     src = OCI_GetInt(rs, i);
01155                     dst = va_arg(args, int *);
01156 
01157                     if (dst != NULL)
01158                     {
01159                         *dst = src;
01160                     }
01161 
01162                     break;
01163                 }
01164                 case OCI_ARG_UINT:
01165                 {
01166                     unsigned int src, *dst;
01167 
01168                     src = OCI_GetUnsignedInt(rs, i);
01169                     dst = va_arg(args, unsigned int *);
01170 
01171                     if (dst != NULL)
01172                     {
01173                         *dst = src;
01174                     }
01175 
01176                     break;
01177                 }
01178                 case OCI_ARG_BIGINT:
01179                 {
01180                     big_int src, *dst;
01181 
01182                     src = OCI_GetBigInt(rs, i);
01183                     dst = va_arg(args, big_int *);
01184 
01185                     if (dst != NULL)
01186                     {
01187                         *dst = src;
01188                     }
01189 
01190                     break;
01191                 }
01192                 case OCI_ARG_BIGUINT:
01193                 {
01194                     big_uint src, *dst;
01195 
01196                     src = OCI_GetUnsignedBigInt(rs, i);
01197                     dst = va_arg(args, big_uint *);
01198 
01199                     if (dst != NULL)
01200                     {
01201                         *dst = src;
01202                     }
01203 
01204                     break;
01205                 }
01206                 case OCI_ARG_DOUBLE:
01207                 {
01208                     double src, *dst;
01209 
01210                     src = OCI_GetDouble(rs, i);
01211                     dst = va_arg(args, double *);
01212 
01213                     if (dst != NULL)
01214                     {
01215                         *dst = src;
01216                     }
01217 
01218                     break;
01219                 }
01220                 case OCI_ARG_DATETIME:
01221                 {
01222                     OCI_Date *src, *dst;
01223 
01224                     src = OCI_GetDate(rs, i);
01225                     dst = (OCI_Date *) va_arg(args, OCI_Date *);
01226 
01227                     if ((src != NULL) && (dst != NULL))
01228                     {
01229                         res = OCI_DateAssign(dst, src);
01230                     }
01231 
01232                     break;
01233                 }
01234                 case OCI_ARG_TEXT:
01235                 {
01236                     const dtext *src;
01237                     dtext *dst;
01238 
01239                     src = OCI_GetString(rs, i);
01240                     dst = va_arg(args, dtext *);
01241 
01242                     if (dst != NULL)
01243                     {
01244                         dst[0] = 0;
01245                     }
01246 
01247                     if ((dst != NULL) && (src != NULL))
01248                     {
01249                         dtscat(dst, src);
01250                     }
01251 
01252                     break;
01253                 }
01254                 case OCI_ARG_RAW:
01255                 {
01256                     OCI_GetRaw(rs, i, va_arg(args, dtext *), col->bufsize);
01257                     break;
01258                 }
01259                 case OCI_ARG_LOB:
01260                 {
01261                     OCI_Lob *src, *dst;
01262 
01263                     src = OCI_GetLob(rs, i);
01264                     dst = (OCI_Lob *) va_arg(args, OCI_Lob *);
01265 
01266                     if ((dst != NULL) && (src != NULL))
01267                     {
01268                         res = OCI_LobAssign(dst, src);
01269                     }
01270 
01271                     break;
01272                 }
01273                 case OCI_ARG_FILE:
01274                 {
01275                     OCI_File *src, *dst;
01276 
01277                     src = OCI_GetFile(rs, i);
01278                     dst = (OCI_File *) va_arg(args, OCI_File *);
01279 
01280                     if ((dst != NULL) && (src != NULL))
01281                     {
01282                         res = OCI_FileAssign(dst, src);
01283                     }
01284 
01285                     break;
01286                 }
01287                 case OCI_ARG_TIMESTAMP:
01288                 {
01289                     OCI_Timestamp *src, *dst;
01290 
01291                     src = OCI_GetTimestamp(rs, i);
01292                     dst = (OCI_Timestamp *) va_arg(args, OCI_Timestamp *);
01293 
01294                     if ((dst != NULL) && (src != NULL))
01295                     {
01296                         res = OCI_TimestampAssign(dst, src);
01297                     }
01298 
01299                     break;
01300                 }
01301                 case OCI_ARG_INTERVAL:
01302                 {
01303                     OCI_Interval *src, *dst;
01304 
01305                     src = OCI_GetInterval(rs, i);
01306                     dst = (OCI_Interval *) va_arg(args, OCI_Interval *);
01307 
01308                     if ((dst != NULL) && (src != NULL))
01309                     {
01310                         res = OCI_IntervalAssign(dst, src);
01311                     }
01312 
01313                     break;
01314                 }
01315                 case OCI_ARG_OBJECT:
01316                 {
01317                     OCI_Object *src, *dst;
01318 
01319                     src = OCI_GetObject(rs, i);
01320                     dst = (OCI_Object *) va_arg(args, OCI_Object *);
01321 
01322                     if ((dst != NULL) && (src != NULL))
01323                     {
01324                         res = OCI_ObjectAssign(dst, src);
01325                     }
01326 
01327                     break;
01328                 }
01329                 case OCI_ARG_COLLECTION:
01330                 {
01331                     OCI_Coll *src, *dst;
01332 
01333                     src = OCI_GetColl(rs, i);
01334                     dst = (OCI_Coll *) va_arg(args, OCI_Coll *);
01335 
01336                     if ((dst != NULL) && (src != NULL))
01337                     {
01338                         res =OCI_CollAssign(dst, src);
01339                     }
01340 
01341                     break;
01342                 }
01343                 case OCI_ARG_REF:
01344                 {
01345                     OCI_Ref *src, *dst;
01346 
01347                     src = OCI_GetRef(rs, i);
01348                     dst = (OCI_Ref *) va_arg(args, OCI_Ref *);
01349 
01350                     if ((dst != NULL) && (src != NULL))
01351                     {
01352                         res =OCI_RefAssign(dst, src);
01353                     }
01354 
01355                     break;
01356                 }
01357                 default:
01358                 {
01359                     OCI_ExceptionMappingArgument(stmt->con, stmt, type);
01360 
01361                     res = FALSE;
01362 
01363                     break;
01364                 }
01365             }
01366         }
01367     }
01368 
01369     return res;
01370 }
01371 
01372 /* --------------------------------------------------------------------------------------------- *
01373  * OCI_StatementInit
01374  * --------------------------------------------------------------------------------------------- */
01375 
01376 OCI_Statement * OCI_StatementInit
01377 (
01378     OCI_Connection *con,
01379     OCI_Statement **pstmt,
01380     OCIStmt        *handle,
01381     OCI_Define     *def
01382 )
01383 {
01384     OCI_Statement * stmt = NULL;
01385     boolean res          = TRUE;
01386 
01387     OCI_CHECK(pstmt == NULL, NULL);
01388 
01389     if (*pstmt == NULL)
01390     {
01391         *pstmt = (OCI_Statement *) OCI_MemAlloc(OCI_IPC_STATEMENT, sizeof(*stmt), (size_t) 1, TRUE);
01392     }
01393 
01394     if (*pstmt != NULL)
01395     {
01396         stmt = *pstmt;
01397 
01398         stmt->con  = con;
01399         stmt->stmt = handle;
01400 
01401         stmt->exec_mode       = OCI_DEFAULT;
01402         stmt->long_size       = OCI_SIZE_LONG;
01403         stmt->bind_reuse      = FALSE;
01404         stmt->bind_mode       = OCI_BIND_BY_NAME;
01405         stmt->long_mode       = OCI_LONG_EXPLICIT;
01406         stmt->bind_alloc_mode = OCI_BAM_EXTERNAL;
01407 
01408         /* reset statement */
01409 
01410         OCI_StatementReset(stmt);
01411 
01412         if (def == NULL)
01413         {
01414             /* allocate handle for non fetched cursor */
01415 
01416             stmt->hstate = OCI_OBJECT_ALLOCATED;
01417         }
01418         else
01419         {
01420             stmt->hstate = OCI_OBJECT_FETCHED_CLEAN;
01421             stmt->status = OCI_STMT_PREPARED  | OCI_STMT_PARSED | 
01422                            OCI_STMT_DESCRIBED | OCI_STMT_EXECUTED;
01423             stmt->type   = OCI_CST_SELECT;
01424 
01425             res = (res && OCI_SetPrefetchSize(stmt, OCI_PREFETCH_SIZE));
01426             res = (res && OCI_SetFetchSize(stmt, OCI_FETCH_SIZE));
01427 
01428             /* not really perfect, but better than nothing */
01429 
01430             if (def->col.name != NULL)
01431             {
01432                 stmt->sql = mtsdup(def->col.name);
01433             }
01434         }
01435     }
01436 
01437     /* check for failurec */
01438 
01439     if (res == FALSE)
01440     {
01441         OCI_StatementFree(stmt);
01442         stmt = NULL;
01443     }
01444 
01445     return stmt;
01446 }
01447 
01448 /* --------------------------------------------------------------------------------------------- *
01449  * OCI_StatementReset
01450  * --------------------------------------------------------------------------------------------- */
01451 
01452 boolean OCI_StatementReset
01453 (
01454     OCI_Statement *stmt
01455 )
01456 {
01457     boolean res = TRUE;
01458 
01459     /* reset batch errors */
01460 
01461     res = OCI_BatchErrorClear(stmt);
01462 
01463     /* free resultsets */
01464 
01465     res = OCI_ReleaseResultsets(stmt);
01466 
01467     /* free in/out binds */
01468 
01469     res = OCI_BindFreeAll(stmt);
01470 
01471     /* free bind map */
01472 
01473     if (stmt->map != NULL)
01474     {
01475         OCI_HashFree(stmt->map);
01476     }
01477 
01478     /* free handle if needed */
01479 
01480     if (stmt->stmt != NULL)
01481     {
01482         if (stmt->hstate == OCI_OBJECT_ALLOCATED)
01483         {
01484 
01485         #if OCI_VERSION_COMPILE >= OCI_9_2
01486 
01487 
01488             if (OCILib.version_runtime >= OCI_9_2)
01489             {
01490                 OCIStmtRelease(stmt->stmt, stmt->con->err, NULL, 0, OCI_DEFAULT);
01491             }
01492             else
01493 
01494         #endif
01495 
01496             {
01497                 OCI_HandleFree((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT);
01498             }
01499                 
01500             stmt->stmt = NULL;
01501         }
01502         else if (stmt->hstate == OCI_OBJECT_ALLOCATED_BIND_STMT)
01503         {  
01504             OCI_HandleFree((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT);
01505 
01506             stmt->stmt = NULL;
01507         }
01508     }
01509 
01510     /* free sql statement */
01511 
01512     OCI_FREE(stmt->sql);
01513 
01514     stmt->rsts  = NULL;
01515     stmt->sql   = NULL;
01516     stmt->map   = NULL;
01517     stmt->batch = NULL;
01518 
01519     stmt->status     = OCI_STMT_CLOSED;
01520     stmt->type       = OCI_UNKNOWN;
01521     stmt->bind_array = FALSE;
01522 
01523     stmt->nb_iters      = 1;
01524     stmt->nb_iters_init = 1;
01525     stmt->dynidx        = 0;
01526     stmt->err_pos       = 0;
01527 
01528     return res;
01529 }
01530 
01531 /* --------------------------------------------------------------------------------------------- *
01532  * OCI_StatementClose
01533  * --------------------------------------------------------------------------------------------- */
01534 
01535 boolean OCI_StatementClose
01536 (
01537     OCI_Statement *stmt
01538 )
01539 {
01540     boolean res    = TRUE;
01541     OCI_Error *err = NULL;
01542 
01543     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01544 
01545     /* clear statement reference from current error object */
01546 
01547     err = OCI_ErrorGet(FALSE, FALSE);
01548 
01549     if (err != NULL && err->stmt == stmt)
01550     {
01551         err->stmt = NULL;
01552     }
01553 
01554     /* reset data */
01555 
01556     res = OCI_StatementReset(stmt);
01557 
01558     return res;
01559 }
01560 
01561 /* --------------------------------------------------------------------------------------------- *
01562  * OCI_BatchErrorClear
01563  * --------------------------------------------------------------------------------------------- */
01564 
01565 boolean OCI_BatchErrorClear
01566 (
01567     OCI_Statement *stmt
01568 )
01569 {
01570     boolean res = FALSE;
01571 
01572     if (stmt->batch != NULL)
01573     {
01574         /* free internal array of OCI_Errors */
01575 
01576         OCI_FREE(stmt->batch->errs);
01577 
01578         /* free batch structure */
01579 
01580         OCI_FREE(stmt->batch);
01581 
01582         res = TRUE;
01583     }
01584 
01585     return res;
01586 }
01587 
01588 /* --------------------------------------------------------------------------------------------- *
01589  * OCI_BatchErrorsInit
01590  * --------------------------------------------------------------------------------------------- */
01591 
01592 boolean OCI_BatchErrorInit
01593 (
01594     OCI_Statement *stmt
01595 )
01596 {
01597     boolean res   = TRUE;
01598     ub4 err_count = 0;
01599 
01600     OCI_BatchErrorClear(stmt);
01601 
01602     /* all OCI call here are not checked for errors as we already dealing
01603        with an array DML error */
01604 
01605     OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
01606                (dvoid *) &err_count, (ub4 *) NULL,
01607                (ub4) OCI_ATTR_NUM_DML_ERRORS, stmt->con->err);
01608 
01609     if (err_count > 0)
01610     {
01611         OCIError *hndl = NULL;
01612 
01613         /* allocate batch error structure */
01614 
01615         stmt->batch = (OCI_BatchErrors *) OCI_MemAlloc(OCI_IPC_BATCH_ERRORS,
01616                                                        sizeof(*stmt->batch),
01617                                                        (size_t) 1, TRUE);
01618 
01619         res = (stmt->batch != NULL);
01620 
01621         /* allocate array of error objects */
01622 
01623         if (res == TRUE)
01624         {
01625             stmt->batch->errs = (OCI_Error *) OCI_MemAlloc(OCI_IPC_ERROR,
01626                                                            sizeof(*stmt->batch->errs),
01627                                                            (size_t) err_count, TRUE);
01628 
01629             res = (stmt->batch->errs != NULL);
01630         }
01631 
01632         if (res == TRUE)
01633         {
01634             /* allocate OCI error handle */
01635 
01636             OCI_HandleAlloc((dvoid  *) stmt->con->env,
01637                             (dvoid **) (void *) &hndl,
01638                             (ub4) OCI_HTYPE_ERROR,
01639                             (size_t) 0, (dvoid **) NULL);
01640 
01641             res = (hndl != NULL);
01642         }
01643 
01644         /* loop on the OCI errors to fill OCILIB error objects */
01645 
01646         if (res == TRUE)
01647         {
01648             ub4 i;
01649 
01650             stmt->batch->count = err_count;
01651 
01652             for (i = 0; i < stmt->batch->count; i++)
01653             {
01654                 int osize  = -1;
01655                 void *ostr = NULL;
01656 
01657                 OCI_Error *err = &stmt->batch->errs[i];
01658 
01659                 OCIParamGet((dvoid *) stmt->con->err, OCI_HTYPE_ERROR,
01660                             stmt->con->err, (dvoid **) (void *) &hndl, i);
01661 
01662                 /* get row offset */
01663 
01664                 OCIAttrGet((dvoid *) hndl, (ub4) OCI_HTYPE_ERROR,
01665                            (void *) &err->row, (ub4 *) NULL,
01666                            (ub4) OCI_ATTR_DML_ROW_OFFSET, stmt->con->err);
01667 
01668                 /* fill error attributes */
01669 
01670                 err->type = OCI_ERR_ORACLE;
01671                 err->con  = stmt->con;
01672                 err->stmt = stmt;
01673 
01674                 /* OCILIB indexes start at 1 */
01675 
01676                 err->row++;
01677 
01678                 /* get error string */
01679 
01680                 osize = (int) msizeof(err->str) - 1;
01681 
01682                 ostr = OCI_GetInputMetaString(err->str, &osize);
01683 
01684                 OCIErrorGet((dvoid *) hndl,
01685                             (ub4) 1,
01686                             (OraText *) NULL, &err->ocode,
01687                             (OraText *) ostr,
01688                             (ub4) osize,
01689                             (ub4) OCI_HTYPE_ERROR);
01690 
01691                 OCI_GetOutputMetaString(ostr, err->str, &osize);
01692                 OCI_ReleaseMetaString(ostr);
01693             }
01694         }
01695 
01696         /* release error handle */
01697 
01698         if (hndl != NULL)
01699         {
01700             OCI_HandleFree(hndl, OCI_HTYPE_ERROR);
01701         }
01702     }
01703 
01704     return res;
01705 }
01706 
01707 /* --------------------------------------------------------------------------------------------- *
01708  * OCI_ExecuteInternal
01709  * --------------------------------------------------------------------------------------------- */
01710 
01711 boolean OCI_API OCI_ExecuteInternal
01712 (
01713     OCI_Statement *stmt,
01714     ub4            mode
01715 )
01716 {
01717     boolean res  = TRUE;
01718     sword status = OCI_SUCCESS;
01719     ub4 iters    = 0;
01720 
01721     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01722     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_PREPARED, FALSE);
01723 
01724     /* set up iters and mode values for execution */
01725 
01726     if (stmt->type == OCI_CST_SELECT)
01727     {
01728         mode |= stmt->exec_mode;
01729     }
01730     else
01731     {
01732         iters = stmt->nb_iters;
01733 
01734         /* for array DML, use batch error mode */
01735 
01736         if (iters > 1)
01737         {
01738             mode = mode | OCI_BATCH_ERRORS;
01739         }
01740     }
01741 
01742     /* reset batch errors */
01743 
01744     res = OCI_BatchErrorClear(stmt);
01745 
01746     /* check bind objects for updating their null indicator status */
01747 
01748     res = OCI_BindCheck(stmt);
01749 
01750     /* check current resultsets */
01751 
01752     if ((res == TRUE) && (stmt->rsts != NULL))
01753     {
01754         /* resultsets are freed before any prepare operations.
01755            So, if we got ones here, it means the same SQL order
01756            is re-executed */
01757 
01758         if (stmt->type == OCI_CST_SELECT)
01759         {
01760             /* just reinitialize the current resultet */
01761 
01762             res = OCI_ResultsetInit(stmt->rsts[0]);
01763         }
01764         else
01765         {
01766             /* Must free previous resulsets for 'returning into'
01767                SQL orders that can produce multiple resulsets */
01768 
01769             res = OCI_ReleaseResultsets(stmt);
01770         }
01771     }
01772 
01773     /* Oracle execute call */
01774 
01775     status = OCIStmtExecute(stmt->con->cxt, stmt->stmt, stmt->con->err, iters,
01776                             (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL, mode);
01777 
01778     /* reset input binds indicators status even if execution failed */
01779 
01780     OCI_BindReset(stmt);
01781 
01782     /* check result */
01783 
01784     res = ((status == OCI_SUCCESS) ||
01785            (status == OCI_SUCCESS_WITH_INFO) ||
01786            (status == OCI_NEED_DATA));
01787 
01788     if (status == OCI_SUCCESS_WITH_INFO)
01789     {
01790         OCI_ExceptionOCI(stmt->con->err, stmt->con, stmt, TRUE);
01791     }
01792 
01793     /* on batch mode, check if any error occured */
01794 
01795     if (mode & OCI_BATCH_ERRORS)
01796     {
01797         /* build batch error list if the statement is array DML */
01798 
01799         OCI_BatchErrorInit(stmt);
01800 
01801         if (stmt->batch != NULL)
01802         {
01803             res = (stmt->batch->count == 0);
01804         }
01805     }
01806 
01807     /* update status on success */
01808 
01809     if (res == TRUE)
01810     {
01811         if (mode & OCI_PARSE_ONLY)
01812         {
01813             stmt->status |= OCI_STMT_PARSED;
01814         }
01815         else if (mode & OCI_DESCRIBE_ONLY)
01816         {
01817             stmt->status |= OCI_STMT_PARSED;
01818             stmt->status |= OCI_STMT_DESCRIBED;
01819         }
01820         else
01821         {
01822             stmt->status |= OCI_STMT_PARSED;
01823             stmt->status |= OCI_STMT_DESCRIBED;
01824             stmt->status |= OCI_STMT_EXECUTED;
01825 
01826             /* commit if necessary */
01827 
01828             if (stmt->con->autocom == TRUE)
01829             {
01830                 OCI_Commit(stmt->con);
01831             }
01832         }
01833     }
01834     else
01835     {
01836         /* get parse error position type */
01837 
01838         /* (one of the rare OCI call not enclosed with a OCI_CALLX macro ...) */
01839 
01840         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
01841                    (dvoid *) &stmt->err_pos, (ub4 *) NULL,
01842                    (ub4) OCI_ATTR_PARSE_ERROR_OFFSET, stmt->con->err);
01843 
01844         /* raise exception */
01845 
01846         OCI_ExceptionOCI(stmt->con->err, stmt->con, stmt, FALSE);
01847     }
01848 
01849     OCI_RESULT(res);
01850 
01851     return res;
01852 }
01853 
01854 /* ********************************************************************************************* *
01855  *                            PUBLIC FUNCTIONS
01856  * ********************************************************************************************* */
01857 
01858 /* --------------------------------------------------------------------------------------------- *
01859  * OCI_StatementCreate
01860  * --------------------------------------------------------------------------------------------- */
01861 
01862 OCI_Statement * OCI_API OCI_StatementCreate
01863 (
01864     OCI_Connection *con
01865 )
01866 {
01867     OCI_Statement *stmt = NULL;
01868     OCI_Item *item      = NULL;
01869 
01870     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01871 
01872     /* create statement object */
01873 
01874     item = OCI_ListAppend(con->stmts, sizeof(*stmt));
01875 
01876     if (item != NULL)
01877     {
01878         stmt = OCI_StatementInit(con, (OCI_Statement **) &item->data, NULL, FALSE);
01879     }
01880 
01881     OCI_RESULT(stmt != NULL);
01882 
01883     return stmt;
01884 }
01885 
01886 /* --------------------------------------------------------------------------------------------- *
01887  * OCI_StatementFree
01888  * --------------------------------------------------------------------------------------------- */
01889 
01890 boolean OCI_API OCI_StatementFree
01891 (
01892     OCI_Statement *stmt
01893 )
01894 {
01895     boolean res = FALSE;
01896 
01897     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01898 
01899     OCI_CHECK_OBJECT_FETCHED(stmt, FALSE);
01900 
01901     res = OCI_StatementClose(stmt);
01902 
01903     OCI_ListRemove(stmt->con->stmts, stmt);
01904 
01905     OCI_FREE(stmt);
01906 
01907     OCI_RESULT(res);
01908 
01909     return res;
01910 }
01911 
01912 /* --------------------------------------------------------------------------------------------- *
01913  * OCI_ReleaseResultsets
01914  * --------------------------------------------------------------------------------------------- */
01915 
01916 boolean OCI_API OCI_ReleaseResultsets
01917 (
01918     OCI_Statement *stmt
01919 )
01920 {
01921     boolean res = TRUE;
01922     ub4 i, nb_err = 0;
01923 
01924     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01925 
01926     if (stmt->rsts != NULL)
01927     {
01928         for (i = 0; i  < stmt->nb_rs; i++)
01929         {
01930             if (stmt->rsts[i] != NULL)
01931             {
01932                 if (FALSE == OCI_ResultsetFree(stmt->rsts[i]))
01933                     nb_err++;
01934             }
01935         }
01936 
01937         OCI_FREE(stmt->rsts);
01938     }
01939 
01940     res = (nb_err == 0);
01941 
01942     OCI_RESULT(res);
01943 
01944     return res;
01945 }
01946 
01947 /* --------------------------------------------------------------------------------------------- *
01948  * OCI_Prepare
01949  * --------------------------------------------------------------------------------------------- */
01950 
01951 boolean OCI_API OCI_Prepare
01952 (
01953     OCI_Statement *stmt,
01954     const mtext   *sql
01955 )
01956 {
01957     boolean res = TRUE;
01958     void *ostr  = NULL;
01959     int osize   = -1;
01960 
01961     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01962     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
01963 
01964     /* reset statement */
01965 
01966     res = OCI_StatementReset(stmt);
01967 
01968     if (res == TRUE)
01969     {
01970         /* store SQL */
01971 
01972         stmt->sql = mtsdup(sql);
01973 
01974         ostr = OCI_GetInputMetaString(stmt->sql, &osize);
01975 
01976     #if OCI_VERSION_COMPILE < OCI_9_2
01977 
01978         if (OCILib.version_runtime < OCI_9_2)
01979         {
01980             /* allocate handle */
01981 
01982             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) stmt->con->env,
01983                                                   (dvoid **) (void *) &stmt->stmt,
01984                                                   (ub4) OCI_HTYPE_STMT,
01985                                                   (size_t) 0, (dvoid **) NULL));
01986         }
01987 
01988     #endif
01989 
01990     }
01991 
01992     if (res == TRUE)
01993     {
01994         /* prepare SQL */
01995 
01996     #if OCI_VERSION_COMPILE >= OCI_9_2
01997 
01998         if (OCILib.version_runtime >= OCI_9_2)
01999         {
02000             OCI_CALL1
02001             (
02002                 res, stmt->con, stmt,
02003 
02004                 OCIStmtPrepare2(stmt->con->cxt, &stmt->stmt, stmt->con->err, (OraText *) ostr,
02005                                (ub4) osize, NULL, 0, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)
02006             )
02007         }
02008         else
02009 
02010     #endif
02011 
02012         {
02013             OCI_CALL1
02014             (
02015                 res, stmt->con, stmt,
02016 
02017                 OCIStmtPrepare(stmt->stmt,stmt->con->err, (OraText *) ostr,
02018                                (ub4) osize, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)
02019             )
02020         }
02021 
02022         OCI_ReleaseMetaString(ostr);
02023 
02024         /* get statement type */
02025 
02026         OCI_CALL1
02027         (
02028             res, stmt->con, stmt,
02029 
02030             OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
02031                        (dvoid *) &stmt->type, (ub4 *) NULL,
02032                        (ub4) OCI_ATTR_STMT_TYPE, stmt->con->err)
02033         )
02034     }
02035 
02036     /* update statement status */
02037 
02038     if (res == TRUE)
02039     {
02040         ub4 size = 0;
02041 
02042         stmt->status = OCI_STMT_PREPARED;
02043 
02044         size = stmt->prefetch_size ? stmt->prefetch_size : OCI_PREFETCH_SIZE;
02045         res  = (res && OCI_SetPrefetchSize(stmt, size));
02046                 
02047         size = stmt->fetch_size ? stmt->fetch_size : OCI_FETCH_SIZE;
02048         res  = (res && OCI_SetFetchSize(stmt, size));
02049     }
02050 
02051     OCI_RESULT(res);
02052 
02053     return res;
02054 }
02055 
02056 /* --------------------------------------------------------------------------------------------- *
02057  * OCI_Execute
02058  * --------------------------------------------------------------------------------------------- */
02059 
02060 boolean OCI_API OCI_Execute
02061 (
02062     OCI_Statement *stmt
02063 )
02064 {
02065     return OCI_ExecuteInternal(stmt, OCI_DEFAULT);
02066 }
02067 
02068 /* --------------------------------------------------------------------------------------------- *
02069  * OCI_ExecuteStmt
02070  * --------------------------------------------------------------------------------------------- */
02071 
02072 boolean OCI_API OCI_ExecuteStmt
02073 (
02074     OCI_Statement *stmt,
02075     const mtext   *sql
02076 )
02077 {
02078     return (OCI_Prepare(stmt, sql) && OCI_ExecuteInternal(stmt, OCI_DEFAULT));
02079 }
02080 
02081 /* --------------------------------------------------------------------------------------------- *
02082  * OCI_Parse
02083  * --------------------------------------------------------------------------------------------- */
02084 
02085 boolean OCI_API OCI_Parse
02086 (
02087     OCI_Statement *stmt,
02088     const mtext   *sql
02089 )
02090 {
02091     return (OCI_Prepare(stmt, sql) && OCI_ExecuteInternal(stmt, OCI_PARSE_ONLY));
02092 }
02093 
02094 /* --------------------------------------------------------------------------------------------- *
02095  * OCI_Describe
02096  * --------------------------------------------------------------------------------------------- */
02097 
02098 boolean OCI_API OCI_Describe
02099 (
02100     OCI_Statement *stmt,
02101     const mtext   *sql
02102 )
02103 {
02104     boolean res = TRUE;
02105 
02106     res = OCI_Prepare(stmt, sql);
02107     
02108     if ((res == TRUE) && (stmt->type == OCI_CST_SELECT))
02109     {
02110         res = OCI_ExecuteInternal(stmt, OCI_DESCRIBE_ONLY);
02111     }
02112 
02113     return res;
02114 }
02115 
02116 /* --------------------------------------------------------------------------------------------- *
02117  * OCI_PrepareFmt
02118  * --------------------------------------------------------------------------------------------- */
02119 
02120 boolean OCI_PrepareFmt
02121 (
02122     OCI_Statement *stmt,
02123     const mtext   *sql,
02124     ...
02125 )
02126 {
02127     boolean res    = FALSE;
02128     mtext *sql_fmt = NULL;
02129     va_list args;
02130     int size;
02131 
02132     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02133     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02134 
02135     /* first, get buffer size */
02136 
02137     va_start(args, sql);
02138 
02139     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02140 
02141     va_end(args);
02142 
02143     if (size > 0)
02144     {
02145         /* allocate buffer */
02146 
02147         sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02148 
02149         if (sql_fmt != NULL)
02150         {
02151             /* format buffer */
02152 
02153             va_start(args, sql);
02154 
02155             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02156             {
02157                 /* parse buffer */
02158 
02159                 res = OCI_Prepare(stmt, sql_fmt);
02160             }
02161 
02162             va_end(args);
02163 
02164             OCI_FREE(sql_fmt);
02165         }
02166     }
02167 
02168     OCI_RESULT(res);
02169 
02170     return res;
02171 }
02172 
02173 /* --------------------------------------------------------------------------------------------- *
02174  * OCI_ExecuteStmtFmt
02175  * --------------------------------------------------------------------------------------------- */
02176 
02177 boolean OCI_ExecuteStmtFmt
02178 (
02179     OCI_Statement *stmt,
02180     const mtext   *sql,
02181     ...
02182 )
02183 {
02184     boolean res    = FALSE;
02185     mtext *sql_fmt = NULL;
02186     va_list args;
02187     int size;
02188 
02189     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02190     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02191 
02192     /* first, get buffer size */
02193 
02194     va_start(args, sql);
02195 
02196     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02197 
02198     va_end(args);
02199 
02200     if (size > 0)
02201     {
02202         /* allocate buffer */
02203 
02204         sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02205 
02206         if (sql_fmt != NULL)
02207         {
02208             /* format buffer */
02209 
02210             va_start(args, sql);
02211 
02212             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02213             {
02214                 /* prepare and execute SQL buffer */
02215 
02216                 res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_DEFAULT));
02217             }
02218 
02219             va_end(args);
02220 
02221             OCI_FREE(sql_fmt);
02222         }
02223     }
02224 
02225     OCI_RESULT(res);
02226 
02227     return res;
02228 }
02229 
02230 /* --------------------------------------------------------------------------------------------- *
02231  * OCI_ParseFmt
02232  * --------------------------------------------------------------------------------------------- */
02233 
02234 boolean OCI_ParseFmt
02235 (
02236     OCI_Statement *stmt,
02237     const mtext   *sql,
02238     ...
02239 )
02240 {
02241     boolean res    = FALSE;
02242     mtext *sql_fmt = NULL;
02243     va_list args;
02244     int size;
02245 
02246     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02247     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02248 
02249     /* first, get buffer size */
02250 
02251     va_start(args, sql);
02252 
02253     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02254 
02255     va_end(args);
02256 
02257     if (size > 0)
02258     {
02259         /* allocate buffer */
02260 
02261         sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02262 
02263         if (sql_fmt != NULL)
02264         {
02265             /* format buffer */
02266 
02267             va_start(args, sql);
02268 
02269             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02270             {
02271                 /* prepare and execute SQL buffer */
02272 
02273                 res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_PARSE_ONLY));
02274             }
02275 
02276             va_end(args);
02277 
02278             OCI_FREE(sql_fmt);
02279         }
02280     }
02281 
02282     OCI_RESULT(res);
02283 
02284     return res;
02285 }
02286 
02287 /* --------------------------------------------------------------------------------------------- *
02288  * OCI_DescribeFmt
02289  * --------------------------------------------------------------------------------------------- */
02290 
02291 boolean OCI_DescribeFmt
02292 (
02293     OCI_Statement *stmt,
02294     const mtext   *sql,
02295     ...
02296 )
02297 {
02298     boolean res    = FALSE;
02299     mtext *sql_fmt = NULL;
02300     va_list args;
02301     int size;
02302 
02303     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02304     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02305 
02306     /* first, get buffer size */
02307 
02308     va_start(args, sql);
02309 
02310     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02311 
02312     va_end(args);
02313 
02314     if (size > 0)
02315     {
02316         /* allocate buffer */
02317 
02318         sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size_t) (size+1), TRUE);
02319 
02320         if (sql_fmt != NULL)
02321         {
02322             /* format buffer */
02323 
02324             va_start(args, sql);
02325 
02326             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02327             {
02328                 /* prepare and execute SQL buffer */
02329 
02330                 res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_DESCRIBE_ONLY));
02331             }
02332 
02333             va_end(args);
02334 
02335             OCI_FREE(sql_fmt);
02336         }
02337     }
02338 
02339     OCI_RESULT(res);
02340 
02341     return res;
02342 }
02343 
02344 /* --------------------------------------------------------------------------------------------- *
02345  * OCI_Immediate
02346  * --------------------------------------------------------------------------------------------- */
02347 
02348 boolean OCI_Immediate
02349 (
02350     OCI_Connection *con,
02351     const mtext    *sql,
02352     ...
02353 )
02354 {
02355     OCI_Statement *stmt = NULL;
02356     boolean res         = FALSE;
02357     va_list args;
02358 
02359     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02360     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02361 
02362     /* First, execute SQL */
02363 
02364     stmt = OCI_StatementCreate(con);
02365 
02366     if (stmt != NULL)
02367     {
02368         res = OCI_ExecuteStmt(stmt, sql);
02369 
02370         if (res == TRUE)
02371         {
02372             /* get resultset and set up variables */
02373 
02374             if (OCI_GetStatementType(stmt) == OCI_CST_SELECT)
02375             {
02376                 va_start(args, sql);
02377 
02378                 res = OCI_FetchIntoUserVariables(stmt, args);
02379 
02380                 va_end(args);
02381             }
02382         }
02383 
02384         OCI_StatementFree(stmt);
02385     }
02386 
02387     OCI_RESULT(res);
02388 
02389     return res;
02390 }
02391 
02392 /* --------------------------------------------------------------------------------------------- *
02393  * OCI_ImmediateFmt
02394  * --------------------------------------------------------------------------------------------- */
02395 
02396 boolean OCI_ImmediateFmt
02397 (
02398     OCI_Connection *con,
02399     const mtext    *sql,
02400     ...
02401 )
02402 {
02403     OCI_Statement *stmt = NULL;
02404     mtext *sql_fmt      = NULL;
02405     boolean res         = FALSE;
02406     va_list args;
02407     int size;
02408 
02409     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02410     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
02411 
02412     stmt = OCI_StatementCreate(con);
02413 
02414     if (stmt != NULL)
02415     {
02416         /* first, get buffer size */
02417 
02418         va_start(args, sql);
02419 
02420         size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
02421 
02422         va_end(args);
02423 
02424         if (size > 0)
02425         {
02426             /* allocate buffer */
02427 
02428             sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
02429                                              (size_t) (size+1), TRUE);
02430 
02431             if (sql_fmt != NULL)
02432             {
02433                 /* format buffer */
02434 
02435                 va_start(args, sql);
02436 
02437                 if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
02438                 {
02439                     /* prepare and execute SQL buffer */
02440 
02441                     res = (OCI_Prepare(stmt, sql_fmt) && OCI_ExecuteInternal(stmt, OCI_DEFAULT));
02442 
02443                     /* get resultset and set up variables */
02444 
02445                     if (res && (OCI_GetStatementType(stmt) == OCI_CST_SELECT))
02446                     {
02447                         res = OCI_FetchIntoUserVariables(stmt, args);
02448                     }
02449                 }
02450 
02451                 va_end(args);
02452 
02453                 OCI_FREE(sql_fmt);
02454             }
02455         }
02456 
02457         OCI_StatementFree(stmt);
02458     }
02459 
02460     OCI_RESULT(res);
02461 
02462     return res;
02463 }
02464 
02465 /* --------------------------------------------------------------------------------------------- *
02466  * OCI_BindArraySetSize
02467  * --------------------------------------------------------------------------------------------- */
02468 
02469 boolean OCI_API OCI_BindArraySetSize
02470 (
02471     OCI_Statement *stmt,
02472     unsigned int   size
02473 )
02474 {
02475     boolean res = TRUE;
02476 
02477     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02478 
02479     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
02480 
02481     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_PREPARED, FALSE);
02482 
02483     /* if the statements already has binds, we need to check if the new size is
02484        not greater than the initial size
02485     */
02486 
02487     if ((stmt->nb_ubinds > 0) && (stmt->nb_iters_init < size))
02488     {
02489         OCI_ExceptionBindArraySize(stmt, stmt->nb_iters_init, stmt->nb_iters, size);
02490 
02491         res = FALSE;
02492     }
02493     else
02494     {
02495         stmt->nb_iters   = size;
02496         stmt->bind_array = TRUE;
02497 
02498         if (stmt->nb_ubinds == 0)
02499         {
02500             stmt->nb_iters_init = stmt->nb_iters;
02501         }
02502     }
02503 
02504     OCI_RESULT(res);
02505 
02506     return res;
02507 }
02508 
02509 /* --------------------------------------------------------------------------------------------- *
02510  * OCI_BindArrayGetSize
02511  * --------------------------------------------------------------------------------------------- */
02512 
02513 unsigned int OCI_API OCI_BindArrayGetSize
02514 (
02515     OCI_Statement *stmt
02516 )
02517 {
02518     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02519 
02520     OCI_RESULT(TRUE);
02521 
02522     return stmt->nb_iters;
02523 }
02524 
02525 /* --------------------------------------------------------------------------------------------- *
02526  * OCI_AllowRebinding
02527  * --------------------------------------------------------------------------------------------- */
02528 
02529 OCI_EXPORT boolean OCI_API OCI_AllowRebinding
02530 (
02531     OCI_Statement *stmt,
02532     boolean        value
02533 )
02534 {
02535     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02536 
02537     OCI_RESULT(TRUE);
02538 
02539     stmt->bind_reuse = value;
02540 
02541     return TRUE;
02542 }
02543 
02544 /* --------------------------------------------------------------------------------------------- *
02545  * OCI_BindShort
02546  * --------------------------------------------------------------------------------------------- */
02547 
02548 boolean OCI_API OCI_BindShort
02549 (
02550     OCI_Statement *stmt,
02551     const mtext   *name,
02552     short         *data
02553 )
02554 {
02555     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
02556 
02557     return OCI_BindData(stmt, data, sizeof(short), name, OCI_CDT_NUMERIC,
02558                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_SHORT, NULL, 0);
02559 }
02560 
02561 /* --------------------------------------------------------------------------------------------- *
02562  * OCI_BindArrayOfShorts
02563  * --------------------------------------------------------------------------------------------- */
02564 
02565 boolean OCI_API OCI_BindArrayOfShorts
02566 (
02567     OCI_Statement *stmt,
02568     const mtext   *name,
02569     short         *data,
02570     unsigned int   nbelem
02571 )
02572 {
02573     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
02574 
02575     return OCI_BindData(stmt, data, sizeof(short), name, OCI_CDT_NUMERIC,
02576                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_SHORT, NULL, nbelem);
02577 }
02578 
02579 /* --------------------------------------------------------------------------------------------- *
02580  * OCI_BindUnsignedShort
02581  * --------------------------------------------------------------------------------------------- */
02582 
02583 boolean OCI_API OCI_BindUnsignedShort
02584 (
02585     OCI_Statement  *stmt,
02586     const mtext    *name,
02587     unsigned short *data
02588 )
02589 {
02590     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
02591 
02592     return OCI_BindData(stmt, data, sizeof(unsigned short), name, OCI_CDT_NUMERIC,
02593                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_USHORT, NULL, 0);
02594 }
02595 
02596 /* --------------------------------------------------------------------------------------------- *
02597  * OCI_BindArrayOfUnsignedShorts
02598  * --------------------------------------------------------------------------------------------- */
02599 
02600 boolean OCI_API OCI_BindArrayOfUnsignedShorts
02601 (
02602     OCI_Statement  *stmt,
02603     const mtext    *name,
02604     unsigned short *data,
02605     unsigned int    nbelem
02606 )
02607 {
02608     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
02609 
02610     return OCI_BindData(stmt, data, sizeof(unsigned short), name, OCI_CDT_NUMERIC,
02611                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_USHORT, NULL, nbelem);
02612 }
02613 
02614 /* --------------------------------------------------------------------------------------------- *
02615  * OCI_BindInt
02616  * --------------------------------------------------------------------------------------------- */
02617 
02618 boolean OCI_API OCI_BindInt
02619 (
02620     OCI_Statement *stmt,
02621     const mtext   *name,
02622     int           *data
02623 )
02624 {
02625     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
02626 
02627     return OCI_BindData(stmt, data, sizeof(int), name, OCI_CDT_NUMERIC,
02628                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_INT, NULL, 0);
02629 }
02630 
02631 /* --------------------------------------------------------------------------------------------- *
02632  * OCI_BindArrayOfInts
02633  * --------------------------------------------------------------------------------------------- */
02634 
02635 boolean OCI_API OCI_BindArrayOfInts
02636 (
02637     OCI_Statement *stmt,
02638     const mtext   *name,
02639     int           *data,
02640     unsigned int   nbelem
02641 )
02642 {
02643     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
02644 
02645     return OCI_BindData(stmt, data, sizeof(int), name, OCI_CDT_NUMERIC,
02646                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_INT, NULL, nbelem);
02647 }
02648 
02649 /* --------------------------------------------------------------------------------------------- *
02650  * OCI_BindUnsignedInt
02651  * --------------------------------------------------------------------------------------------- */
02652 
02653 boolean OCI_API OCI_BindUnsignedInt
02654 (
02655     OCI_Statement *stmt,
02656     const mtext   *name,
02657     unsigned int  *data
02658 )
02659 {
02660     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
02661 
02662     return OCI_BindData(stmt, data, sizeof(unsigned int), name, OCI_CDT_NUMERIC,
02663                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_UINT, NULL, 0);
02664 }
02665 
02666 /* --------------------------------------------------------------------------------------------- *
02667  * OCI_BindArrayOfUnsignedInts
02668  * --------------------------------------------------------------------------------------------- */
02669 
02670 boolean OCI_API OCI_BindArrayOfUnsignedInts
02671 (
02672     OCI_Statement *stmt,
02673     const mtext   *name,
02674     unsigned int  *data,
02675     unsigned int   nbelem
02676 )
02677 {
02678     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
02679 
02680     return OCI_BindData(stmt, data, sizeof(unsigned int), name, OCI_CDT_NUMERIC,
02681                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_UINT, NULL, nbelem);
02682 }
02683 
02684 /* --------------------------------------------------------------------------------------------- *
02685  * OCI_BindBigInt
02686  * --------------------------------------------------------------------------------------------- */
02687 
02688 boolean OCI_API OCI_BindBigInt
02689 (
02690     OCI_Statement *stmt,
02691     const mtext   *name,
02692     big_int       *data
02693 )
02694 {
02695     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
02696 
02697     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02698                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGINT, NULL, 0);
02699 }
02700 
02701 /* --------------------------------------------------------------------------------------------- *
02702  * OCI_BindArrayOfBigInts
02703  * --------------------------------------------------------------------------------------------- */
02704 
02705 boolean OCI_API OCI_BindArrayOfBigInts
02706 (
02707     OCI_Statement *stmt,
02708     const mtext   *name,
02709     big_int       *data,
02710     unsigned int   nbelem
02711 )
02712 {
02713     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
02714 
02715     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02716                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGINT, NULL, nbelem);
02717 }
02718 
02719 /* --------------------------------------------------------------------------------------------- *
02720  * OCI_BindUnsignedBigInt
02721  * --------------------------------------------------------------------------------------------- */
02722 
02723 boolean OCI_API OCI_BindUnsignedBigInt
02724 (
02725     OCI_Statement *stmt,
02726     const mtext   *name,
02727     big_uint      *data
02728 )
02729 {
02730     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
02731 
02732     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02733                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGUINT, NULL, 0);
02734 }
02735 
02736 /* --------------------------------------------------------------------------------------------- *
02737  * OCI_BindArrayOfUnsignedInts
02738  * --------------------------------------------------------------------------------------------- */
02739 
02740 boolean OCI_API OCI_BindArrayOfUnsignedBigInts
02741 (
02742     OCI_Statement *stmt,
02743     const mtext   *name,
02744     big_uint      *data,
02745     unsigned int   nbelem
02746 )
02747 {
02748     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
02749 
02750     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02751                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGUINT, NULL, nbelem);
02752 }
02753 
02754 /* --------------------------------------------------------------------------------------------- *
02755  * OCI_BindString
02756  * --------------------------------------------------------------------------------------------- */
02757 
02758 boolean OCI_API OCI_BindString
02759 (
02760     OCI_Statement *stmt,
02761     const mtext   *name,
02762     dtext         *data,
02763     unsigned int   len
02764 )
02765 {
02766     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_STRING);
02767 
02768     if ((len == 0) || len == (UINT_MAX))
02769     {
02770         if (data != NULL)
02771         {
02772             /* only compute length for external bind if no valid length has been provided */
02773 
02774             len = (unsigned int) dtslen(data);
02775         }
02776         else
02777         {
02778             /* if data is NULL, it means that binding mode is OCI_BAM_INTERNAL.
02779                An invalid length passed to the function, we do not have a valid length to 
02780                allocate internal array, thus we need to raise an exception */
02781     
02782             OCI_ExceptionMinimumValue(stmt->con, stmt, 1);
02783 
02784             return FALSE;
02785         }
02786     }
02787 
02788 
02789     return OCI_BindData(stmt, data, (len + 1) * (ub4) sizeof(odtext), name,
02790                         OCI_CDT_TEXT, SQLT_STR, OCI_BIND_INPUT, 0, NULL, 0);
02791 }
02792 
02793 /* --------------------------------------------------------------------------------------------- *
02794  * OCI_BindArrayOfStrings
02795  * --------------------------------------------------------------------------------------------- */
02796 
02797 boolean OCI_API OCI_BindArrayOfStrings
02798 (
02799     OCI_Statement *stmt,
02800     const mtext   *name,
02801     dtext         *data,
02802     unsigned int   len,
02803     unsigned int   nbelem
02804 )
02805 {
02806     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_STRING);
02807 
02808     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02809 
02810     return OCI_BindData(stmt, data, (len + 1) * (ub4) sizeof(odtext), name,
02811                         OCI_CDT_TEXT, SQLT_STR, OCI_BIND_INPUT, 0, NULL, nbelem);
02812 }
02813 
02814 /* --------------------------------------------------------------------------------------------- *
02815  * OCI_BindRaw
02816  * --------------------------------------------------------------------------------------------- */
02817 
02818 boolean OCI_API OCI_BindRaw
02819 (
02820     OCI_Statement *stmt,
02821     const mtext   *name,
02822     void          *data,
02823     unsigned int   len
02824 )
02825 {
02826     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_VOID);
02827 
02828     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02829 
02830     return OCI_BindData(stmt, data, len, name, OCI_CDT_RAW,
02831                         SQLT_BIN, OCI_BIND_INPUT, 0, NULL, 0);
02832 }
02833 
02834 /* --------------------------------------------------------------------------------------------- *
02835  * OCI_BindArrayOfRaws
02836  * --------------------------------------------------------------------------------------------- */
02837 
02838 boolean OCI_API OCI_BindArrayOfRaws
02839 (
02840     OCI_Statement *stmt,
02841     const mtext   *name,
02842     void          *data,
02843     unsigned int   len,
02844     unsigned int   nbelem
02845 )
02846 {
02847     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_VOID);
02848 
02849     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02850 
02851     return OCI_BindData(stmt, data, len, name, OCI_CDT_RAW,
02852                         SQLT_BIN, OCI_BIND_INPUT, 0, NULL, nbelem);
02853 }
02854 
02855 /* --------------------------------------------------------------------------------------------- *
02856  * OCI_BindDouble
02857  * --------------------------------------------------------------------------------------------- */
02858 
02859 boolean OCI_API OCI_BindDouble
02860 (
02861     OCI_Statement *stmt,
02862     const mtext   *name,
02863     double        *data
02864 )
02865 {
02866     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DOUBLE);
02867 
02868     return OCI_BindData(stmt, data, sizeof(double), name, OCI_CDT_NUMERIC,
02869                         SQLT_FLT, OCI_BIND_INPUT, OCI_NUM_DOUBLE, NULL, 0);
02870 }
02871 
02872 /* --------------------------------------------------------------------------------------------- *
02873  * OCI_BindArrayOfDoubles
02874  * --------------------------------------------------------------------------------------------- */
02875 
02876 boolean OCI_API OCI_BindArrayOfDoubles
02877 (
02878     OCI_Statement *stmt,
02879     const mtext   *name,
02880     double        *data,
02881     unsigned int   nbelem
02882 )
02883 {
02884     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DOUBLE);
02885 
02886     return OCI_BindData(stmt, data, sizeof(double), name, OCI_CDT_NUMERIC,
02887                         SQLT_FLT, OCI_BIND_INPUT, OCI_NUM_DOUBLE, NULL, nbelem);
02888 }
02889 
02890 /* --------------------------------------------------------------------------------------------- *
02891  * OCI_BindDate
02892  * --------------------------------------------------------------------------------------------- */
02893 
02894 boolean OCI_API OCI_BindDate
02895 (
02896     OCI_Statement *stmt,
02897     const mtext   *name,
02898     OCI_Date      *data
02899 )
02900 {
02901     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DATE);
02902 
02903     return OCI_BindData(stmt, data, sizeof(OCIDate), name, OCI_CDT_DATETIME,
02904                         SQLT_ODT, OCI_BIND_INPUT, 0, NULL, 0);
02905 }
02906 
02907 /* --------------------------------------------------------------------------------------------- *
02908  * OCI_BindArrayOfDates
02909  * --------------------------------------------------------------------------------------------- */
02910 
02911 boolean OCI_API OCI_BindArrayOfDates
02912 (
02913     OCI_Statement *stmt,
02914     const mtext   *name,
02915     OCI_Date     **data,
02916     unsigned int   nbelem
02917 )
02918 {
02919     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DATE);
02920 
02921     return OCI_BindData(stmt, data, sizeof(OCIDate), name, OCI_CDT_DATETIME,
02922                         SQLT_ODT, OCI_BIND_INPUT, 0, NULL, nbelem);
02923 }
02924 
02925 /* --------------------------------------------------------------------------------------------- *
02926  * OCI_BindTimestamp
02927  * --------------------------------------------------------------------------------------------- */
02928 
02929 boolean OCI_API OCI_BindTimestamp
02930 (
02931     OCI_Statement *stmt,
02932     const mtext   *name,
02933     OCI_Timestamp *data
02934 )
02935 {
02936     int code    = 0;
02937     boolean res = FALSE;
02938 
02939     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_TIMESTAMP);
02940 
02941     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
02942 
02943 #if OCI_VERSION_COMPILE >= OCI_9_0
02944 
02945     /* map oracle internal type */
02946 
02947     if (data->type == OCI_TIMESTAMP_TZ)
02948     {
02949         code = SQLT_TIMESTAMP_TZ;
02950     }
02951     else if (data->type == OCI_TIMESTAMP_LTZ)
02952     {
02953         code = SQLT_TIMESTAMP_LTZ;
02954     }
02955     else
02956     {
02957         code = SQLT_TIMESTAMP;
02958     }
02959 
02960     res = OCI_BindData(stmt, data, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
02961                        code, OCI_BIND_INPUT, data->type, NULL, 0);
02962 
02963 #else
02964 
02965     OCI_NOT_USED(name);
02966     OCI_NOT_USED(code);
02967     OCI_NOT_USED(code);
02968 
02969 #endif
02970 
02971     return res;
02972 }
02973 
02974 /* --------------------------------------------------------------------------------------------- *
02975  * OCI_BindArrayOfTimestamps
02976  * --------------------------------------------------------------------------------------------- */
02977 
02978 boolean OCI_API OCI_BindArrayOfTimestamps
02979 (
02980     OCI_Statement  *stmt,
02981     const mtext    *name,
02982     OCI_Timestamp **data,
02983     unsigned int    type,
02984     unsigned int    nbelem
02985 )
02986 {
02987     unsigned int code = 0;
02988     boolean res       = FALSE;
02989 
02990     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_TIMESTAMP);
02991 
02992     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
02993 
02994 #if OCI_VERSION_COMPILE >= OCI_9_0
02995 
02996     /* map oracle internal type */
02997 
02998     if (type == OCI_TIMESTAMP_TZ)
02999     {    
03000         code = SQLT_TIMESTAMP_TZ;
03001     }
03002     else if (type == OCI_TIMESTAMP_LTZ)
03003     {    
03004         code = SQLT_TIMESTAMP_LTZ;
03005     }
03006     else
03007     {    
03008         code = SQLT_TIMESTAMP;
03009     }
03010 
03011     res =  OCI_BindData(stmt, data, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
03012                         code, OCI_BIND_INPUT, type, NULL, nbelem);
03013 
03014 #else
03015 
03016     OCI_NOT_USED(name);
03017     OCI_NOT_USED(type);
03018     OCI_NOT_USED(code);
03019     OCI_NOT_USED(nbelem);
03020 
03021 #endif
03022 
03023     return res;
03024 }
03025 
03026 /* --------------------------------------------------------------------------------------------- *
03027  * OCI_BindInterval
03028  * --------------------------------------------------------------------------------------------- */
03029 
03030 boolean OCI_API OCI_BindInterval
03031 (
03032     OCI_Statement *stmt,
03033     const mtext   *name,
03034     OCI_Interval  *data
03035 )
03036 {
03037     int code    = 0;
03038     boolean res = FALSE;
03039 
03040     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INTERVAL);
03041 
03042     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
03043 
03044 #if OCI_VERSION_COMPILE >= OCI_9_0
03045 
03046     /* map oracle internal type */
03047 
03048     if (data->type == OCI_INTERVAL_YM)
03049     {
03050         code = SQLT_INTERVAL_YM;
03051     }
03052     else if (data->type == OCI_INTERVAL_DS)
03053     {
03054         code = SQLT_INTERVAL_DS;
03055     }
03056 
03057     res = OCI_BindData(stmt, data, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
03058                        code, OCI_BIND_INPUT, data->type, NULL, 0);
03059 
03060 #else
03061 
03062     OCI_NOT_USED(name);
03063     OCI_NOT_USED(code);
03064 
03065 #endif
03066 
03067     return res;
03068 }
03069 
03070 /* --------------------------------------------------------------------------------------------- *
03071  * OCI_BindArrayOfIntervals
03072  * --------------------------------------------------------------------------------------------- */
03073 
03074 boolean OCI_API OCI_BindArrayOfIntervals
03075 (
03076     OCI_Statement *stmt,
03077     const mtext   *name,
03078     OCI_Interval **data,
03079     unsigned int   type,
03080     unsigned int   nbelem
03081 )
03082 {
03083     unsigned int code = 0;
03084     boolean res       = FALSE;
03085 
03086     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INTERVAL);
03087 
03088     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
03089 
03090 #if OCI_VERSION_COMPILE >= OCI_9_0
03091 
03092     /* map oracle internal type */
03093 
03094     if (type == OCI_INTERVAL_YM)
03095     {
03096         code = SQLT_INTERVAL_YM;
03097     }
03098     else if (type == OCI_INTERVAL_DS)
03099     {
03100         code = SQLT_INTERVAL_DS;
03101     }
03102 
03103     res = OCI_BindData(stmt, data, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
03104                        code, OCI_BIND_INPUT, type, NULL, nbelem);
03105 
03106 #else
03107 
03108     OCI_NOT_USED(name);
03109     OCI_NOT_USED(type);
03110     OCI_NOT_USED(code);
03111     OCI_NOT_USED(nbelem);
03112 
03113 #endif
03114 
03115     return res;
03116 }
03117 
03118 /* --------------------------------------------------------------------------------------------- *
03119  * OCI_BindObject
03120  * --------------------------------------------------------------------------------------------- */
03121 
03122 boolean OCI_API OCI_BindObject
03123 (
03124     OCI_Statement *stmt,
03125     const mtext   *name,
03126     OCI_Object    *data
03127 )
03128 {
03129     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_OBJECT);
03130 
03131     return OCI_BindData(stmt, data, sizeof(void*), name, OCI_CDT_OBJECT,
03132                         SQLT_NTY, OCI_BIND_INPUT, 0, data->typinf, 0);
03133 }
03134 
03135 /* --------------------------------------------------------------------------------------------- *
03136  * OCI_BindArrayOfObjects
03137  * --------------------------------------------------------------------------------------------- */
03138 
03139 boolean OCI_API OCI_BindArrayOfObjects
03140 (
03141     OCI_Statement *stmt,
03142     const mtext   *name,
03143     OCI_Object   **data,
03144     OCI_TypeInfo  *typinf,
03145     unsigned int   nbelem
03146 )
03147 {
03148     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_OBJECT);
03149 
03150     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
03151 
03152     return OCI_BindData(stmt, data, sizeof(void *), name, OCI_CDT_OBJECT,
03153                         SQLT_NTY, OCI_BIND_INPUT, 0, typinf, nbelem);
03154 }
03155 
03156 /* --------------------------------------------------------------------------------------------- *
03157  * OCI_BindLob
03158  * --------------------------------------------------------------------------------------------- */
03159 
03160 boolean OCI_API OCI_BindLob
03161 (
03162     OCI_Statement *stmt,
03163     const mtext   *name,
03164     OCI_Lob       *data
03165 )
03166 {
03167     int code = 0;
03168 
03169     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_LOB);
03170 
03171     /* map oracle internal type */
03172 
03173     if (data->type == OCI_CLOB || data->type == OCI_NCLOB)
03174     {
03175         code = SQLT_CLOB;
03176     }
03177     else
03178     {
03179         code = SQLT_BLOB;
03180     }
03181 
03182     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
03183                         code, OCI_BIND_INPUT, data->type, NULL, 0);
03184 }
03185 
03186 /* --------------------------------------------------------------------------------------------- *
03187  * OCI_BindArrayOfLobs
03188  * --------------------------------------------------------------------------------------------- */
03189 
03190 boolean OCI_API OCI_BindArrayOfLobs
03191 (
03192     OCI_Statement *stmt,
03193     const mtext   *name,
03194     OCI_Lob      **data,
03195     unsigned int   type,
03196     unsigned int   nbelem
03197 )
03198 {
03199     unsigned int code = 0;
03200 
03201     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_LOB);
03202 
03203     /* map oracle internal type */
03204 
03205     if (type == OCI_CLOB || type == OCI_NCLOB)
03206     {
03207         code = SQLT_CLOB;
03208     }
03209     else
03210     {
03211         code = SQLT_BLOB;
03212     }
03213 
03214     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
03215                         code, OCI_BIND_INPUT, type, NULL, nbelem);
03216 }
03217 
03218 /* --------------------------------------------------------------------------------------------- *
03219  * OCI_BindFile
03220  * --------------------------------------------------------------------------------------------- */
03221 
03222 boolean OCI_API OCI_BindFile
03223 (
03224     OCI_Statement *stmt,
03225     const mtext   *name,
03226     OCI_File      *data
03227 )
03228 {
03229     int code = 0;
03230 
03231     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_FILE);
03232 
03233     /* map oracle internal type */
03234 
03235     if (data->type == OCI_CFILE)
03236     {
03237         code = SQLT_CFILE;
03238     }
03239     else
03240     {
03241         code = SQLT_BFILE;
03242     }
03243 
03244     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
03245                         code, OCI_BIND_INPUT, data->type, NULL, 0);
03246 }
03247 
03248 /* --------------------------------------------------------------------------------------------- *
03249  * OCI_BindArrayOfFiles
03250  * --------------------------------------------------------------------------------------------- */
03251 
03252 boolean OCI_API OCI_BindArrayOfFiles
03253 (
03254     OCI_Statement *stmt,
03255     const mtext   *name,
03256     OCI_File     **data,
03257     unsigned int   type,
03258     unsigned int   nbelem
03259 )
03260 {
03261     unsigned int code = 0;
03262 
03263     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_FILE);
03264 
03265     /* map oracle internal type */
03266 
03267     if (type == OCI_CFILE)
03268     {
03269         code = SQLT_CFILE;
03270     }
03271     else
03272     {
03273         code = SQLT_BFILE;
03274     }
03275 
03276     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
03277                         code, OCI_BIND_INPUT, type, NULL, nbelem);
03278 }
03279 
03280 /* --------------------------------------------------------------------------------------------- *
03281  * OCI_BindRef
03282  * --------------------------------------------------------------------------------------------- */
03283 
03284 boolean OCI_API OCI_BindRef
03285 (
03286     OCI_Statement *stmt,
03287     const mtext   *name,
03288     OCI_Ref       *data
03289 )
03290 {
03291     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_REF);
03292 
03293     return OCI_BindData(stmt, data, sizeof(OCIRef *), name, OCI_CDT_REF,
03294                         SQLT_REF, OCI_BIND_INPUT, 0, data->typinf, 0);
03295 }
03296 
03297 /* --------------------------------------------------------------------------------------------- *
03298  * OCI_BindArrayOfRefs
03299  * --------------------------------------------------------------------------------------------- */
03300 
03301 boolean OCI_API OCI_BindArrayOfRefs
03302 (
03303     OCI_Statement *stmt,
03304     const mtext   *name,
03305     OCI_Ref      **data,
03306     OCI_TypeInfo  *typinf,
03307     unsigned int   nbelem
03308 )
03309 {
03310     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_REF);
03311 
03312     return OCI_BindData(stmt, data, sizeof(OCIRef *), name, OCI_CDT_REF,
03313                         SQLT_REF, OCI_BIND_INPUT, 0, typinf, nbelem);
03314 }
03315 
03316 /* --------------------------------------------------------------------------------------------- *
03317  * OCI_BindColl
03318  * --------------------------------------------------------------------------------------------- */
03319 
03320 boolean OCI_API OCI_BindColl
03321 (
03322     OCI_Statement *stmt,
03323     const mtext   *name,
03324     OCI_Coll      *data
03325 )
03326 {
03327     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_COLLECTION);
03328 
03329     return OCI_BindData(stmt, data, sizeof(OCIColl*), name, OCI_CDT_COLLECTION, SQLT_NTY,
03330                         OCI_BIND_INPUT, 0, data->typinf, 0);
03331 }
03332 
03333 /* --------------------------------------------------------------------------------------------- *
03334  * OCI_BindArrayOfColls
03335  * --------------------------------------------------------------------------------------------- */
03336 
03337 boolean OCI_API OCI_BindArrayOfColls
03338 (
03339     OCI_Statement *stmt,
03340     const mtext   *name,
03341     OCI_Coll     **data,
03342     OCI_TypeInfo  *typinf,
03343     unsigned int   nbelem
03344 )
03345 {
03346     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_COLLECTION);
03347 
03348     return OCI_BindData(stmt, data, sizeof(OCIColl*), name, OCI_CDT_COLLECTION, SQLT_NTY, 
03349                         OCI_BIND_INPUT, 0, typinf, nbelem);
03350 }
03351 
03352 /* --------------------------------------------------------------------------------------------- *
03353  * OCI_BindStatement
03354  * --------------------------------------------------------------------------------------------- */
03355 
03356 boolean OCI_API OCI_BindStatement
03357 (
03358     OCI_Statement *stmt,
03359     const mtext   *name,
03360     OCI_Statement *data
03361 )
03362 {
03363     boolean res = FALSE;
03364 
03365     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_STATEMENT);
03366 
03367     res = OCI_BindData(stmt, &data->stmt, sizeof(OCIStmt*), name, OCI_CDT_CURSOR,
03368                        SQLT_RSET, OCI_BIND_INPUT, 0, NULL, 0);
03369 
03370     return res;
03371 }
03372 
03373 /* --------------------------------------------------------------------------------------------- *
03374  * OCI_BindLong
03375  * --------------------------------------------------------------------------------------------- */
03376 
03377 boolean OCI_API OCI_BindLong
03378 (
03379     OCI_Statement *stmt,
03380     const mtext   *name,
03381     OCI_Long      *data,
03382     unsigned int   size
03383 )
03384 {
03385     int code = 0;
03386 
03387     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_LONG);
03388 
03389     /* map oracle internal type */
03390 
03391     if (data->type == OCI_CLONG)
03392     {
03393         code = SQLT_LNG;
03394     }
03395     else
03396     {
03397         code = SQLT_LBI;
03398     }
03399 
03400     if (data->type == OCI_CLONG)
03401     {
03402         size *= (unsigned int) sizeof(dtext);
03403     }
03404 
03405     return OCI_BindData(stmt, data, size, name, OCI_CDT_LONG,
03406                         code, OCI_BIND_INPUT, data->type, NULL, 0);
03407 }
03408 
03409 /* --------------------------------------------------------------------------------------------- *
03410  * OCI_RegisterShort
03411  * --------------------------------------------------------------------------------------------- */
03412 
03413 boolean OCI_API OCI_RegisterShort
03414 (
03415     OCI_Statement *stmt,
03416     const mtext   *name
03417 )
03418 {
03419     OCI_CHECK_REGISTER_CALL(stmt, name);
03420 
03421     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03422                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_SHORT, NULL, 0);
03423 }
03424 
03425 /* --------------------------------------------------------------------------------------------- *
03426  * OCI_RegisterUnsignedShort
03427  * --------------------------------------------------------------------------------------------- */
03428 
03429 boolean OCI_API OCI_RegisterUnsignedShort
03430 (
03431     OCI_Statement *stmt,
03432     const mtext   *name
03433 )
03434 {
03435     OCI_CHECK_REGISTER_CALL(stmt, name);
03436 
03437     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03438                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_USHORT, NULL, 0);
03439 }
03440 
03441 /* --------------------------------------------------------------------------------------------- *
03442  * OCI_RegisterInt
03443  * --------------------------------------------------------------------------------------------- */
03444 
03445 boolean OCI_API OCI_RegisterInt
03446 (
03447     OCI_Statement *stmt,
03448     const mtext   *name
03449 )
03450 {
03451     OCI_CHECK_REGISTER_CALL(stmt, name);
03452 
03453     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03454                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_INT, NULL, 0);
03455 }
03456 
03457 /* --------------------------------------------------------------------------------------------- *
03458  * OCI_RegisterUnsignedInt
03459  * --------------------------------------------------------------------------------------------- */
03460 
03461 boolean OCI_API OCI_RegisterUnsignedInt
03462 (
03463     OCI_Statement *stmt,
03464     const mtext   *name
03465 )
03466 {
03467     OCI_CHECK_REGISTER_CALL(stmt, name);
03468 
03469     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03470                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_UINT, NULL, 0);
03471 }
03472 
03473 /* --------------------------------------------------------------------------------------------- *
03474  * OCI_RegisterBigInt
03475  * --------------------------------------------------------------------------------------------- */
03476 
03477 boolean OCI_API OCI_RegisterBigInt
03478 (
03479     OCI_Statement *stmt,
03480     const mtext   *name
03481 )
03482 {
03483     OCI_CHECK_REGISTER_CALL(stmt, name);
03484 
03485     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03486                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_BIGINT, NULL, 0);
03487 }
03488 
03489 /* --------------------------------------------------------------------------------------------- *
03490  * OCI_RegisterUnsignedBigInt
03491  * --------------------------------------------------------------------------------------------- */
03492 
03493 boolean OCI_API OCI_RegisterUnsignedBigInt
03494 (
03495     OCI_Statement *stmt,
03496     const mtext   *name
03497 )
03498 {
03499     OCI_CHECK_REGISTER_CALL(stmt, name);
03500 
03501     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03502                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_BIGUINT, NULL, 0);
03503 }
03504 
03505 /* --------------------------------------------------------------------------------------------- *
03506  * OCI_RegisterString
03507  * --------------------------------------------------------------------------------------------- */
03508 
03509 boolean OCI_API OCI_RegisterString
03510 (
03511     OCI_Statement *stmt,
03512     const mtext   *name,
03513     unsigned int   len
03514 )
03515 {
03516     OCI_CHECK_REGISTER_CALL(stmt, name);
03517 
03518     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
03519 
03520     return OCI_BindData(stmt, NULL, (len + 1) * (ub4) sizeof(odtext), name,
03521                         OCI_CDT_TEXT, SQLT_STR, OCI_BIND_OUTPUT, 0, NULL, 0);
03522 }
03523 
03524 /* --------------------------------------------------------------------------------------------- *
03525  * OCI_RegisterRaw
03526  * --------------------------------------------------------------------------------------------- */
03527 
03528 boolean OCI_API OCI_RegisterRaw
03529 (
03530     OCI_Statement *stmt,
03531     const mtext   *name,
03532     unsigned int   len
03533 )
03534 {
03535     OCI_CHECK_REGISTER_CALL(stmt, name);
03536 
03537     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
03538 
03539     return OCI_BindData(stmt, NULL, len, name, OCI_CDT_RAW,
03540                         SQLT_BIN, OCI_BIND_OUTPUT, 0, NULL, 0);
03541 }
03542 
03543 /* --------------------------------------------------------------------------------------------- *
03544  * OCI_RegisterDouble
03545  * --------------------------------------------------------------------------------------------- */
03546 
03547 boolean OCI_API OCI_RegisterDouble
03548 (
03549     OCI_Statement *stmt,
03550     const mtext   *name
03551 )
03552 {
03553     OCI_CHECK_REGISTER_CALL(stmt, name);
03554 
03555     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
03556                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_DOUBLE, NULL, 0);
03557 }
03558 
03559 /* --------------------------------------------------------------------------------------------- *
03560  * OCI_RegisterDate
03561  * --------------------------------------------------------------------------------------------- */
03562 
03563 boolean OCI_API OCI_RegisterDate
03564 (
03565     OCI_Statement *stmt,
03566     const mtext   *name
03567 )
03568 {
03569     int code = SQLT_ODT;
03570     int size = sizeof(OCIDate);
03571 
03572     OCI_CHECK_REGISTER_CALL(stmt, name);
03573 
03574     /* versions of OCI (< 10.2) crashes if SQLT_ODT is passed for output
03575        data with returning clause.
03576        It's an Oracle known bug #3269146 */
03577 
03578     if (OCI_GetVersionConnection(stmt->con) < OCI_10_2)
03579     {
03580         code = SQLT_DAT;
03581         size = 7;
03582     }
03583 
03584     return OCI_BindData(stmt, NULL, size, name, OCI_CDT_DATETIME,
03585                         code, OCI_BIND_OUTPUT, 0, NULL, 0);
03586 }
03587 
03588 /* --------------------------------------------------------------------------------------------- *
03589  * OCI_RegisterTimestamp
03590  * --------------------------------------------------------------------------------------------- */
03591 
03592 boolean OCI_API OCI_RegisterTimestamp
03593 (
03594     OCI_Statement *stmt,
03595     const mtext   *name,
03596     unsigned int   type
03597 )
03598 {
03599     int code    = 0;
03600     boolean res = FALSE;
03601 
03602     OCI_CHECK_REGISTER_CALL(stmt, name);
03603 
03604     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
03605 
03606 #if OCI_VERSION_COMPILE >= OCI_9_0
03607 
03608     /* map oracle internal type */
03609 
03610     if (type == OCI_TIMESTAMP_TZ)
03611     {
03612         code = SQLT_TIMESTAMP_TZ;
03613     }
03614     else if (type == OCI_TIMESTAMP_LTZ)
03615     {
03616         code = SQLT_TIMESTAMP_LTZ;
03617     }
03618     else
03619     {
03620         code = SQLT_TIMESTAMP;
03621     }
03622 
03623     res = OCI_BindData(stmt, NULL, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
03624                        code, OCI_BIND_OUTPUT, type, NULL, 0);
03625 
03626 #else
03627 
03628     OCI_NOT_USED(name);
03629     OCI_NOT_USED(type);
03630     OCI_NOT_USED(code);
03631 
03632 #endif
03633 
03634     return res;
03635 }
03636 
03637 /* --------------------------------------------------------------------------------------------- *
03638  * OCI_RegisterInterval
03639  * --------------------------------------------------------------------------------------------- */
03640 
03641 boolean OCI_API OCI_RegisterInterval
03642 (
03643     OCI_Statement *stmt,
03644     const mtext   *name,
03645     unsigned int   type
03646 )
03647 {
03648     unsigned int code = 0;
03649     boolean res       = FALSE;
03650 
03651     OCI_CHECK_REGISTER_CALL(stmt, name);
03652 
03653     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
03654 
03655 #if OCI_VERSION_COMPILE >= OCI_9_0
03656 
03657     /* map oracle internal type */
03658 
03659     if (type == OCI_INTERVAL_YM)
03660     {
03661         code = SQLT_INTERVAL_YM;
03662     }
03663     else if (type == OCI_INTERVAL_DS)
03664     {
03665         code = SQLT_INTERVAL_DS;
03666     }
03667     
03668     res = OCI_BindData(stmt, NULL, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
03669                        code, OCI_BIND_OUTPUT, type, NULL, 0);
03670 
03671 #else
03672 
03673     OCI_NOT_USED(name);
03674     OCI_NOT_USED(type);
03675     OCI_NOT_USED(code);
03676 
03677 #endif
03678 
03679     return res;
03680 }
03681 
03682 /* --------------------------------------------------------------------------------------------- *
03683  * OCI_RegisterObject
03684  * --------------------------------------------------------------------------------------------- */
03685 
03686 boolean OCI_API OCI_RegisterObject
03687 (
03688     OCI_Statement *stmt,
03689     const mtext   *name,
03690     OCI_TypeInfo  *typinf
03691 )
03692 {
03693     OCI_CHECK_REGISTER_CALL(stmt, name);
03694 
03695     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
03696 
03697     return OCI_BindData(stmt, NULL, sizeof(OCIInterval *), name, OCI_CDT_OBJECT,
03698                         SQLT_NTY, OCI_BIND_OUTPUT, 0, typinf, 0);
03699 }
03700 
03701 /* --------------------------------------------------------------------------------------------- *
03702  * OCI_RegisterLob
03703  * --------------------------------------------------------------------------------------------- */
03704 
03705 boolean OCI_API OCI_RegisterLob
03706 (
03707     OCI_Statement *stmt,
03708     const mtext   *name,
03709     unsigned int   type
03710 )
03711 {
03712     unsigned int code = 0;
03713 
03714     OCI_CHECK_REGISTER_CALL(stmt, name);
03715 
03716     /* map oracle internal type */
03717 
03718     if (type == OCI_CLOB || type == OCI_NCLOB)
03719     {
03720         code = SQLT_CLOB;
03721     }
03722     else
03723     {
03724         code = SQLT_BLOB;
03725     }
03726 
03727     return OCI_BindData(stmt, NULL, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
03728                         code, OCI_BIND_OUTPUT, type, NULL, 0);
03729 }
03730 
03731 /* --------------------------------------------------------------------------------------------- *
03732  * OCI_RegisterFile
03733  * --------------------------------------------------------------------------------------------- */
03734 
03735 boolean OCI_API OCI_RegisterFile
03736 (
03737     OCI_Statement *stmt,
03738     const mtext   *name,
03739     unsigned int   type
03740 )
03741 {
03742     unsigned int code;
03743 
03744     OCI_CHECK_REGISTER_CALL(stmt, name);
03745 
03746     /* map oracle internal type */
03747 
03748     if (type == OCI_CFILE)
03749     {
03750         code = SQLT_CFILE;
03751     }
03752     else
03753     {
03754         code = SQLT_BFILE;
03755     }
03756 
03757     return OCI_BindData(stmt, NULL, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
03758                         code, OCI_BIND_OUTPUT, type, NULL, 0);
03759 }
03760 
03761 /* --------------------------------------------------------------------------------------------- *
03762  * OCI_RegisterRef
03763  * --------------------------------------------------------------------------------------------- */
03764 
03765 boolean OCI_API OCI_RegisterRef
03766 (
03767     OCI_Statement *stmt,
03768     const mtext   *name,
03769     OCI_TypeInfo  *typinf
03770 )
03771 {
03772     OCI_CHECK_REGISTER_CALL(stmt, name);
03773 
03774     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
03775 
03776     return OCI_BindData(stmt, NULL, sizeof(OCIRef *), name, OCI_CDT_REF,
03777                         SQLT_REF, OCI_BIND_OUTPUT, 0, typinf, 0);
03778 }
03779 
03780 /* --------------------------------------------------------------------------------------------- *
03781  * OCI_GetStatementType
03782  * --------------------------------------------------------------------------------------------- */
03783 
03784 unsigned int OCI_API OCI_GetStatementType
03785 (
03786     OCI_Statement *stmt
03787 )
03788 {
03789     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03790 
03791     OCI_RESULT(TRUE);
03792 
03793     return stmt->type;
03794 }
03795 
03796 /* --------------------------------------------------------------------------------------------- *
03797  * OCI_SetFetchMode
03798  * --------------------------------------------------------------------------------------------- */
03799 
03800 boolean OCI_API OCI_SetFetchMode
03801 (
03802     OCI_Statement *stmt,
03803     unsigned int   mode
03804 )
03805 {
03806     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03807 
03808     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(stmt->con, FALSE);
03809 
03810     stmt->exec_mode = mode;
03811 
03812     OCI_RESULT(TRUE);
03813 
03814     return TRUE;
03815 }
03816 
03817 /* --------------------------------------------------------------------------------------------- *
03818  * OCI_GetFetchMode
03819  * --------------------------------------------------------------------------------------------- */
03820 
03821 unsigned int OCI_API OCI_GetFetchMode
03822 (
03823     OCI_Statement *stmt
03824 )
03825 {
03826     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03827 
03828     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(stmt->con, OCI_UNKNOWN);
03829 
03830     OCI_RESULT(TRUE);
03831 
03832     return stmt->exec_mode;
03833 }
03834 
03835 /* --------------------------------------------------------------------------------------------- *
03836  * OCI_SetBindMode
03837  * --------------------------------------------------------------------------------------------- */
03838 
03839 boolean OCI_API OCI_SetBindMode
03840 (
03841     OCI_Statement *stmt,
03842     unsigned int   mode
03843 )
03844 {
03845     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03846 
03847     stmt->bind_mode = mode;
03848 
03849     OCI_RESULT(TRUE);
03850 
03851     return TRUE;
03852 }
03853 
03854 /* --------------------------------------------------------------------------------------------- *
03855  * OCI_GetBindMode
03856  * --------------------------------------------------------------------------------------------- */
03857 
03858 unsigned int OCI_API OCI_GetBindMode
03859 (
03860     OCI_Statement *stmt
03861 )
03862 {
03863     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03864 
03865     OCI_RESULT(TRUE);
03866 
03867     return stmt->bind_mode;
03868 }
03869 
03870 /* --------------------------------------------------------------------------------------------- *
03871  * OCI_SetBindAllocation
03872  * --------------------------------------------------------------------------------------------- */
03873 
03874 boolean OCI_API OCI_SetBindAllocation
03875 (
03876     OCI_Statement *stmt,
03877     unsigned int   mode
03878 )
03879 {
03880     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03881 
03882     stmt->bind_alloc_mode = mode;
03883 
03884     OCI_RESULT(TRUE);
03885 
03886     return TRUE;
03887 }
03888 
03889 /* --------------------------------------------------------------------------------------------- *
03890  * OCI_GetBindAllocation
03891  * --------------------------------------------------------------------------------------------- */
03892 
03893 unsigned int OCI_API OCI_GetBindAllocation
03894 (
03895     OCI_Statement *stmt
03896 )
03897 {
03898     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03899 
03900     OCI_RESULT(TRUE);
03901 
03902     return stmt->bind_alloc_mode;
03903 }
03904 
03905 /* --------------------------------------------------------------------------------------------- *
03906  * OCI_SetFetchSize
03907  * --------------------------------------------------------------------------------------------- */
03908 
03909 boolean OCI_API OCI_SetFetchSize
03910 (
03911     OCI_Statement *stmt,
03912     unsigned int   size
03913 )
03914 {
03915     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03916 
03917     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
03918 
03919     stmt->fetch_size = size;
03920 
03921     OCI_RESULT(TRUE);
03922 
03923     return TRUE;
03924 }
03925 
03926 /* --------------------------------------------------------------------------------------------- *
03927  * OCI_GetFetchSize
03928  * --------------------------------------------------------------------------------------------- */
03929 
03930 unsigned int OCI_API OCI_GetFetchSize
03931 (
03932     OCI_Statement *stmt
03933 )
03934 {
03935     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03936 
03937     OCI_RESULT(TRUE);
03938 
03939     return stmt->fetch_size;
03940 }
03941 
03942 /* --------------------------------------------------------------------------------------------- *
03943  * OCI_SetPrefetchSize
03944  * --------------------------------------------------------------------------------------------- */
03945 
03946 boolean OCI_API OCI_SetPrefetchSize
03947 (
03948     OCI_Statement *stmt,
03949     unsigned int   size
03950 )
03951 {
03952     boolean res = TRUE;
03953 
03954     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
03955   
03956     stmt->prefetch_size = size;
03957     
03958     if (stmt->stmt != NULL)
03959     {
03960         OCI_CALL1
03961         (
03962             res, stmt->con, stmt,
03963 
03964             OCIAttrSet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
03965                        (dvoid *) &stmt->prefetch_size,
03966                        (ub4) sizeof(stmt->prefetch_size),
03967                        (ub4) OCI_ATTR_PREFETCH_ROWS, stmt->con->err)
03968         )
03969     }
03970 
03971     OCI_RESULT(res);
03972 
03973     return res;
03974 }
03975 
03976 /* --------------------------------------------------------------------------------------------- *
03977  * OCI_GetPrefetchSize
03978  * --------------------------------------------------------------------------------------------- */
03979 
03980 unsigned int OCI_API OCI_GetPrefetchSize
03981 (
03982     OCI_Statement *stmt
03983 )
03984 {
03985     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03986 
03987     OCI_RESULT(TRUE);
03988 
03989     return stmt->prefetch_size;
03990 }
03991 
03992 /* --------------------------------------------------------------------------------------------- *
03993  * OCI_SetPrefetchMemory
03994  * --------------------------------------------------------------------------------------------- */
03995 
03996 boolean OCI_API OCI_SetPrefetchMemory
03997 (
03998     OCI_Statement *stmt,
03999     unsigned int   size
04000 )
04001 {
04002     boolean res = TRUE;
04003 
04004     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
04005 
04006     stmt->prefetch_mem = size;
04007 
04008     if (stmt->stmt != NULL)
04009     {
04010         OCI_CALL1
04011         (
04012             res, stmt->con, stmt,
04013 
04014             OCIAttrSet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
04015                        (dvoid *) &stmt->prefetch_mem,
04016                        (ub4) sizeof(stmt->prefetch_mem),
04017                        (ub4) OCI_ATTR_PREFETCH_MEMORY, stmt->con->err)
04018         )
04019     }
04020 
04021     OCI_RESULT(res);
04022 
04023     return res;
04024 }
04025 
04026 /* --------------------------------------------------------------------------------------------- *
04027  * OCI_GetPrefetchMemory
04028  * --------------------------------------------------------------------------------------------- */
04029 
04030 unsigned int OCI_API OCI_GetPrefetchMemory
04031 (
04032     OCI_Statement *stmt
04033 )
04034 {
04035     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04036 
04037     OCI_RESULT(TRUE);
04038 
04039     return stmt->prefetch_mem;
04040 }
04041 
04042 /* --------------------------------------------------------------------------------------------- *
04043  * OCI_SetLongMaxSize
04044  * --------------------------------------------------------------------------------------------- */
04045 
04046 boolean OCI_API OCI_SetLongMaxSize
04047 (
04048     OCI_Statement *stmt,
04049     unsigned int   size
04050 )
04051 {
04052     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
04053 
04054     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
04055 
04056     stmt->long_size = size;
04057 
04058     OCI_RESULT(TRUE);
04059 
04060     return TRUE;
04061 }
04062 
04063 /* --------------------------------------------------------------------------------------------- *
04064  * OCI_GetLongMaxSize
04065  * --------------------------------------------------------------------------------------------- */
04066 
04067 unsigned int OCI_API OCI_GetLongMaxSize
04068 (
04069     OCI_Statement *stmt
04070 )
04071 {
04072     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04073 
04074     OCI_RESULT(TRUE);
04075 
04076     return stmt->long_size;
04077 }
04078 
04079 /* --------------------------------------------------------------------------------------------- *
04080  * OCI_SetLongMode
04081  * --------------------------------------------------------------------------------------------- */
04082 
04083 boolean OCI_API OCI_SetLongMode
04084 (
04085     OCI_Statement *stmt,
04086     unsigned int   mode
04087 )
04088 {
04089     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
04090 
04091     stmt->long_mode = (ub1) mode;
04092 
04093     OCI_RESULT(TRUE);
04094 
04095     return TRUE;
04096 }
04097 
04098 /* --------------------------------------------------------------------------------------------- *
04099  * OCI_GetLongMode
04100  * --------------------------------------------------------------------------------------------- */
04101 
04102 unsigned int OCI_API OCI_GetLongMode
04103 (
04104     OCI_Statement *stmt
04105 )
04106 {
04107     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
04108 
04109     OCI_RESULT(TRUE);
04110 
04111     return stmt->long_mode;
04112 }
04113 
04114 /* --------------------------------------------------------------------------------------------- *
04115  * OCI_StatementGetConnection
04116  * --------------------------------------------------------------------------------------------- */
04117 
04118 OCI_Connection * OCI_API OCI_StatementGetConnection
04119 (
04120     OCI_Statement *stmt
04121 )
04122 {
04123     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04124 
04125     OCI_RESULT(TRUE);
04126 
04127     return stmt->con;
04128 }
04129 
04130 /* --------------------------------------------------------------------------------------------- *
04131  * OCI_GetSql
04132  * --------------------------------------------------------------------------------------------- */
04133 
04134 const mtext * OCI_API OCI_GetSql
04135 (
04136     OCI_Statement *stmt
04137 )
04138 {
04139     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04140 
04141     OCI_RESULT(TRUE);
04142 
04143     return stmt->sql;
04144 }
04145 
04146 /* --------------------------------------------------------------------------------------------- *
04147  * OCI_GetSqlErrorPos
04148  * --------------------------------------------------------------------------------------------- */
04149 
04150 unsigned int OCI_API OCI_GetSqlErrorPos
04151 (
04152     OCI_Statement *stmt
04153 )
04154 {
04155     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04156 
04157     OCI_RESULT(TRUE);
04158 
04159     return stmt->err_pos;
04160 }
04161 
04162 /* --------------------------------------------------------------------------------------------- *
04163  * OCI_GetAffecteddRows
04164  * --------------------------------------------------------------------------------------------- */
04165 
04166 unsigned int OCI_API OCI_GetAffectedRows
04167 (
04168     OCI_Statement *stmt
04169 )
04170 {
04171     boolean res = TRUE;
04172     ub4 count   = 0;
04173 
04174     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  0);
04175     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_EXECUTED, 0);
04176 
04177     OCI_CALL1
04178     (
04179         res, stmt->con, stmt,
04180 
04181         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
04182                    (void *) &count, (ub4 *) NULL, (ub4) OCI_ATTR_ROW_COUNT,
04183                    stmt->con->err)
04184     )
04185 
04186     OCI_RESULT(res);
04187 
04188     return count;
04189 }
04190 
04191 /* --------------------------------------------------------------------------------------------- *
04192  * OCI_GetBindCount
04193  * --------------------------------------------------------------------------------------------- */
04194 
04195 unsigned int OCI_API OCI_GetBindCount
04196 (
04197     OCI_Statement *stmt
04198 )
04199 {
04200     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04201 
04202     OCI_RESULT(TRUE);
04203 
04204     return (unsigned int) stmt->nb_ubinds;
04205 }
04206 
04207 /* --------------------------------------------------------------------------------------------- *
04208  * OCI_GetBind
04209  * --------------------------------------------------------------------------------------------- */
04210 
04211 OCI_Bind * OCI_API OCI_GetBind
04212 (
04213     OCI_Statement *stmt,
04214     unsigned int   index
04215 )
04216 {
04217     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04218     OCI_CHECK_BOUND(stmt->con, index, 1, stmt->nb_ubinds, NULL);
04219 
04220     OCI_RESULT(TRUE);
04221 
04222     return stmt->ubinds[index-1];
04223 }
04224 
04225 /* --------------------------------------------------------------------------------------------- *
04226  * OCI_GetBind2
04227  * --------------------------------------------------------------------------------------------- */
04228 
04229 OCI_Bind * OCI_API OCI_GetBind2
04230 (
04231     OCI_Statement *stmt,
04232     const mtext   *name
04233 )
04234 {
04235     OCI_Bind *bnd = NULL;
04236     int index     = -1;
04237 
04238     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04239     OCI_CHECK_PTR(OCI_IPC_STRING, name, NULL);
04240 
04241     index =  OCI_BindGetIndex(stmt, name);
04242 
04243     if (index > 0)
04244     {
04245         bnd = stmt->ubinds[index-1];
04246     }
04247 
04248     OCI_RESULT(bnd != NULL);
04249 
04250     return bnd;
04251 }
04252 
04253 /* --------------------------------------------------------------------------------------------- *
04254  * OCI_GetSQLCommand
04255  * --------------------------------------------------------------------------------------------- */
04256 
04257 unsigned int OCI_API OCI_GetSQLCommand
04258 (
04259     OCI_Statement *stmt
04260 )
04261 {
04262     boolean res = TRUE;
04263     ub2 code    = OCI_UNKNOWN;
04264 
04265     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
04266     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_EXECUTED, OCI_UNKNOWN);
04267 
04268     OCI_CALL1
04269     (
04270         res, stmt->con, stmt,
04271 
04272         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
04273                    (dvoid *) &code, (ub4 *) NULL,
04274                    (ub4) OCI_ATTR_SQLFNCODE, stmt->con->err)
04275     )
04276 
04277     OCI_RESULT(res);
04278 
04279     return (unsigned int) code;
04280 }
04281 
04282 /* --------------------------------------------------------------------------------------------- *
04283  * OCI_GetSQLVerb
04284  * --------------------------------------------------------------------------------------------- */
04285 
04286 const mtext * OCI_API OCI_GetSQLVerb
04287 (
04288     OCI_Statement *stmt
04289 )
04290 {
04291     mtext * desc      = NULL;
04292     unsigned int code = OCI_UNKNOWN;
04293 
04294     int i;
04295 
04296     code = OCI_GetSQLCommand(stmt);
04297 
04298     if (code != OCI_UNKNOWN)
04299     {
04300         for (i = 0; i < OCI_SQLCMD_COUNT; i++)
04301         {
04302             if (code == SQLCmds[i].code)
04303             {
04304                 desc = SQLCmds[i].verb;
04305                 break;
04306             }
04307         }
04308     }
04309 
04310     return desc;
04311 }
04312 
04313 /* --------------------------------------------------------------------------------------------- *
04314  * OCI_GetBatchError
04315  * --------------------------------------------------------------------------------------------- */
04316 
04317 OCI_Error * OCI_API OCI_GetBatchError
04318 (
04319     OCI_Statement *stmt
04320 )
04321 {
04322     OCI_Error *err = NULL;
04323 
04324     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
04325 
04326     if (stmt->batch != NULL)
04327     {
04328         if (stmt->batch->cur < stmt->batch->count)
04329         {
04330             err = &stmt->batch->errs[stmt->batch->cur++];
04331         }
04332     }
04333 
04334     OCI_RESULT(TRUE);
04335 
04336     return err;
04337 }
04338 
04339 /* --------------------------------------------------------------------------------------------- *
04340  * OCI_GetBatchErrorCount
04341  * --------------------------------------------------------------------------------------------- */
04342 
04343 unsigned int OCI_API OCI_GetBatchErrorCount
04344 (
04345     OCI_Statement *stmt
04346 )
04347 {
04348     unsigned int count = 0;
04349 
04350     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
04351 
04352     if (stmt->batch != NULL)
04353     {
04354         count = stmt->batch->count;
04355     }
04356 
04357     OCI_RESULT(TRUE);
04358 
04359     return 0;
04360 }