C:/Users/vincent/Data/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    +----------------------------------------------------------------------+
00009    |                      Website : http://www.ocilib.net                 |
00010    +----------------------------------------------------------------------+
00011    |               Copyright (c) 2007-2009 Vincent ROGIER                 |
00012    +----------------------------------------------------------------------+
00013    | This library is free software; you can redistribute it and/or        |
00014    | modify it under the terms of the GNU Lesser General Public           |
00015    | License as published by the Free Software Foundation; either         |
00016    | version 2 of the License, or (at your option) any later version.     |
00017    |                                                                      |
00018    | This library is distributed in the hope that it will be useful,      |
00019    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
00020    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
00021    | Lesser General Public License for more details.                      |
00022    |                                                                      |
00023    | You should have received a copy of the GNU Lesser General Public     |
00024    | License along with this library; if not, write to the Free           |
00025    | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   |
00026    +----------------------------------------------------------------------+
00027    |          Author: Vincent ROGIER <vince.rogier@gmail.com>             |
00028    +----------------------------------------------------------------------+
00029 */
00030 
00031 /* ------------------------------------------------------------------------ *
00032  * $Id: statement.c, v 3.4.0 2009-07-30 17:40 Vince $
00033  * ------------------------------------------------------------------------ */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ************************************************************************ *
00038  *                             PRIVATE FUNCTIONS
00039  * ************************************************************************ */
00040 
00041 /* ------------------------------------------------------------------------ *
00042  * OCI_BindFreeAll
00043  * ------------------------------------------------------------------------ */
00044 
00045 boolean OCI_BindFreeAll(OCI_Statement *stmt)
00046 {
00047     int i;
00048 
00049     OCI_CHECK(stmt == NULL, FALSE);
00050 
00051     /* free user binds */
00052 
00053     if (stmt->ubinds != NULL)
00054     {
00055         for(i = 0; i < stmt->nb_ubinds; i++)
00056         {
00057             OCI_BindFree(stmt->ubinds[i]);
00058         }
00059 
00060         OCI_FREE(stmt->ubinds);
00061     }
00062 
00063     /* free register binds */
00064 
00065     if (stmt->rbinds != NULL)
00066     {
00067         for(i = 0; i < stmt->nb_rbinds; i++)
00068         {
00069             OCI_BindFree(stmt->rbinds[i]);
00070         }
00071 
00072         OCI_FREE(stmt->rbinds);
00073     }
00074 
00075     stmt->nb_ubinds = 0;
00076     stmt->nb_rbinds = 0;
00077 
00078     return TRUE;
00079 }
00080 
00081 /* ------------------------------------------------------------------------ *
00082  * OCI_BindCheck
00083  * ------------------------------------------------------------------------ */
00084 
00085 boolean OCI_BindCheck(OCI_Statement *stmt)
00086 {
00087     boolean res   = TRUE;
00088     OCI_Bind *bnd = NULL;
00089     sb2 *ind      = NULL;
00090     ub4 i, j;
00091 
00092     OCI_CHECK(stmt == NULL, FALSE)
00093     OCI_CHECK(stmt->ubinds == NULL, TRUE);
00094 
00095     for(i = 0; i < stmt->nb_ubinds; i++)
00096     {
00097         bnd = stmt->ubinds[i];
00098         ind = (sb2 *) bnd->buf.inds;
00099 
00100         /* for strings, re-initialize length array with buffer default size */
00101 
00102         if (bnd->type == OCI_CDT_TEXT)
00103         {
00104             unsigned int i;
00105 
00106             for (i=0; i < bnd->buf.count; i++)
00107             {
00108                 *(ub2*)(((ub1 *)bnd->buf.lens) + sizeof(ub2) * i) = (ub2) bnd->size;
00109             }
00110         }
00111 
00112         /* extra work for internal allocated binds buffers */
00113 
00114         if (bnd->alloc == TRUE)
00115         {
00116             if (bnd->stmt->bind_array == FALSE)
00117             {
00118                 /* - For big integer (64 bits), we use an OCINumber.
00119 
00120                    - Oracle date/time type is the only non scalar type
00121                      implemented by oracle through a public structure instead
00122                      of using a handle. So we need to copy the value
00123                 */
00124 
00125                 if (bnd->type == OCI_CDT_NUMERIC)
00126                 {
00127                     res = OCI_NumberSet(stmt->con,
00128                                         (OCINumber *) bnd->buf.data,
00129                                         (void *) bnd->input,
00130                                         (uword) sizeof(big_int),
00131                                         bnd->subtype);
00132                 }
00133                 else if (bnd->type == OCI_CDT_DATETIME)
00134                 {
00135                     memcpy((void *) bnd->buf.data,
00136                            ((OCI_Date *) bnd->input)->handle,
00137                            sizeof(OCIDate));
00138                 }
00139 
00140 #ifdef OCI_CHECK_DATASTRINGS
00141 
00142                 else if (bnd->type == OCI_CDT_TEXT)
00143                 {
00144                     /* need conversion if bind buffer was allocated */
00145 
00146                     int osize = -1;
00147 
00148                     OCI_GetOutputString(bnd->input, bnd->buf.data, &osize,
00149                                         sizeof(dtext), sizeof(odtext));
00150 
00151                 }
00152 
00153 #endif
00154 
00155                 else
00156                 {
00157                     bnd->buf.data[0] = ((OCI_Datatype *) bnd->input)->handle;
00158 
00159                     /* for handles, check anyway the value for null data */
00160 
00161                     if (ind != NULL && *ind != -1)
00162                         *ind = OCI_IND(bnd->buf.data);
00163                 }
00164 
00165                 if (res == FALSE)
00166                     break;
00167             }
00168             else
00169             {
00170                 for (j = 0; j < bnd->buf.count; j++, ind++)
00171                 {
00172 
00173                     /* - For big integer (64 bits), we use an OCINumber.
00174 
00175                        - Oracle date/time type is the only non scalar type
00176                          implemented by oracle through a public structure instead
00177                          of using a handle. So we need to copy the value
00178                     */
00179 
00180                     if (bnd->type == OCI_CDT_NUMERIC)
00181                     {
00182 
00183                         res = OCI_NumberSet(stmt->con,
00184                                            (OCINumber *) ((ub1 *) bnd->buf.data + (j*bnd->size)),
00185                                            (void *) (((ub1 *) bnd->input) + (j*sizeof(big_int))),
00186                                            (uword) sizeof(big_int), bnd->subtype);
00187                     }
00188                     else  if (bnd->type == OCI_CDT_DATETIME)
00189                     {
00190                         memcpy(((ub1 *) bnd->buf.data) + (j*bnd->size),
00191                                ((OCI_Date *) bnd->input[j])->handle,
00192                                sizeof(OCIDate));
00193                     }
00194 
00195 #ifdef OCI_CHECK_DATASTRINGS
00196 
00197                     else if (bnd->type == OCI_CDT_TEXT)
00198                     {
00199                         /* need conversion if bind buffer was allocated */
00200 
00201                         int osize   = -1;
00202                         int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
00203                         int offset2 = bnd->size;
00204 
00205                         OCI_GetOutputString(((ub1 *) bnd->input)    + (j*offset1),
00206                                             ((ub1 *) bnd->buf.data) + (j*offset2),
00207                                             &osize, sizeof(dtext), sizeof(odtext));
00208 
00209                         /* set zero terminal null character */
00210 
00211                         {
00212                             odtext *str = (odtext *) (((ub1 *) bnd->buf.data) + (j*offset2));
00213 
00214                             if (osize> 0)
00215                                 str[osize/sizeof(odtext)] = 0;
00216                         }
00217                     }
00218 
00219 #endif
00220 
00221                     else
00222                     {
00223                         bnd->buf.data[j] = ((OCI_Datatype *) bnd->input[j])->handle;
00224 
00225                         /* for handles, check anyway the value for null data */
00226 
00227                         if (ind != NULL && *ind != -1)
00228                             *ind = OCI_IND(bnd->buf.data[j]);
00229                     }
00230 
00231 
00232                     if (res == FALSE)
00233                         break;
00234                 }
00235             }
00236         }
00237     }
00238 
00239     return res;
00240 }
00241 
00242 /* ------------------------------------------------------------------------ *
00243  * OCI_BindReset
00244  * ------------------------------------------------------------------------ */
00245 
00246 boolean OCI_BindReset(OCI_Statement *stmt)
00247 {
00248     ub4 i, j;
00249 
00250     OCI_CHECK(stmt == NULL, FALSE)
00251     OCI_CHECK(stmt->ubinds == NULL, FALSE);
00252 
00253     /* avoid unused param warning from compiler */
00254     
00255     i = j = 0;
00256 
00257     for(i = 0; i < stmt->nb_ubinds; i++)
00258     {
00259         OCI_Bind *bnd = stmt->ubinds[i];
00260 
00261         /* only reset bind indicators if bind was not a PL/SQL bind
00262            that can have oupout values
00263         */
00264              
00265         if (stmt->type != OCI_CST_BEGIN && stmt->type != OCI_CST_DECLARE)
00266         {
00267             memset(bnd->buf.inds, 0, bnd->buf.count * sizeof(sb2));
00268         }
00269 
00270 #ifdef OCI_CHECK_DATASTRINGS
00271 
00272         if (bnd->type == OCI_CDT_TEXT)
00273         {
00274             for (j = 0; j < bnd->buf.count; j++)
00275             {
00276                 /* need conversion if bind buffer was allocated */
00277 
00278                 int osize   = -1;
00279                 int offset1 = (bnd->size/sizeof(odtext))*sizeof(dtext);
00280                 int offset2 = bnd->size;
00281 
00282                 if (bnd->buf.lens != NULL)
00283                     osize = (int) ((ub2 *) bnd->buf.lens)[j];
00284 
00285                 if (bnd->size == (sb4) osize)
00286                     osize -= sizeof(odtext);
00287                 
00288                 OCI_GetOutputString(((ub1 *) bnd->buf.data) + (j*offset2),
00289                                     ((ub1 *) bnd->input)    + (j*offset1),
00290                                     &osize, sizeof(odtext), sizeof(dtext));
00291 
00292                 /* set zero terminal null character (sometimes it is not set 
00293                    by OCI and causes problems if the string has been modified 
00294                    and its length reduced */
00295 
00296                 {
00297                     dtext *str = (dtext *) (((ub1 *) bnd->input) + (j*offset1));
00298 
00299                     if (osize> 0)
00300                         str[osize/sizeof(dtext)] = 0;
00301                 }
00302             }
00303         }
00304 #endif
00305 
00306     }
00307 
00308     return TRUE;
00309 }
00310 
00311 /* ------------------------------------------------------------------------ *
00312  * OCI_BindData
00313  * ------------------------------------------------------------------------ */
00314 
00315 boolean OCI_BindData(OCI_Statement *stmt, void *data, ub4 size,
00316                      const mtext *name, ub1 type, unsigned int code,
00317                      unsigned int mode, unsigned int subtype,
00318                      OCI_TypeInfo *typinf, unsigned int nbelem)
00319 {
00320     boolean res      = TRUE;
00321     OCI_Bind *bnd    = NULL;
00322     ub4 exec_mode    = OCI_DEFAULT;
00323     boolean is_pltbl = FALSE;
00324     boolean reused   = FALSE;
00325     ub4 *pnbelem     = NULL;
00326     int index        = 0;
00327 
00328     /* check index if necessary */
00329 
00330     if (res == TRUE)
00331     {
00332         if (stmt->bind_mode == OCI_BIND_BY_POS)
00333         {
00334             index = (int) mtstol(&name[1], NULL, 10);
00335 
00336             if (index <= 0 || index > OCI_BIND_MAX)
00337             {
00338                 OCI_ExceptionOutOfBounds(stmt->con, index);
00339                 res = FALSE;
00340             }
00341         }
00342     }
00343 
00344     /* check if the bind name has already been used */
00345 
00346     if (res == TRUE)
00347     {
00348         if (mode == OCI_BIND_INPUT)
00349         {
00350             int test_index = OCI_BindGetIndex(stmt, name);
00351 
00352             if (test_index > 0)
00353             {
00354                 if (stmt->bind_reuse == FALSE)
00355                 {
00356                     OCI_ExceptionBindAlreadyUsed(stmt, name);
00357                     res = FALSE;
00358                 }
00359                 else
00360                 {
00361                     bnd = stmt->ubinds[test_index-1];
00362                     reused = TRUE;
00363                 }
00364 
00365                 index = test_index;
00366             }
00367         }
00368     }
00369 
00370     /* check if we can handle another bind */
00371 
00372     if (res == TRUE)
00373     {
00374         if (mode == OCI_BIND_INPUT)
00375         {
00376             if (stmt->nb_ubinds >= OCI_BIND_MAX)
00377             {
00378                 OCI_ExceptionMaxBind(stmt);
00379                 res = FALSE;
00380             }
00381 
00382             /* allocate user bind array if necessary */
00383 
00384             if (stmt->ubinds == NULL)
00385             {
00386                 stmt->ubinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
00387                                                           sizeof(*stmt->ubinds),
00388                                                           OCI_BIND_MAX, TRUE);
00389             }
00390 
00391             res = (stmt->ubinds != NULL);
00392         }
00393         else
00394         {
00395             if (stmt->nb_rbinds >= OCI_BIND_MAX)
00396             {
00397                 OCI_ExceptionMaxBind(stmt);
00398                 res = FALSE;
00399             }
00400 
00401             /* allocate register bind array if necessary */
00402 
00403             if (stmt->rbinds == NULL)
00404             {
00405                 stmt->rbinds = (OCI_Bind **) OCI_MemAlloc(OCI_IPC_BIND_ARRAY,
00406                                                           sizeof(*stmt->rbinds),
00407                                                           OCI_BIND_MAX, TRUE);
00408             }
00409 
00410             res = (stmt->rbinds != NULL);
00411         }
00412     }
00413 
00414     /* checks done */
00415 
00416     if (res == TRUE)
00417     {
00418         /* check out the number of elements that the bind variable will hold */
00419 
00420         if (nbelem > 0)
00421         {
00422             /* is it a pl/sql table bind ? */
00423 
00424             if (stmt->type == OCI_CST_BEGIN || stmt->type == OCI_CST_DECLARE)
00425             {
00426                 is_pltbl          = TRUE;
00427                 stmt->bind_array  = TRUE;
00428             }
00429         }
00430         else
00431             nbelem = stmt->nb_iters;
00432     }
00433 
00434     /* create hash table for mapping bind names / index */
00435 
00436     if (res == TRUE)
00437     {
00438         if (stmt->map == NULL)
00439         {
00440             stmt->map = OCI_HashCreate(OCI_HASH_DEFAULT_SIZE, OCI_HASH_INTEGER);
00441 
00442             res = (stmt->map != NULL);
00443         }
00444     }
00445 
00446     /* allocate bind object */
00447 
00448     if (res == TRUE)
00449     {
00450         if (bnd == NULL)
00451         {
00452             bnd = (OCI_Bind *) OCI_MemAlloc(OCI_IPC_BIND, sizeof(*bnd),  1, TRUE);
00453         }
00454 
00455         res = (bnd != NULL);
00456     }
00457 
00458     /* allocate indicators array */
00459 
00460     if (res == TRUE)
00461     {
00462         if (bnd->buf.inds == NULL)
00463         {
00464             bnd->buf.inds = (void *) OCI_MemAlloc(OCI_IPC_INDICATOR_ARRAY,
00465                                                   sizeof(sb2), nbelem, TRUE);
00466         }
00467 
00468         res = (bnd->buf.inds != NULL);
00469     }
00470 
00471     /* check need for PL/SQL table extra info */
00472 
00473     if ((res == TRUE) && (is_pltbl == TRUE))
00474     {
00475         bnd->nbelem = nbelem;
00476         pnbelem     = &bnd->nbelem;
00477 
00478         /* allocate array of returned codes */
00479 
00480         if (res == TRUE)
00481         {
00482             if (bnd->plrcds == NULL)
00483             {
00484                 bnd->plrcds = (ub2 *) OCI_MemAlloc(OCI_IPC_PLS_RCODE_ARRAY,
00485                                                    sizeof(ub2), nbelem, TRUE);
00486             }
00487 
00488             res = (bnd->plrcds != NULL);
00489         }
00490     }
00491 
00492     /* for handle based datatypes, we need to allocate an array of handles for
00493        bind calls because OCILIB uses external arrays of OCILIB Objects */
00494 
00495     if ((res == TRUE) && (mode == OCI_BIND_INPUT))
00496     {
00497         if (type != OCI_CDT_RAW      &&
00498             type != OCI_CDT_LONG     &&
00499             type != OCI_CDT_CURSOR   &&
00500 
00501 #ifndef OCI_CHECK_DATASTRINGS
00502 
00503             type != OCI_CDT_TEXT     &&
00504 
00505 #endif
00506             (type != OCI_CDT_NUMERIC || code == SQLT_VNU)
00507         )
00508         {
00509             bnd->alloc = TRUE;
00510 
00511             if (bnd->buf.data == NULL)
00512             {
00513                 bnd->buf.data = (void **) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY, size,
00514                                                        nbelem, TRUE);
00515             }
00516 
00517             res = (bnd->buf.data != NULL);
00518         }
00519         else
00520             bnd->buf.data = (void **) data;
00521     }
00522 
00523     /* setup data length array */
00524 
00525     if ((res == TRUE) && ((type == OCI_CDT_RAW) || (type == OCI_CDT_TEXT)))
00526     {
00527         if (bnd->buf.lens == NULL)
00528         {
00529             bnd->buf.lens = (void *) OCI_MemAlloc(OCI_IPC_LEN_ARRAY, sizeof(ub2),
00530                                                   nbelem, TRUE);
00531         }
00532 
00533         res = (bnd->buf.lens != NULL);
00534 
00535         /* initialize length array with buffer default size */
00536 
00537         if (res == TRUE)
00538         {
00539             unsigned int i;
00540 
00541             for (i=0; i < nbelem; i++)
00542             {
00543                 *(ub2*)(((ub1 *)bnd->buf.lens) + sizeof(ub2) * i) = (ub2) size;
00544             }
00545         }
00546     }
00547 
00548     /* initialize bind object */
00549 
00550     if (res == TRUE)
00551     {
00552         /* initialize bind attributes */
00553 
00554         bnd->stmt      = stmt;
00555         bnd->input     = (void **) data;
00556         bnd->type      = type;
00557         bnd->size      = size;
00558         bnd->code      = (ub2) code;
00559         bnd->subtype   = (ub1) subtype;
00560 
00561         if (bnd->name == NULL)
00562         {
00563             bnd->name = mtsdup(name);
00564         }
00565 
00566         /* initialize buffer */
00567 
00568         bnd->buf.count   = nbelem;
00569         bnd->buf.sizelen = sizeof(ub2);
00570 
00571         /* if we bind an OCI_Long or any output bind, we need to change the
00572            execution mode to provide data at execute time */
00573 
00574         if (bnd->type == OCI_CDT_LONG)
00575         {
00576             stmt->long_size = size;
00577             exec_mode       = OCI_DATA_AT_EXEC;
00578         }
00579         else if (mode == OCI_BIND_OUTPUT)
00580         {
00581             exec_mode = OCI_DATA_AT_EXEC;
00582         }
00583     }
00584 
00585    /* OCI binding */
00586 
00587     if (res == TRUE)
00588     {
00589         if (stmt->bind_mode == OCI_BIND_BY_POS)
00590         {
00591             OCI_CALL1
00592             (
00593                 res, stmt->con, stmt,
00594 
00595                 OCIBindByPos(stmt->stmt, (OCIBind **) &bnd->buf.handle,
00596                              stmt->con->err, (ub4) index, (void *) bnd->buf.data,
00597                              bnd->size, bnd->code, bnd->buf.inds,  bnd->buf.lens,
00598                              bnd->plrcds, (ub4) (is_pltbl == TRUE ? nbelem : 0),
00599                              pnbelem, exec_mode)
00600             )
00601         }
00602         else
00603         {
00604             void * ostr = NULL;
00605             int osize   = -1;
00606 
00607             ostr = OCI_GetInputMetaString(bnd->name, &osize);
00608 
00609             OCI_CALL1
00610             (
00611                 res, stmt->con, stmt,
00612 
00613                 OCIBindByName(stmt->stmt, (OCIBind **) &bnd->buf.handle,
00614                               stmt->con->err, (OraText *) ostr, (sb4) osize,
00615                               (void *) bnd->buf.data, bnd->size, bnd->code,
00616                               bnd->buf.inds, bnd->buf.lens, bnd->plrcds,
00617                               (ub4) (is_pltbl == TRUE ? nbelem : 0),
00618                               pnbelem, exec_mode)
00619             )
00620 
00621             OCI_ReleaseMetaString(ostr);
00622         }
00623 
00624         if (code == SQLT_NTY || code == SQLT_REF)
00625         {
00626             OCI_CALL1
00627             (
00628                 res, stmt->con, stmt,
00629 
00630                 OCIBindObject((OCIBind *) bnd->buf.handle, stmt->con->err,
00631                               (OCIType *) typinf->tdo, (void **) bnd->buf.data,
00632                               (ub4 *) NULL, (void **) NULL,
00633                               (ub4 *) bnd->buf.inds)
00634             )
00635         }
00636 
00637         if (mode == OCI_BIND_OUTPUT)
00638         {
00639             /* register output placeholder */
00640 
00641             OCI_CALL1
00642             (
00643                 res, stmt->con, stmt,
00644 
00645                 OCIBindDynamic((OCIBind *) bnd->buf.handle, stmt->con->err,
00646                                (dvoid *) bnd, OCI_ProcInBind,
00647                                (dvoid *) bnd, OCI_ProcOutBind)
00648             )
00649         }
00650 
00651         /* setup national charset from flag if needed */
00652 
00653         if (
00654             (
00655                 (bnd->type    == OCI_CDT_LOB) &&
00656                 (bnd->subtype == OCI_NCLOB)
00657             )
00658 #ifdef OCI_USERDATA_UNICODE
00659             ||
00660             (
00661                 (bnd->type          == OCI_CDT_TEXT)             &&
00662                 (OCI_GetVersionConnection(stmt->con) >= OCI_9_0) &&
00663                 (bnd->buf.lens      == NULL)
00664             )
00665 #endif
00666            )
00667         {
00668             ub1 csfrm = SQLCS_NCHAR;
00669 
00670             OCI_CALL1
00671             (
00672                 res, stmt->con, stmt,
00673 
00674                 OCIAttrSet((dvoid *) bnd->buf.handle, (ub4) OCI_HTYPE_BIND,
00675                            (dvoid *) &csfrm, (ub4) sizeof(csfrm),
00676                            (ub4) OCI_ATTR_CHARSET_FORM,  bnd->stmt->con->err)
00677             )
00678         }
00679 
00680 
00681         if (bnd->type == OCI_CDT_TEXT)
00682         {
00683             OCI_CALL1
00684             (
00685                 res, stmt->con, stmt,
00686 
00687                 OCIAttrSet((dvoid *) bnd->buf.handle, (ub4) OCI_HTYPE_BIND,
00688                            (dvoid *) &bnd->size, (ub4) sizeof(bnd->size),
00689                            (ub4) OCI_ATTR_MAXDATA_SIZE,  bnd->stmt->con->err)
00690             )
00691         }
00692 
00693 #ifdef OCI_CHARSET_MIXED
00694 
00695         /* setup Unicode mode for user data in mixed builds */
00696 
00697         {
00698             ub2 csid = OCI_UTF16ID;
00699 
00700             OCI_CALL1
00701             (
00702                 res, stmt->con, stmt,
00703 
00704                 OCIAttrSet((dvoid *) bnd->buf.handle, (ub4) OCI_HTYPE_BIND,
00705                            (dvoid *) &csid,  (ub4) sizeof(csid),
00706                            (ub4) OCI_ATTR_CHARSET_ID,  stmt->con->err)
00707             )
00708         }
00709 
00710 #endif
00711 
00712     }
00713 
00714     /* on success, we :
00715          - add the bind handle to the bind array
00716          - add the bind index to the map
00717     */
00718 
00719     if (res == TRUE)
00720     {
00721         if (mode == OCI_BIND_INPUT)
00722         {
00723             if (reused == FALSE)
00724             {
00725                 stmt->ubinds[stmt->nb_ubinds++] = bnd;
00726 
00727                 /* for user binds, add a positive index */
00728 
00729                 OCI_HashAddInt(stmt->map, name, stmt->nb_ubinds);
00730             }
00731         }
00732         else
00733         {
00734             /* for register binds, add a negative index */
00735 
00736             stmt->rbinds[stmt->nb_rbinds++] = bnd;
00737 
00738             index = (int) stmt->nb_rbinds;
00739 
00740             OCI_HashAddInt(stmt->map, name, -index);
00741         }
00742     }
00743 
00744     OCI_RESULT(res);
00745 
00746     return res;
00747 }
00748 
00749 
00750 /* ------------------------------------------------------------------------ *
00751  * OCI_BindGetIndex
00752  * ------------------------------------------------------------------------ */
00753 
00754 int OCI_BindGetIndex(OCI_Statement *stmt, const mtext *name)
00755 {
00756     OCI_HashEntry *he = NULL;
00757     int index         = -1;
00758 
00759     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, -1);
00760     OCI_CHECK_PTR(OCI_IPC_STRING, name, -1);
00761 
00762     if (stmt->map != NULL)
00763     {
00764         he = OCI_HashLookup(stmt->map, name, FALSE);
00765 
00766         while (he != NULL)
00767         {
00768             /* no more entries or key matched => so we got it ! */
00769 
00770             if (he->next == NULL || mtscasecmp(he->key, name) == 0)
00771             {
00772                 /* in order to sue the same map for user binds and
00773                    register binds :
00774                       - user binds are stored as positive values
00775                       - registers binds are stored as negatives values
00776                 */
00777 
00778                 index = he->values->value.num;
00779 
00780                 if (index < 0)
00781                     index = -index;
00782 
00783                 break;
00784             }
00785         }
00786     }
00787 
00788     return index;
00789 }
00790 
00791 /* ------------------------------------------------------------------------ *
00792  * OCI_FetchIntoUserVariables
00793  * ------------------------------------------------------------------------ */
00794 
00795 boolean OCI_FetchIntoUserVariables(OCI_Statement *stmt, va_list args)
00796 {
00797     OCI_Resultset *rs = NULL;
00798     boolean res = FALSE;
00799     int i, n;
00800 
00801     /* get resultset */
00802 
00803     rs  = OCI_GetResultset(stmt);
00804 
00805     /* fetch data */
00806 
00807     if (rs != NULL)
00808         res = OCI_FetchNext(rs);
00809 
00810     if (res == TRUE)
00811     {
00812         /* loop on column list for updating user given placeholders */
00813 
00814         for (i = 1, n = OCI_GetColumnCount(rs); i <= n && res == TRUE; i++)
00815         {
00816             OCI_Column *col = OCI_GetColumn(rs, i);
00817 
00818             int type = va_arg(args, int);
00819 
00820             switch (type)
00821             {
00822                 case OCI_ARG_SHORT:
00823                 {
00824                     short src, *dst;
00825 
00826                     src = OCI_GetShort(rs, i);
00827                     dst = va_arg(args, short *);
00828 
00829                     if (dst != NULL)
00830                         *dst = src;
00831 
00832                     break;
00833                 }
00834                 case OCI_ARG_USHORT:
00835                 {
00836                    unsigned short src, *dst;
00837 
00838                     src = OCI_GetUnsignedShort(rs, i);
00839                     dst = va_arg(args, unsigned short *);
00840 
00841                     if (dst != NULL)
00842                         *dst = src;
00843 
00844                     break;
00845                 }
00846                 case OCI_ARG_INT:
00847                 {
00848                     int src, *dst;
00849 
00850                     src = OCI_GetInt(rs, i);
00851                     dst = va_arg(args, int *);
00852 
00853                     if (dst != NULL)
00854                         *dst = src;
00855 
00856                     break;
00857                 }
00858                 case OCI_ARG_UINT:
00859                 {
00860                    unsigned int src, *dst;
00861 
00862                     src = OCI_GetUnsignedInt(rs, i);
00863                     dst = va_arg(args, unsigned int *);
00864 
00865                     if (dst != NULL)
00866                         *dst = src;
00867 
00868                     break;
00869                 }
00870                 case OCI_ARG_BIGINT:
00871                 {
00872                     big_int src, *dst;
00873 
00874                     src = OCI_GetBigInt(rs, i);
00875                     dst = va_arg(args, big_int *);
00876 
00877                     if (dst != NULL)
00878                         *dst = src;
00879 
00880                     break;
00881                 }
00882                 case OCI_ARG_BIGUINT:
00883                 {
00884                    big_uint src, *dst;
00885 
00886                     src = OCI_GetUnsignedBigInt(rs, i);
00887                     dst = va_arg(args, big_uint *);
00888 
00889                     if (dst != NULL)
00890                         *dst = src;
00891 
00892                     break;
00893                 }
00894                 case OCI_ARG_DOUBLE:
00895                 {
00896                     double src, *dst;
00897 
00898                     src = OCI_GetDouble(rs, i);
00899                     dst = va_arg(args, double *);
00900 
00901                     if (dst != NULL)
00902                         *dst = src;
00903 
00904                     break;
00905                 }
00906                 case OCI_ARG_DATETIME:
00907                 {
00908                     OCI_Date *src, *dst;
00909 
00910                     src = OCI_GetDate(rs, i);
00911                     dst = (OCI_Date *) va_arg(args, OCI_Date *);
00912 
00913                     if (src != NULL && dst != NULL)
00914                         res = OCI_DateAssign(dst, src);
00915 
00916                     break;
00917                 }
00918                 case OCI_ARG_TEXT:
00919                 {
00920                     const dtext *src;
00921                     dtext *dst;
00922 
00923                     src = OCI_GetString(rs, i);
00924                     dst = va_arg(args, dtext *);
00925 
00926                     if (dst != NULL)
00927                         dst[0] = 0;
00928 
00929                     if (dst != NULL && src != NULL)
00930                         dtscat(dst, src);
00931 
00932                     break;
00933                 }
00934                 case OCI_ARG_RAW:
00935                 {
00936                     OCI_GetRaw(rs, i, va_arg(args, dtext *), col->bufsize);
00937                     break;
00938                 }
00939                 case OCI_ARG_LOB:
00940                 {
00941                     OCI_Lob *src, *dst;
00942 
00943                     src = OCI_GetLob(rs, i);
00944                     dst = (OCI_Lob *) va_arg(args, OCI_Lob *);
00945 
00946                     if (src != NULL && dst != NULL)
00947                         res = OCI_LobAssign(dst, src);
00948 
00949                     break;
00950                 }
00951                 case OCI_ARG_FILE:
00952                 {
00953                     OCI_File *src, *dst;
00954 
00955                     src = OCI_GetFile(rs, i);
00956                     dst = (OCI_File *) va_arg(args, OCI_File *);
00957 
00958                     if (src != NULL && dst != NULL)
00959                         res = OCI_FileAssign(dst, src);
00960 
00961                     break;
00962                 }
00963                 case OCI_ARG_TIMESTAMP:
00964                 {
00965                     OCI_Timestamp *src, *dst;
00966 
00967                     src = OCI_GetTimestamp(rs, i);
00968                     dst = (OCI_Timestamp *) va_arg(args, OCI_Timestamp *);
00969 
00970                     if (src != NULL && dst != NULL)
00971                         res = OCI_TimestampAssign(dst, src);
00972 
00973                     break;
00974                 }
00975                 case OCI_ARG_INTERVAL:
00976                 {
00977                     OCI_Interval *src, *dst;
00978 
00979                     src = OCI_GetInterval(rs, i);
00980                     dst = (OCI_Interval *) va_arg(args, OCI_Interval *);
00981 
00982                     if (src != NULL && dst != NULL)
00983                         res =OCI_IntervalAssign(dst, src);
00984 
00985                     break;
00986                 }
00987                 case OCI_ARG_OBJECT:
00988                 {
00989                     OCI_Object *src, *dst;
00990 
00991                     src = OCI_GetObject(rs, i);
00992                     dst = (OCI_Object *) va_arg(args, OCI_Object *);
00993 
00994                     if (src != NULL && dst != NULL)
00995                         res =OCI_ObjectAssign(dst, src);
00996 
00997                     break;
00998                 }
00999                 case OCI_ARG_COLLECTION:
01000                 {
01001                     OCI_Coll *src, *dst;
01002 
01003                     src = OCI_GetColl(rs, i);
01004                     dst = (OCI_Coll *) va_arg(args, OCI_Coll *);
01005 
01006                     if (src != NULL && dst != NULL)
01007                         res =OCI_CollAssign(dst, src);
01008 
01009                     break;
01010                 }
01011                 case OCI_ARG_REF:
01012                 {
01013                     OCI_Ref *src, *dst;
01014 
01015                     src = OCI_GetRef(rs, i);
01016                     dst = (OCI_Ref *) va_arg(args, OCI_Ref *);
01017 
01018                     if (src != NULL && dst != NULL)
01019                         res =OCI_RefAssign(dst, src);
01020 
01021                     break;
01022                 }
01023                 default:
01024                 {
01025                     OCI_ExceptionMappingArgument(stmt->con, stmt, type);
01026 
01027                     res = FALSE;
01028 
01029                     break;
01030                 }
01031             }
01032         }
01033     }
01034 
01035     return res;
01036 }
01037 
01038 /* ------------------------------------------------------------------------ *
01039  * OCI_StatementInit
01040  * ------------------------------------------------------------------------ */
01041 
01042 OCI_Statement * OCI_StatementInit(OCI_Connection *con, OCI_Statement **pstmt,
01043                                   OCIStmt *handle, OCI_Define *def)
01044 {
01045     OCI_Statement * stmt = NULL;
01046     boolean res = TRUE;
01047 
01048     OCI_CHECK(pstmt == NULL, NULL);
01049 
01050     if (*pstmt == NULL)
01051         *pstmt = (OCI_Statement *) OCI_MemAlloc(OCI_IPC_STATEMENT, sizeof(*stmt),
01052                                               1, TRUE);
01053 
01054     if (*pstmt != NULL)
01055     {
01056         stmt = *pstmt;
01057 
01058         stmt->con           = con;
01059         stmt->stmt          = handle;
01060 
01061         stmt->exec_mode     = OCI_DEFAULT;
01062         stmt->long_size     = OCI_SIZE_LONG;
01063         stmt->bind_reuse    = FALSE;
01064         stmt->bind_mode     = OCI_BIND_BY_NAME;
01065         stmt->long_mode     = OCI_LONG_EXPLICIT;
01066 
01067         /* reset statement */
01068 
01069         OCI_StatementReset(stmt);
01070 
01071         if (def == NULL)
01072         {
01073             /* allocate handle for non fetched lob (temporary lob) */
01074 
01075             stmt->hstate = OCI_OBJECT_ALLOCATED;
01076 
01077             /* allocate handle */
01078 
01079             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
01080                                                   (dvoid **) (void *) &stmt->stmt,
01081                                                   (ub4) OCI_HTYPE_STMT,
01082                                                   (size_t) 0, (dvoid **) NULL));
01083         }
01084         else
01085         {
01086             stmt->hstate = OCI_OBJECT_FETCHED_CLEAN;
01087             stmt->status = OCI_STMT_EXECUTED;
01088             stmt->type   = OCI_CST_SELECT;
01089 
01090             /* not really perfect, but better than nothing */
01091 
01092             if (def->col.name != NULL)
01093                 stmt->sql = mtsdup(def->col.name);
01094         }
01095 
01096         /* set statement default attributes */
01097 
01098         OCI_SetPrefetchSize(stmt, OCI_PREFETCH_SIZE);
01099         OCI_SetFetchSize(stmt, OCI_FETCH_SIZE);
01100     }
01101 
01102     /* check for failure */
01103 
01104     if (res == FALSE)
01105     {
01106         OCI_StatementFree(stmt);
01107         stmt = NULL;
01108     }
01109 
01110     return stmt;
01111 }
01112 
01113 /* ------------------------------------------------------------------------ *
01114  * OCI_StatementReset
01115  * ------------------------------------------------------------------------ */
01116 
01117 boolean OCI_StatementReset(OCI_Statement *stmt)
01118 {
01119     boolean res = TRUE;
01120 
01121     /* reset batch errors */
01122 
01123     res = OCI_BatchErrorClear(stmt);
01124 
01125     /* free resultsets */
01126 
01127     res = OCI_ReleaseResultsets(stmt);
01128 
01129     /* free in/out binds */
01130 
01131     res = OCI_BindFreeAll(stmt);
01132 
01133     /* free bind map */
01134 
01135     if (stmt->map != NULL)
01136     {
01137         OCI_HashFree(stmt->map);
01138     }
01139 
01140     /* free sql statement */
01141 
01142     OCI_FREE(stmt->sql);
01143 
01144     stmt->rsts        = NULL;
01145     stmt->sql         = NULL;
01146     stmt->map         = NULL;
01147     stmt->batch       = NULL;
01148 
01149     stmt->status      = OCI_STMT_CLOSED;
01150     stmt->type        = OCI_UNKNOWN;
01151     stmt->bind_array  = FALSE;
01152 
01153     stmt->nb_iters     = 1;
01154     stmt->dynidx       = 0;
01155     stmt->err_pos      = 0;
01156 
01157     return res;
01158 }
01159 
01160 /* ------------------------------------------------------------------------ *
01161  * OCI_StatementClose
01162  * ------------------------------------------------------------------------ */
01163 
01164 boolean OCI_StatementClose(OCI_Statement *stmt)
01165 {
01166     boolean res    = TRUE;
01167     OCI_Error *err = NULL;
01168 
01169     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01170 
01171     /* clear statement reference from current error object */
01172 
01173     err = OCI_ErrorGet(FALSE);
01174 
01175     if (err != NULL && err->stmt == stmt)
01176         err->stmt = NULL;
01177 
01178     /* reset data */
01179 
01180     res = OCI_StatementReset(stmt);
01181 
01182     if (stmt->stmt != NULL && stmt->hstate == OCI_OBJECT_ALLOCATED)
01183     {
01184         OCI_HandleFree((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT);
01185     }
01186 
01187     return res;
01188 }
01189 
01190 /* ------------------------------------------------------------------------ *
01191  * OCI_BatchErrorClear
01192  * ------------------------------------------------------------------------ */
01193 
01194 boolean OCI_BatchErrorClear(OCI_Statement *stmt)
01195 {
01196     if (stmt->batch != NULL)
01197     {
01198         /* free internal array of OCI_Errors */
01199 
01200         OCI_FREE(stmt->batch->errs);
01201 
01202         /* free batch structure */
01203 
01204         OCI_FREE(stmt->batch);
01205 
01206         stmt->batch = NULL;
01207     }
01208 
01209     return TRUE;
01210 }
01211 
01212 /* ------------------------------------------------------------------------ *
01213  * OCI_BatchErrorsInit
01214  * ------------------------------------------------------------------------ */
01215 
01216 boolean OCI_BatchErrorInit(OCI_Statement *stmt)
01217 {
01218     boolean res   = TRUE;
01219     ub4 err_count = 0;
01220 
01221     OCI_BatchErrorClear(stmt);
01222 
01223     /* all OCI call here are not checked for errors as we already dealing
01224        with an array DML error */
01225 
01226     OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
01227                (dvoid *) &err_count, (ub4 *) NULL,
01228                (ub4) OCI_ATTR_NUM_DML_ERRORS, stmt->con->err);
01229 
01230     if (err_count > 0)
01231     {
01232         OCIError *hndl = NULL;
01233 
01234         /* allocate batch error structure */
01235 
01236         stmt->batch = (OCI_BatchErrors *) OCI_MemAlloc(OCI_IPC_BATCH_ERRORS,
01237                                                        sizeof(*stmt->batch),
01238                                                        1, TRUE);
01239 
01240         res = (stmt->batch != NULL);
01241 
01242          /* allocate array of error objects */
01243 
01244         if (res == TRUE)
01245         {
01246             stmt->batch->errs = (OCI_Error *) OCI_MemAlloc(OCI_IPC_ERROR,
01247                                                            sizeof(*stmt->batch->errs),
01248                                                            err_count, TRUE);
01249 
01250             res = (stmt->batch->errs != NULL);
01251         }
01252 
01253         if (res == TRUE)
01254         {
01255             /* allocate OCI error handle */
01256 
01257             OCI_HandleAlloc((dvoid  *) OCILib.env,
01258                             (dvoid **) (void *) &hndl,
01259                             (ub4) OCI_HTYPE_ERROR,
01260                             (size_t) 0, (dvoid **) NULL);
01261 
01262             res = (hndl != NULL);
01263         }
01264 
01265         /* loop on the OCI errors to fill OCILIB error objects */
01266 
01267         if (res == TRUE)
01268         {
01269             ub4 i;
01270 
01271             stmt->batch->count = err_count;
01272 
01273             for (i = 0; i < stmt->batch->count; i++)
01274             {
01275                 int osize  = -1;
01276                 void *ostr = NULL;
01277 
01278                 OCI_Error *err = &stmt->batch->errs[i];
01279 
01280                 OCIParamGet((dvoid *) stmt->con->err, OCI_HTYPE_ERROR,
01281                             stmt->con->err, (dvoid **) (void *) &hndl, i);
01282 
01283                 /* get row offset */
01284 
01285                 OCIAttrGet((dvoid *) hndl, (ub4) OCI_HTYPE_ERROR,
01286                            (void *) &err->row, (ub4 *) NULL,
01287                            (ub4) OCI_ATTR_DML_ROW_OFFSET, stmt->con->err);
01288 
01289                 /* fill error attributes */
01290 
01291                 err->type = OCI_ERR_ORACLE;
01292                 err->con  = stmt->con;
01293                 err->stmt = stmt;
01294 
01295                 /* OCILIB indexes start at 1 */
01296 
01297                 err->row++;
01298 
01299                 /* get error string */
01300 
01301                 osize = msizeof(err->str) - 1;
01302 
01303                 ostr  = OCI_GetInputMetaString(err->str, &osize);
01304 
01305                 OCIErrorGet((dvoid *) hndl,
01306                             (ub4) 1,
01307                             (OraText *) NULL, &err->ocode,
01308                             (OraText *) ostr,
01309                             (ub4) osize,
01310                             (ub4) OCI_HTYPE_ERROR);
01311 
01312 
01313                 OCI_GetOutputMetaString(ostr, err->str, &osize);
01314                 OCI_ReleaseMetaString(ostr);
01315             }
01316         }
01317 
01318         /* release error handle */
01319 
01320         if (hndl != NULL)
01321         {
01322             OCI_HandleFree(hndl, OCI_HTYPE_ERROR);
01323         }
01324     }
01325 
01326     return res;
01327 }
01328 
01329 /* ************************************************************************ *
01330  *                            PUBLIC FUNCTIONS
01331  * ************************************************************************ */
01332 
01333 /* ------------------------------------------------------------------------ *
01334  * OCI_StatementCreate
01335  * ------------------------------------------------------------------------ */
01336 
01337 OCI_Statement * OCI_API OCI_StatementCreate(OCI_Connection *con)
01338 {
01339     OCI_Statement *stmt = NULL;
01340     OCI_Item *item      = NULL;
01341 
01342     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01343 
01344     /* create statement object */
01345 
01346     item = OCI_ListAppend(con->stmts, sizeof(*stmt));
01347 
01348     if (item != NULL)
01349     {
01350         stmt = OCI_StatementInit(con, (OCI_Statement **) &item->data, NULL, FALSE);
01351     }
01352 
01353     OCI_RESULT(stmt != NULL);
01354 
01355     return stmt;
01356 }
01357 
01358 /* ------------------------------------------------------------------------ *
01359  * OCI_StatementFree
01360  * ------------------------------------------------------------------------ */
01361 
01362 boolean OCI_API OCI_StatementFree(OCI_Statement *stmt)
01363 {
01364     boolean res = FALSE;
01365 
01366     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01367 
01368     OCI_CHECK_OBJECT_FETCHED(stmt, FALSE);
01369 
01370     res = OCI_StatementClose(stmt);
01371 
01372     OCI_ListRemove(stmt->con->stmts, stmt);
01373 
01374     OCI_FREE(stmt);
01375 
01376     OCI_RESULT(res);
01377 
01378     return res;
01379 }
01380 
01381 /* ------------------------------------------------------------------------ *
01382  * OCI_ReleaseResultsets
01383  * ------------------------------------------------------------------------ */
01384 
01385 boolean OCI_API OCI_ReleaseResultsets(OCI_Statement *stmt)
01386 {
01387     boolean res   = TRUE;
01388     ub4 i, nb_err = 0;
01389 
01390     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01391 
01392     if (stmt->rsts != NULL)
01393     {
01394         for (i = 0; i  < stmt->nb_rs; i++)
01395         {
01396             if (stmt->rsts[i] != NULL)
01397             {
01398                 if (FALSE == OCI_ResultsetFree(stmt->rsts[i]))
01399                     nb_err++;
01400             }
01401         }
01402 
01403         OCI_FREE(stmt->rsts);
01404     }
01405 
01406     res = (nb_err == 0);
01407 
01408     OCI_RESULT(res);
01409 
01410     return res;
01411 }
01412 
01413 /* ------------------------------------------------------------------------ *
01414  * OCI_Prepare
01415  * ------------------------------------------------------------------------ */
01416 
01417 boolean OCI_API OCI_Prepare(OCI_Statement *stmt, const mtext *sql)
01418 {
01419     boolean res = TRUE;
01420     void *ostr  = NULL;
01421     int  osize  = -1;
01422 
01423     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01424     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
01425 
01426     /* reset statement */
01427 
01428     res = OCI_StatementReset(stmt);
01429 
01430     if (res == TRUE)
01431     {
01432         /* store SQL */
01433 
01434         stmt->sql = mtsdup(sql);
01435 
01436         ostr = OCI_GetInputMetaString(stmt->sql, &osize);
01437 
01438         /* prepare SQL */
01439 
01440         OCI_CALL1
01441         (
01442             res, stmt->con, stmt,
01443 
01444             OCIStmtPrepare(stmt->stmt,stmt->con->err, (OraText *) ostr,
01445                            (ub4) osize, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT)
01446         )
01447 
01448         OCI_ReleaseMetaString(ostr);
01449 
01450         /* get statement type */
01451 
01452         OCI_CALL1
01453         (
01454             res, stmt->con, stmt,
01455 
01456             OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
01457                        (dvoid *) &stmt->type, (ub4 *) NULL,
01458                        (ub4) OCI_ATTR_STMT_TYPE, stmt->con->err)
01459         )
01460     }
01461 
01462     /* update statement status */
01463 
01464     if (res == TRUE)
01465         stmt->status = OCI_STMT_PREPARED;
01466 
01467     OCI_RESULT(res);
01468 
01469    return res;
01470 }
01471 
01472 /* ------------------------------------------------------------------------ *
01473  * OCI_Execute
01474  * ------------------------------------------------------------------------ */
01475 
01476 boolean OCI_API OCI_Execute(OCI_Statement *stmt)
01477 {
01478     boolean res   = TRUE;
01479     sword status  = OCI_SUCCESS;
01480     ub4 iters     = 0;
01481     ub4 mode      = OCI_DEFAULT;
01482 
01483     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01484     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_CLOSED, FALSE);
01485 
01486     /* set up iters and mode values for execution */
01487 
01488     if (stmt->type == OCI_CST_SELECT)
01489         mode  = stmt->exec_mode;
01490     else
01491     {
01492         iters = stmt->nb_iters;
01493 
01494         /* for array DML, use batch error mode */
01495 
01496         if (iters > 1)
01497         {
01498             mode = mode | OCI_BATCH_ERRORS;
01499         }
01500     }
01501 
01502     /* reset batch errors */
01503 
01504     res = OCI_BatchErrorClear(stmt);
01505 
01506     /* check bind objects for updating their null indicator status */
01507 
01508     res = OCI_BindCheck(stmt);
01509 
01510     /* free previous resulsets in case of re-execution of the same SQL order */
01511 
01512    if (res == TRUE)
01513        res = OCI_ReleaseResultsets(stmt);
01514 
01515     /* Oracle execute call */
01516 
01517     status = OCIStmtExecute(stmt->con->cxt, stmt->stmt, stmt->con->err, iters,
01518                             (ub4) 0, (OCISnapshot *) NULL, (OCISnapshot *) NULL,
01519                             mode);
01520 
01521     /* reset input binds indicators status even if execution failed */
01522 
01523     OCI_BindReset(stmt);
01524 
01525     /* check result */
01526 
01527     res = ((status == OCI_SUCCESS) || (status == OCI_NEED_DATA));
01528 
01529     /* update status on success */
01530 
01531     if (res == TRUE)
01532     {
01533         stmt->status = OCI_STMT_EXECUTED;
01534 
01535         /* commit if necessary */
01536 
01537         if (stmt->con->autocom == TRUE)
01538             OCI_Commit(stmt->con);
01539     }
01540     else
01541     {
01542         /* get parse error position type */
01543 
01544         /* (one of the rare OCI call not enclosed with a OCI_CALLX macro ...) */
01545 
01546 
01547         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
01548                    (dvoid *) &stmt->err_pos, (ub4 *) NULL,
01549                    (ub4) OCI_ATTR_PARSE_ERROR_OFFSET, stmt->con->err);
01550 
01551         /* raise exception */
01552 
01553         OCI_ExceptionOCI(stmt->con->err, stmt->con, stmt);
01554 
01555         /* build batch error list if the statement is array DML */
01556 
01557         if (mode & OCI_BATCH_ERRORS)
01558         {
01559             OCI_BatchErrorInit(stmt);
01560         }
01561     }
01562 
01563     OCI_RESULT(res);
01564 
01565     return res;
01566 }
01567 
01568 /* ------------------------------------------------------------------------ *
01569  * OCI_ExecuteStmt
01570  * ------------------------------------------------------------------------ */
01571 
01572 boolean OCI_API OCI_ExecuteStmt(OCI_Statement *stmt, const mtext *sql)
01573 {
01574     return (OCI_Prepare(stmt, sql) && OCI_Execute(stmt));
01575 }
01576 
01577 /* ------------------------------------------------------------------------ *
01578  * OCI_PrepareFmt
01579  * ------------------------------------------------------------------------ */
01580 
01581 boolean OCI_PrepareFmt(OCI_Statement *stmt, const mtext *sql, ...)
01582 {
01583     boolean res    = FALSE;
01584     mtext *sql_fmt = NULL;
01585     va_list args;
01586     int size;
01587 
01588     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01589     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
01590 
01591     /* first, get buffer size */
01592 
01593     va_start(args, sql);
01594 
01595     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
01596 
01597     va_end(args);
01598 
01599     if (size > 0)
01600     {
01601         /* allocate buffer */
01602 
01603         sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size+1),
01604                                          TRUE);
01605 
01606         if (sql_fmt != NULL)
01607         {
01608             /* format buffer */
01609 
01610             va_start(args, sql);
01611 
01612             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
01613             {
01614                /* parse buffer */
01615 
01616                res = OCI_Prepare(stmt, sql_fmt);
01617             }
01618 
01619             va_end(args);
01620 
01621             OCI_FREE(sql_fmt);
01622         }
01623     }
01624 
01625     OCI_RESULT(res);
01626 
01627     return res;
01628 }
01629 
01630 /* ------------------------------------------------------------------------ *
01631  * OCI_ExecuteStmtFmt
01632  * ------------------------------------------------------------------------ */
01633 
01634 boolean OCI_ExecuteStmtFmt(OCI_Statement *stmt, const mtext *sql, ...)
01635 {
01636     boolean res    = FALSE;
01637     mtext *sql_fmt = NULL;
01638     va_list args;
01639     int size;
01640 
01641     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01642     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
01643 
01644     /* first, get buffer size */
01645 
01646     va_start(args, sql);
01647 
01648     size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
01649 
01650     va_end(args);
01651 
01652     if (size > 0)
01653     {
01654         /* allocate buffer */
01655 
01656         sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext), (size+1),
01657                                          TRUE);
01658 
01659         if (sql_fmt != NULL)
01660         {
01661             /* format buffer */
01662 
01663             va_start(args, sql);
01664 
01665             if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
01666             {
01667                 /* prepare and execute SQL buffer */
01668 
01669                 res = (OCI_Prepare(stmt, sql_fmt) &&  OCI_Execute(stmt));
01670             }
01671 
01672             va_end(args);
01673 
01674             OCI_FREE(sql_fmt);
01675         }
01676     }
01677 
01678     OCI_RESULT(res);
01679 
01680     return res;
01681 }
01682 
01683 /* ------------------------------------------------------------------------ *
01684  * OCI_Immediate
01685  * ------------------------------------------------------------------------ */
01686 
01687 boolean OCI_Immediate(OCI_Connection *con, const mtext *sql, ...)
01688 {
01689     OCI_Statement *stmt = NULL;
01690     boolean res = FALSE;
01691     va_list args;
01692 
01693     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01694     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
01695 
01696     /* First, execute SQL */
01697 
01698     stmt = OCI_StatementCreate(con);
01699 
01700     if ((stmt != NULL) &&OCI_ExecuteStmt(stmt, sql))
01701     {
01702         /* get resultset and set up variables */
01703 
01704         if (OCI_GetStatementType(stmt) == OCI_CST_SELECT)
01705         {
01706             va_start(args, sql);
01707 
01708             res = OCI_FetchIntoUserVariables(stmt, args);
01709 
01710             va_end(args);
01711         }
01712 
01713         OCI_StatementFree(stmt);
01714     }
01715 
01716     OCI_RESULT(res);
01717 
01718     return res;
01719 }
01720 
01721 /* ------------------------------------------------------------------------ *
01722  * OCI_ImmediateFmt
01723  * ------------------------------------------------------------------------ */
01724 
01725 boolean OCI_ImmediateFmt(OCI_Connection *con, const mtext *sql, ...)
01726 {
01727     OCI_Statement *stmt = NULL;
01728     mtext *sql_fmt = NULL;
01729     boolean res = FALSE;
01730     va_list args;
01731     int size;
01732 
01733     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01734     OCI_CHECK_PTR(OCI_IPC_STRING, sql, FALSE);
01735 
01736     stmt = OCI_StatementCreate(con);
01737 
01738     if (stmt != NULL)
01739     {
01740         /* first, get buffer size */
01741 
01742         va_start(args, sql);
01743 
01744         size = OCI_ParseSqlFmt(stmt, NULL, sql, &args);
01745 
01746         va_end(args);
01747 
01748         if (size > 0)
01749         {
01750             /* allocate buffer */
01751 
01752             sql_fmt = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
01753                                              (size+1), TRUE);
01754 
01755             if (sql_fmt != NULL)
01756             {
01757                 /* format buffer */
01758 
01759                 va_start(args, sql);
01760 
01761                 if (OCI_ParseSqlFmt(stmt, sql_fmt, sql, &args) > 0)
01762                 {
01763                     /* prepare and execute SQL buffer */
01764 
01765                     res = (OCI_Prepare(stmt, sql_fmt) &&  OCI_Execute(stmt));
01766 
01767                     /* get resultset and set up variables */
01768 
01769                     if (res && (OCI_GetStatementType(stmt) == OCI_CST_SELECT))
01770                     {
01771                         res = OCI_FetchIntoUserVariables(stmt, args);
01772                     }
01773                 }
01774 
01775                 va_end(args);
01776 
01777                 OCI_FREE(sql_fmt);
01778             }
01779         }
01780 
01781         OCI_StatementFree(stmt);
01782     }
01783 
01784     OCI_RESULT(res);
01785 
01786     return res;
01787 }
01788 
01789 /* ------------------------------------------------------------------------ *
01790  * OCI_BindArraySetSize
01791  * ------------------------------------------------------------------------ */
01792 
01793 boolean OCI_API OCI_BindArraySetSize(OCI_Statement *stmt, unsigned int size)
01794 {
01795     boolean res = TRUE;
01796 
01797     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01798 
01799     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
01800 
01801     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_CLOSED, FALSE);
01802 
01803     /* if the statements already has binds, we need to check if the new size is
01804        not greater than the initial size
01805     */
01806 
01807     if ((stmt->nb_ubinds > 0) && (size > stmt->ubinds[0]->buf.count))
01808     {
01809         OCI_ExceptionBindArraySize(stmt, stmt->ubinds[0]->buf.count,
01810                                          stmt->nb_iters, size);
01811 
01812         res = FALSE;
01813     }
01814     else
01815     {
01816         stmt->nb_iters   = size;
01817         stmt->bind_array = TRUE;
01818     }
01819 
01820     OCI_RESULT(res);
01821 
01822     return res;
01823 }
01824 
01825 /* ------------------------------------------------------------------------ *
01826  * OCI_BindArrayGetSize
01827  * ------------------------------------------------------------------------ */
01828 
01829 unsigned int OCI_API OCI_BindArrayGetSize(OCI_Statement *stmt)
01830 {
01831     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01832 
01833     OCI_RESULT(TRUE);
01834 
01835     return stmt->nb_iters;
01836 }
01837 
01838 /* ------------------------------------------------------------------------ *
01839  * OCI_AllowRebinding
01840  * ------------------------------------------------------------------------ */
01841 
01842 OCI_EXPORT boolean OCI_API OCI_AllowRebinding(OCI_Statement *stmt, boolean value)
01843 {
01844     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
01845 
01846     OCI_RESULT(TRUE);
01847 
01848     stmt->bind_reuse = value;
01849 
01850     return TRUE;
01851 }
01852 
01853 /* ------------------------------------------------------------------------ *
01854  * OCI_BindShort
01855  * ------------------------------------------------------------------------ */
01856 
01857 boolean OCI_API OCI_BindShort(OCI_Statement *stmt, const mtext *name, short *data)
01858 {
01859     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
01860 
01861     return OCI_BindData(stmt, data, sizeof(short), name, OCI_CDT_NUMERIC,
01862                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_SHORT, NULL, 0);
01863 }
01864 
01865 /* ------------------------------------------------------------------------ *
01866  * OCI_BindArrayOfShorts
01867  * ------------------------------------------------------------------------ */
01868 
01869 boolean OCI_API OCI_BindArrayOfShorts(OCI_Statement *stmt, const mtext *name,
01870                                     short *data, unsigned int nbelem)
01871 {
01872     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
01873 
01874     return OCI_BindData(stmt, data, sizeof(short), name, OCI_CDT_NUMERIC,
01875                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_SHORT, NULL, nbelem);
01876 }
01877 
01878 /* ------------------------------------------------------------------------ *
01879  * OCI_BindUnsignedShort
01880  * ------------------------------------------------------------------------ */
01881 
01882 boolean OCI_API OCI_BindUnsignedShort(OCI_Statement *stmt, const mtext *name,
01883                                     unsigned short *data)
01884 {
01885     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
01886 
01887     return OCI_BindData(stmt, data, sizeof(unsigned short), name, OCI_CDT_NUMERIC,
01888                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_USHORT, NULL, 0);
01889 }
01890 
01891 /* ------------------------------------------------------------------------ *
01892  * OCI_BindArrayOfUnsignedShorts
01893  * ------------------------------------------------------------------------ */
01894 
01895 boolean OCI_API OCI_BindArrayOfUnsignedShorts(OCI_Statement *stmt,
01896                                             const mtext *name,
01897                                             unsigned short *data,
01898                                             unsigned int nbelem)
01899 {
01900     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_SHORT);
01901 
01902     return OCI_BindData(stmt, data, sizeof(unsigned short), name, OCI_CDT_NUMERIC,
01903                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_USHORT, NULL, nbelem);
01904 }
01905 
01906 /* ------------------------------------------------------------------------ *
01907  * OCI_BindInt
01908  * ------------------------------------------------------------------------ */
01909 
01910 boolean OCI_API OCI_BindInt(OCI_Statement *stmt, const mtext *name, int *data)
01911 {
01912     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
01913 
01914     return OCI_BindData(stmt, data, sizeof(int), name, OCI_CDT_NUMERIC,
01915                         SQLT_INT, OCI_BIND_INPUT, OCI_NUM_INT, NULL, 0);
01916 }
01917 
01918 /* ------------------------------------------------------------------------ *
01919  * OCI_BindArrayOfInts
01920  * ------------------------------------------------------------------------ */
01921 
01922 boolean OCI_API OCI_BindArrayOfInts(OCI_Statement *stmt, const mtext *name,
01923                                     int *data, unsigned int nbelem)
01924 {
01925     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
01926 
01927    return OCI_BindData(stmt, data, sizeof(int), name, OCI_CDT_NUMERIC,
01928                        SQLT_INT, OCI_BIND_INPUT, OCI_NUM_INT, NULL, nbelem);
01929 }
01930 
01931 /* ------------------------------------------------------------------------ *
01932  * OCI_BindUnsignedInt
01933  * ------------------------------------------------------------------------ */
01934 
01935 boolean OCI_API OCI_BindUnsignedInt(OCI_Statement *stmt, const mtext *name,
01936                                     unsigned int *data)
01937 {
01938     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
01939 
01940     return OCI_BindData(stmt, data, sizeof(unsigned int), name, OCI_CDT_NUMERIC,
01941                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_UINT, NULL, 0);
01942 }
01943 
01944 /* ------------------------------------------------------------------------ *
01945  * OCI_BindArrayOfUnsignedInts
01946  * ------------------------------------------------------------------------ */
01947 
01948 boolean OCI_API OCI_BindArrayOfUnsignedInts(OCI_Statement *stmt, const mtext *name,
01949                                             unsigned int *data, unsigned int nbelem)
01950 {
01951     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INT);
01952 
01953     return OCI_BindData(stmt, data, sizeof(unsigned int), name, OCI_CDT_NUMERIC,
01954                         SQLT_UIN, OCI_BIND_INPUT, OCI_NUM_UINT, NULL, nbelem);
01955 }
01956 
01957 /* ------------------------------------------------------------------------ *
01958  * OCI_BindBigInt
01959  * ------------------------------------------------------------------------ */
01960 
01961 boolean OCI_API OCI_BindBigInt(OCI_Statement *stmt, const mtext *name,
01962                                big_int *data)
01963 {
01964     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
01965 
01966     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
01967                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGINT, NULL, 0);
01968 }
01969 
01970 /* ------------------------------------------------------------------------ *
01971  * OCI_BindArrayOfBigInts
01972  * ------------------------------------------------------------------------ */
01973 
01974 boolean OCI_API OCI_BindArrayOfBigInts(OCI_Statement *stmt, const mtext *name,
01975                                        big_int *data, unsigned int nbelem)
01976 {
01977     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
01978 
01979     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
01980                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGINT, NULL, nbelem);
01981 }
01982 
01983 /* ------------------------------------------------------------------------ *
01984  * OCI_BindUnsignedBigInt
01985  * ------------------------------------------------------------------------ */
01986 
01987 boolean OCI_API OCI_BindUnsignedBigInt(OCI_Statement *stmt, const mtext *name,
01988                                       big_uint *data)
01989 {
01990     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
01991 
01992     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
01993                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGUINT, NULL, 0);
01994 }
01995 
01996 /* ------------------------------------------------------------------------ *
01997  * OCI_BindArrayOfUnsignedInts
01998  * ------------------------------------------------------------------------ */
01999 
02000 boolean OCI_API OCI_BindArrayOfUnsignedBigInts(OCI_Statement *stmt,
02001                                                const mtext *name,
02002                                                big_uint *data,
02003                                                unsigned int nbelem)
02004 {
02005     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_BIGINT);
02006 
02007     return OCI_BindData(stmt, data, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02008                         SQLT_VNU, OCI_BIND_INPUT, OCI_NUM_BIGUINT, NULL, nbelem);
02009 }
02010 
02011 /* ------------------------------------------------------------------------ *
02012  * OCI_BindString
02013  * ------------------------------------------------------------------------ */
02014 
02015 boolean OCI_API OCI_BindString(OCI_Statement *stmt, const mtext *name,
02016                                dtext *data, unsigned int len)
02017 {
02018     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_STRING);
02019 
02020     if (len == 0 || len == UINT_MAX)
02021         len = (int) dtslen(data);
02022 
02023     return OCI_BindData(stmt, data, (len + 1) * sizeof(odtext), name, OCI_CDT_TEXT,
02024                         SQLT_STR, OCI_BIND_INPUT, 0, NULL, 0);
02025 }
02026 
02027 /* ------------------------------------------------------------------------ *
02028  * OCI_BindArrayOfStrings
02029  * ------------------------------------------------------------------------ */
02030 
02031 boolean OCI_API OCI_BindArrayOfStrings(OCI_Statement *stmt, const mtext *name,
02032                                        dtext *data, unsigned int len,
02033                                        unsigned int nbelem)
02034 {
02035     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_STRING);
02036 
02037     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02038 
02039     return OCI_BindData(stmt, data, (len + 1) * sizeof(odtext), name, OCI_CDT_TEXT,
02040                         SQLT_STR, OCI_BIND_INPUT, 0, NULL, nbelem);
02041 }
02042 
02043 /* ------------------------------------------------------------------------ *
02044  * OCI_BindRaw
02045  * ------------------------------------------------------------------------ */
02046 
02047 boolean OCI_API OCI_BindRaw(OCI_Statement *stmt, const mtext *name, void *data,
02048                                unsigned int len)
02049 {
02050     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_VOID);
02051 
02052     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02053 
02054     return OCI_BindData(stmt, data, len, name, OCI_CDT_RAW,
02055                         SQLT_BIN, OCI_BIND_INPUT, 0, NULL, 0);
02056 }
02057 
02058 /* ------------------------------------------------------------------------ *
02059  * OCI_BindArrayOfRaws
02060  * ------------------------------------------------------------------------ */
02061 
02062 boolean OCI_API OCI_BindArrayOfRaws(OCI_Statement *stmt, const mtext *name,
02063                                        void  *data, unsigned int len,
02064                                        unsigned int nbelem)
02065 {
02066     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_VOID);
02067 
02068     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02069 
02070     return OCI_BindData(stmt, data, len, name, OCI_CDT_RAW,
02071                         SQLT_BIN, OCI_BIND_INPUT, 0, NULL, nbelem);
02072 }
02073 
02074 /* ------------------------------------------------------------------------ *
02075  * OCI_BindDouble
02076  * ------------------------------------------------------------------------ */
02077 
02078 boolean OCI_API OCI_BindDouble(OCI_Statement *stmt, const mtext *name,
02079                                double *data)
02080 {
02081     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DOUBLE);
02082 
02083     return OCI_BindData(stmt, data, sizeof(double), name, OCI_CDT_NUMERIC,
02084                         SQLT_FLT, OCI_BIND_INPUT, 0, NULL, 0);
02085 }
02086 
02087 /* ------------------------------------------------------------------------ *
02088  * OCI_BindArrayOfDoubles
02089  * ------------------------------------------------------------------------ */
02090 
02091 boolean OCI_API OCI_BindArrayOfDoubles(OCI_Statement *stmt, const mtext *name,
02092                                        double *data, unsigned int nbelem)
02093 {
02094     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DOUBLE);
02095 
02096     return OCI_BindData(stmt, data, sizeof(double), name, OCI_CDT_NUMERIC,
02097                         SQLT_FLT, OCI_BIND_INPUT, 0, NULL, nbelem);
02098 }
02099 
02100 /* ------------------------------------------------------------------------ *
02101  * OCI_BindDate
02102  * ------------------------------------------------------------------------ */
02103 
02104 boolean OCI_API OCI_BindDate(OCI_Statement *stmt, const mtext *name,
02105                              OCI_Date *data)
02106 {
02107     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DATE);
02108 
02109     return OCI_BindData(stmt, data, sizeof(OCIDate), name, OCI_CDT_DATETIME,
02110                         SQLT_ODT, OCI_BIND_INPUT, 0, NULL, 0);
02111 }
02112 
02113 /* ------------------------------------------------------------------------ *
02114  * OCI_BindArrayOfDates
02115  * ------------------------------------------------------------------------ */
02116 
02117 boolean OCI_API OCI_BindArrayOfDates(OCI_Statement *stmt, const mtext *name,
02118                                      OCI_Date **data, unsigned int nbelem)
02119 {
02120     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_DATE);
02121 
02122     return OCI_BindData(stmt, data, sizeof(OCIDate), name, OCI_CDT_DATETIME,
02123                         SQLT_ODT, OCI_BIND_INPUT, 0, NULL, nbelem);
02124 }
02125 
02126 /* ------------------------------------------------------------------------ *
02127  * OCI_BindTimestamp
02128  * ------------------------------------------------------------------------ */
02129 
02130 boolean OCI_API OCI_BindTimestamp(OCI_Statement *stmt, const mtext *name,
02131                                   OCI_Timestamp *data)
02132 {
02133     int code    = 0;
02134     boolean res = FALSE;
02135 
02136     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_TIMESTAMP);
02137 
02138     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
02139 
02140 #if OCI_VERSION_COMPILE >= OCI_9_0
02141 
02142     /* map oracle internal type */
02143 
02144     if (data->type == OCI_TIMESTAMP_TZ)
02145         code = SQLT_TIMESTAMP_TZ;
02146     else if (data->type == OCI_TIMESTAMP_LTZ)
02147         code = SQLT_TIMESTAMP_LTZ;
02148     else
02149         code = SQLT_TIMESTAMP;
02150 
02151     res = OCI_BindData(stmt, data, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
02152                        code, OCI_BIND_INPUT, data->type, NULL, 0);
02153 
02154 #else
02155 
02156     OCI_NOT_USED(name);
02157     OCI_NOT_USED(code);
02158     OCI_NOT_USED(code);
02159 
02160 #endif
02161 
02162     return res;
02163 }
02164 
02165 /* ------------------------------------------------------------------------ *
02166  * OCI_BindArrayOfTimestamps
02167  * ------------------------------------------------------------------------ */
02168 
02169 boolean OCI_API OCI_BindArrayOfTimestamps(OCI_Statement *stmt, const mtext *name,
02170                                           OCI_Timestamp **data,
02171                                           unsigned int type,
02172                                           unsigned int nbelem)
02173 {
02174     unsigned int code    = 0;
02175     boolean res          = FALSE;
02176 
02177     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_TIMESTAMP);
02178 
02179     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
02180 
02181 #if OCI_VERSION_COMPILE >= OCI_9_0
02182 
02183     /* map oracle internal type */
02184 
02185     if (type == OCI_TIMESTAMP_TZ)
02186         code = SQLT_TIMESTAMP_TZ;
02187     else if (type == OCI_TIMESTAMP_LTZ)
02188         code = SQLT_TIMESTAMP_LTZ;
02189     else
02190         code = SQLT_TIMESTAMP;
02191 
02192     res =  OCI_BindData(stmt, data, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
02193                         code, OCI_BIND_INPUT, type, NULL, nbelem);
02194 
02195 #else
02196 
02197     OCI_NOT_USED(name);
02198     OCI_NOT_USED(type);
02199     OCI_NOT_USED(code);
02200     OCI_NOT_USED(nbelem);
02201 
02202 #endif
02203 
02204     return res;
02205 }
02206 
02207 /* ------------------------------------------------------------------------ *
02208  * OCI_BindInterval
02209  * ------------------------------------------------------------------------ */
02210 
02211 boolean OCI_API OCI_BindInterval(OCI_Statement *stmt, const mtext *name,
02212                                   OCI_Interval *data)
02213 {
02214     int code    = 0;
02215     boolean res = FALSE;
02216 
02217     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INTERVAL);
02218 
02219     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
02220 
02221 #if OCI_VERSION_COMPILE >= OCI_9_0
02222 
02223     /* map oracle internal type */
02224 
02225     if (data->type == OCI_INTERVAL_YM)
02226         code = SQLT_INTERVAL_YM;
02227     else if (data->type == OCI_INTERVAL_DS)
02228         code = SQLT_INTERVAL_DS;
02229 
02230     res = OCI_BindData(stmt, data, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
02231                        code, OCI_BIND_INPUT, data->type, NULL, 0);
02232 
02233 #else
02234 
02235     OCI_NOT_USED(name);
02236     OCI_NOT_USED(code);
02237 
02238 #endif
02239 
02240     return res;
02241 }
02242 
02243 /* ------------------------------------------------------------------------ *
02244  * OCI_BindArrayOfIntervals
02245  * ------------------------------------------------------------------------ */
02246 
02247 boolean OCI_API OCI_BindArrayOfIntervals(OCI_Statement *stmt, const mtext *name,
02248                                          OCI_Interval **data,
02249                                          unsigned int type,
02250                                          unsigned int nbelem)
02251 {
02252     unsigned int code = 0;
02253     boolean res       = FALSE;
02254 
02255     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_INTERVAL);
02256 
02257     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
02258 
02259 #if OCI_VERSION_COMPILE >= OCI_9_0
02260 
02261     /* map oracle internal type */
02262 
02263     if (type == OCI_INTERVAL_YM)
02264         code = SQLT_INTERVAL_YM;
02265     else if (type == OCI_INTERVAL_DS)
02266         code = SQLT_INTERVAL_DS;
02267 
02268     res = OCI_BindData(stmt, data, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
02269                        code, OCI_BIND_INPUT, type, NULL, nbelem);
02270 
02271 #else
02272 
02273     OCI_NOT_USED(name);
02274     OCI_NOT_USED(type);
02275     OCI_NOT_USED(code);
02276     OCI_NOT_USED(nbelem);
02277 
02278 #endif
02279 
02280     return res;
02281 }
02282 
02283 /* ------------------------------------------------------------------------ *
02284  * OCI_BindObject
02285  * ------------------------------------------------------------------------ */
02286 
02287 boolean OCI_API OCI_BindObject(OCI_Statement *stmt, const mtext *name,
02288                                OCI_Object *data)
02289 {
02290     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_OBJECT);
02291 
02292     return OCI_BindData(stmt, data, sizeof(void*), name, OCI_CDT_OBJECT,
02293                         SQLT_NTY, OCI_BIND_INPUT, 0, data->typinf, 0);
02294 }
02295 
02296 /* ------------------------------------------------------------------------ *
02297  * OCI_BindArrayOfObjects
02298  * ------------------------------------------------------------------------ */
02299 
02300 boolean OCI_API OCI_BindArrayOfObjects(OCI_Statement *stmt, const mtext *name,
02301                                        OCI_Object **data, OCI_TypeInfo *typinf,
02302                                        unsigned int nbelem)
02303 {
02304     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_OBJECT);
02305 
02306     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
02307 
02308     return OCI_BindData(stmt, data, sizeof(void *), name, OCI_CDT_OBJECT,
02309                         SQLT_NTY, OCI_BIND_INPUT, 0, typinf, nbelem);
02310 }
02311 
02312 /* ------------------------------------------------------------------------ *
02313  * OCI_BindLob
02314  * ------------------------------------------------------------------------ */
02315 
02316 boolean OCI_API OCI_BindLob(OCI_Statement *stmt, const mtext *name,
02317                             OCI_Lob *data)
02318 {
02319     int code = 0;
02320 
02321     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_LOB);
02322 
02323     /* map oracle internal type */
02324 
02325     if (data->type == OCI_CLOB || data->type == OCI_NCLOB)
02326         code = SQLT_CLOB;
02327     else
02328         code = SQLT_BLOB;
02329 
02330     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
02331                         code, OCI_BIND_INPUT, data->type, NULL, 0);
02332 }
02333 
02334 /* ------------------------------------------------------------------------ *
02335  * OCI_BindArrayOfLobs
02336  * ------------------------------------------------------------------------ */
02337 
02338 boolean OCI_API OCI_BindArrayOfLobs(OCI_Statement *stmt, const mtext *name,
02339                                     OCI_Lob **data, unsigned int type,
02340                                     unsigned int nbelem)
02341 {
02342     unsigned int code = 0;
02343 
02344     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_LOB);
02345 
02346     /* map oracle internal type */
02347 
02348     if (type == OCI_CLOB || type == OCI_NCLOB)
02349         code = SQLT_CLOB;
02350     else
02351         code = SQLT_BLOB;
02352 
02353     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
02354                         code, OCI_BIND_INPUT, type, NULL, nbelem);
02355 }
02356 
02357 /* ------------------------------------------------------------------------ *
02358  * OCI_BindFile
02359  * ------------------------------------------------------------------------ */
02360 
02361 boolean OCI_API OCI_BindFile(OCI_Statement *stmt, const mtext *name,
02362                              OCI_File *data)
02363 {
02364     int code = 0;
02365 
02366     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_FILE);
02367 
02368     /* map oracle internal type */
02369 
02370     if (data->type == OCI_CFILE)
02371         code = SQLT_CFILE;
02372     else
02373         code = SQLT_BFILE;
02374 
02375     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
02376                         code, OCI_BIND_INPUT, data->type, NULL, 0);
02377 }
02378 
02379 /* ------------------------------------------------------------------------ *
02380  * OCI_BindArrayOfFiles
02381  * ------------------------------------------------------------------------ */
02382 
02383 boolean OCI_API OCI_BindArrayOfFiles(OCI_Statement *stmt, const mtext *name,
02384                                      OCI_File **data, unsigned int type,
02385                                      unsigned int nbelem)
02386 {
02387     unsigned int code = 0;
02388 
02389     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_FILE);
02390 
02391     /* map oracle internal type */
02392 
02393     if (type == OCI_CFILE)
02394         code = SQLT_CFILE;
02395     else
02396         code = SQLT_BFILE;
02397 
02398     return OCI_BindData(stmt, data, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
02399                         code, OCI_BIND_INPUT, type, NULL, nbelem);
02400 }
02401 
02402 /* ------------------------------------------------------------------------ *
02403  * OCI_BindRef
02404  * ------------------------------------------------------------------------ */
02405 
02406 boolean OCI_API OCI_BindRef(OCI_Statement *stmt, const mtext *name, OCI_Ref *data)
02407 {
02408     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_REF);
02409 
02410     return OCI_BindData(stmt, data, sizeof(OCIRef *), name, OCI_CDT_REF,
02411                         SQLT_REF, OCI_BIND_INPUT, 0, data->typinf, 0);
02412 }
02413 
02414 /* ------------------------------------------------------------------------ *
02415  * OCI_BindArrayOfRefs
02416  * ------------------------------------------------------------------------ */
02417 
02418 boolean OCI_API OCI_BindArrayOfRefs(OCI_Statement *stmt, const mtext *name,
02419                                      OCI_Ref **data, OCI_TypeInfo *typinf,
02420                                      unsigned int nbelem)
02421 {
02422     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_REF);
02423 
02424     return OCI_BindData(stmt, data, sizeof(OCIRef *), name, OCI_CDT_REF,
02425                         SQLT_REF, OCI_BIND_INPUT, 0, typinf, nbelem);
02426 }
02427 
02428 /* ------------------------------------------------------------------------ *
02429  * OCI_BindColl
02430  * ------------------------------------------------------------------------ */
02431 
02432 boolean OCI_API OCI_BindColl(OCI_Statement *stmt, const mtext *name,
02433                              OCI_Coll *data)
02434 {
02435     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_COLLECTION);
02436 
02437     return OCI_BindData(stmt, data, sizeof(OCIColl*), name,
02438                         OCI_CDT_COLLECTION, SQLT_NTY, OCI_BIND_INPUT, 0,
02439                         data->typinf, 0);
02440 }
02441 
02442 
02443 /* ------------------------------------------------------------------------ *
02444  * OCI_BindArrayOfColls
02445  * ------------------------------------------------------------------------ */
02446 
02447 boolean OCI_API OCI_BindArrayOfColls(OCI_Statement *stmt, const mtext *name,
02448                                      OCI_Coll **data, OCI_TypeInfo *typinf,
02449                                      unsigned int nbelem)
02450 {
02451     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_COLLECTION);
02452 
02453     return OCI_BindData(stmt, data, sizeof(OCIColl*), name,
02454                         OCI_CDT_COLLECTION, SQLT_NTY, OCI_BIND_INPUT, 0,
02455                         typinf, nbelem);
02456 }
02457 
02458 /* ------------------------------------------------------------------------ *
02459  * OCI_BindStatement
02460  * ------------------------------------------------------------------------ */
02461 
02462 boolean OCI_API OCI_BindStatement(OCI_Statement *stmt, const mtext *name,
02463                                   OCI_Statement *data)
02464 {
02465     boolean res = FALSE;
02466 
02467     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_STATEMENT);
02468 
02469     OCI_StatementReset(data);
02470 
02471     res = OCI_BindData(stmt, &data->stmt, sizeof(OCIStmt*), name, OCI_CDT_CURSOR,
02472                       SQLT_RSET, OCI_BIND_INPUT, 0, NULL, 0);
02473 
02474     if (res == TRUE)
02475     {
02476         /* Once stmt is executed, Oracle provides a statement handle
02477            ready to be fetched  */
02478 
02479         data->status  = OCI_STMT_EXECUTED;
02480         data->type    = OCI_CST_SELECT;
02481     }
02482 
02483     return res;
02484 }
02485 
02486 /* ------------------------------------------------------------------------ *
02487  * OCI_BindLong
02488  * ------------------------------------------------------------------------ */
02489 
02490 boolean OCI_API OCI_BindLong(OCI_Statement *stmt, const mtext *name,
02491                              OCI_Long *data, unsigned int size)
02492 {
02493     int code = 0;
02494 
02495     OCI_CHECK_BIND_CALL(stmt, name, data, OCI_IPC_LONG);
02496 
02497     /* map oracle internal type */
02498 
02499     if (data->type == OCI_CLONG)
02500         code = SQLT_LNG;
02501     else
02502         code = SQLT_LBI;
02503 
02504     if (data->type == OCI_CLONG)
02505         size *= sizeof(dtext);
02506 
02507     return OCI_BindData(stmt, data, size, name, OCI_CDT_LONG,
02508                         code, OCI_BIND_INPUT, data->type, NULL, 0);
02509 }
02510 
02511 /* ------------------------------------------------------------------------ *
02512  * OCI_RegisterShort
02513  * ------------------------------------------------------------------------ */
02514 
02515 boolean OCI_API OCI_RegisterShort(OCI_Statement *stmt, const mtext *name)
02516 {
02517     OCI_CHECK_REGISTER_CALL(stmt, name);
02518 
02519     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02520                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_SHORT, NULL, 0);
02521 }
02522 
02523 /* ------------------------------------------------------------------------ *
02524  * OCI_RegisterUnsignedShort
02525  * ------------------------------------------------------------------------ */
02526 
02527 boolean OCI_API OCI_RegisterUnsignedShort(OCI_Statement *stmt, const mtext *name)
02528 {
02529     OCI_CHECK_REGISTER_CALL(stmt, name);
02530 
02531     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02532                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_USHORT, NULL, 0);
02533 }
02534 
02535 /* ------------------------------------------------------------------------ *
02536  * OCI_RegisterInt
02537  * ------------------------------------------------------------------------ */
02538 
02539 boolean OCI_API OCI_RegisterInt(OCI_Statement *stmt, const mtext *name)
02540 {
02541     OCI_CHECK_REGISTER_CALL(stmt, name);
02542 
02543     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02544                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_INT, NULL, 0);
02545 }
02546 
02547 /* ------------------------------------------------------------------------ *
02548  * OCI_RegisterUnsignedInt
02549  * ------------------------------------------------------------------------ */
02550 
02551 boolean OCI_API OCI_RegisterUnsignedInt(OCI_Statement *stmt, const mtext *name)
02552 {
02553     OCI_CHECK_REGISTER_CALL(stmt, name);
02554 
02555     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02556                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_UINT, NULL, 0);
02557 }
02558 
02559 /* ------------------------------------------------------------------------ *
02560  * OCI_RegisterBigInt
02561  * ------------------------------------------------------------------------ */
02562 
02563 boolean OCI_API OCI_RegisterBigInt(OCI_Statement *stmt, const mtext *name)
02564 {
02565     OCI_CHECK_REGISTER_CALL(stmt, name);
02566 
02567     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02568                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_BIGINT, NULL, 0);
02569 }
02570 
02571 /* ------------------------------------------------------------------------ *
02572  * OCI_RegisterUnsignedBigInt
02573  * ------------------------------------------------------------------------ */
02574 
02575 boolean OCI_API OCI_RegisterUnsignedBigInt(OCI_Statement *stmt, const mtext *name)
02576 {
02577     OCI_CHECK_REGISTER_CALL(stmt, name);
02578 
02579     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02580                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_BIGUINT, NULL, 0);
02581 }
02582 
02583 /* ------------------------------------------------------------------------ *
02584  * OCI_RegisterString
02585  * ------------------------------------------------------------------------ */
02586 
02587 boolean OCI_API OCI_RegisterString(OCI_Statement *stmt, const mtext *name,
02588                                    unsigned int len)
02589 {
02590     OCI_CHECK_REGISTER_CALL(stmt, name);
02591 
02592     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02593 
02594     return OCI_BindData(stmt, NULL, (len+1)*sizeof(odtext), name, OCI_CDT_TEXT,
02595                         SQLT_STR, OCI_BIND_OUTPUT, 0, NULL, 0);
02596 }
02597 
02598 /* ------------------------------------------------------------------------ *
02599  * OCI_RegisterRaw
02600  * ------------------------------------------------------------------------ */
02601 
02602 boolean OCI_API OCI_RegisterRaw(OCI_Statement *stmt, const mtext *name,
02603                                 unsigned int len)
02604 {
02605     OCI_CHECK_REGISTER_CALL(stmt, name);
02606 
02607     OCI_CHECK_MIN(stmt->con, stmt, len, 1, FALSE);
02608 
02609     return OCI_BindData(stmt, NULL, len, name, OCI_CDT_RAW,
02610                         SQLT_BIN, OCI_BIND_OUTPUT, 0, NULL, 0);
02611 }
02612 
02613 /* ------------------------------------------------------------------------ *
02614  * OCI_RegisterDouble
02615  * ------------------------------------------------------------------------ */
02616 
02617 boolean OCI_API OCI_RegisterDouble(OCI_Statement *stmt, const mtext *name)
02618 {
02619     OCI_CHECK_REGISTER_CALL(stmt, name);
02620 
02621     return OCI_BindData(stmt, NULL, sizeof(OCINumber), name, OCI_CDT_NUMERIC,
02622                         SQLT_VNU, OCI_BIND_OUTPUT, OCI_NUM_DOUBLE, NULL, 0);
02623 }
02624 
02625 /* ------------------------------------------------------------------------ *
02626  * OCI_RegisterDate
02627  * ------------------------------------------------------------------------ */
02628 
02629 boolean OCI_API OCI_RegisterDate(OCI_Statement *stmt, const mtext *name)
02630 {
02631     int code = SQLT_ODT;
02632     int size = sizeof(OCIDate);
02633 
02634     OCI_CHECK_REGISTER_CALL(stmt, name);
02635 
02636     /* versions of OCI (< 10.2) crashes if SQLT_ODT is passed for output
02637        data with returning clause.
02638        It's an Oracle known bug #3269146 */
02639 
02640     if (OCI_GetVersionConnection(stmt->con) < OCI_10_2)
02641     {
02642         code = SQLT_DAT;
02643         size = 7;
02644     }
02645 
02646     return OCI_BindData(stmt, NULL, size, name, OCI_CDT_DATETIME,
02647                         code, OCI_BIND_OUTPUT, 0, NULL, 0);
02648 }
02649 
02650 /* ------------------------------------------------------------------------ *
02651  * OCI_RegisterTimestamp
02652  * ------------------------------------------------------------------------ */
02653 
02654 boolean OCI_API OCI_RegisterTimestamp(OCI_Statement *stmt, const mtext *name,
02655                                       unsigned int type)
02656 {
02657     int code    = 0;
02658     boolean res = FALSE;
02659 
02660     OCI_CHECK_REGISTER_CALL(stmt, name);
02661 
02662     OCI_CHECK_TIMESTAMP_ENABLED(stmt->con, FALSE);
02663 
02664 #if OCI_VERSION_COMPILE >= OCI_9_0
02665 
02666     /* map oracle internal type */
02667 
02668     if (type == OCI_TIMESTAMP_TZ)
02669         code = SQLT_TIMESTAMP_TZ;
02670     else if (type == OCI_TIMESTAMP_LTZ)
02671         code = SQLT_TIMESTAMP_LTZ;
02672     else
02673         code = SQLT_TIMESTAMP;
02674 
02675     res = OCI_BindData(stmt, NULL, sizeof(OCIDateTime *), name, OCI_CDT_TIMESTAMP,
02676                        code, OCI_BIND_OUTPUT, type, NULL, 0);
02677 
02678 #else
02679 
02680     OCI_NOT_USED(name);
02681     OCI_NOT_USED(type);
02682     OCI_NOT_USED(code);
02683 
02684 #endif
02685 
02686     return res;
02687 }
02688 
02689 /* ------------------------------------------------------------------------ *
02690  * OCI_RegisterInterval
02691  * ------------------------------------------------------------------------ */
02692 
02693 boolean OCI_API OCI_RegisterInterval(OCI_Statement *stmt, const mtext *name,
02694                                      unsigned int type)
02695 {
02696     unsigned int code    = 0;
02697     boolean res          = FALSE;
02698 
02699     OCI_CHECK_REGISTER_CALL(stmt, name);
02700 
02701     OCI_CHECK_INTERVAL_ENABLED(stmt->con, FALSE);
02702 
02703 #if OCI_VERSION_COMPILE >= OCI_9_0
02704 
02705     /* map oracle internal type */
02706 
02707     if (type == OCI_INTERVAL_YM)
02708         code = SQLT_INTERVAL_YM;
02709     else if (type == OCI_INTERVAL_DS)
02710         code = SQLT_INTERVAL_DS;
02711 
02712     res = OCI_BindData(stmt, NULL, sizeof(OCIInterval *), name, OCI_CDT_INTERVAL,
02713                        code, OCI_BIND_OUTPUT, type, NULL, 0);
02714 
02715 #else
02716 
02717     OCI_NOT_USED(name);
02718     OCI_NOT_USED(type);
02719     OCI_NOT_USED(code);
02720 
02721 #endif
02722 
02723     return res;
02724 }
02725 
02726 /* ------------------------------------------------------------------------ *
02727  * OCI_RegisterObject
02728  * ------------------------------------------------------------------------ */
02729 
02730 boolean OCI_API OCI_RegisterObject(OCI_Statement *stmt, const mtext *name,
02731                                    OCI_TypeInfo *typinf)
02732 {
02733     OCI_CHECK_REGISTER_CALL(stmt, name);
02734 
02735     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
02736 
02737     return OCI_BindData(stmt, NULL, sizeof(OCIInterval *), name, OCI_CDT_OBJECT,
02738                         SQLT_NTY, OCI_BIND_OUTPUT, 0, typinf, 0);
02739 }
02740 
02741 /* ------------------------------------------------------------------------ *
02742  * OCI_RegisterLob
02743  * ------------------------------------------------------------------------ */
02744 
02745 boolean OCI_API OCI_RegisterLob(OCI_Statement *stmt, const mtext *name,
02746                                 unsigned int type)
02747 {
02748     unsigned int code = 0;
02749 
02750     OCI_CHECK_REGISTER_CALL(stmt, name);
02751 
02752     /* map oracle internal type */
02753 
02754     if (type == OCI_CLOB || type == OCI_NCLOB)
02755         code = SQLT_CLOB;
02756     else
02757         code = SQLT_BLOB;
02758 
02759     return OCI_BindData(stmt, NULL, sizeof(OCILobLocator*), name, OCI_CDT_LOB,
02760                         code, OCI_BIND_OUTPUT, type, NULL, 0);
02761 }
02762 
02763 /* ------------------------------------------------------------------------ *
02764  * OCI_RegisterFile
02765  * ------------------------------------------------------------------------ */
02766 
02767 boolean OCI_API OCI_RegisterFile(OCI_Statement *stmt, const mtext *name,
02768                                  unsigned int type)
02769 {
02770     unsigned int code;
02771 
02772     OCI_CHECK_REGISTER_CALL(stmt, name);
02773 
02774     /* map oracle internal type */
02775 
02776     if (type == OCI_CFILE)
02777         code = SQLT_CFILE;
02778     else
02779         code = SQLT_BFILE;
02780 
02781     return OCI_BindData(stmt, NULL, sizeof(OCILobLocator*), name, OCI_CDT_FILE,
02782                         code, OCI_BIND_OUTPUT, type, NULL, 0);
02783 }
02784 
02785 
02786 /* ------------------------------------------------------------------------ *
02787  * OCI_RegisterRef
02788  * ------------------------------------------------------------------------ */
02789 
02790 boolean OCI_API OCI_RegisterRef(OCI_Statement *stmt, const mtext *name,
02791                                 OCI_TypeInfo *typinf)
02792 {
02793     OCI_CHECK_REGISTER_CALL(stmt, name);
02794 
02795     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, FALSE);
02796 
02797     return OCI_BindData(stmt, NULL, sizeof(OCIRef *), name, OCI_CDT_REF,
02798                         SQLT_REF, OCI_BIND_OUTPUT, 0, typinf, 0);
02799 }
02800 
02801 /* ------------------------------------------------------------------------ *
02802  * OCI_GetStatementType
02803  * ------------------------------------------------------------------------ */
02804 
02805 unsigned int OCI_API OCI_GetStatementType(OCI_Statement *stmt)
02806 {
02807     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
02808 
02809     OCI_RESULT(TRUE);
02810 
02811     return stmt->type;
02812 }
02813 
02814 /* ------------------------------------------------------------------------ *
02815  * OCI_SetFetchMode
02816  * ------------------------------------------------------------------------ */
02817 
02818 boolean OCI_API OCI_SetFetchMode(OCI_Statement *stmt, unsigned int mode)
02819 {
02820     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02821 
02822     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(stmt->con, FALSE);
02823 
02824     stmt->exec_mode = mode;
02825 
02826     OCI_RESULT(TRUE);
02827 
02828     return TRUE;
02829 }
02830 
02831 /* ------------------------------------------------------------------------ *
02832  * OCI_GetFetchMode
02833  * ------------------------------------------------------------------------ */
02834 
02835 unsigned int OCI_API OCI_GetFetchMode(OCI_Statement *stmt)
02836 {
02837     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
02838 
02839     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(stmt->con, OCI_UNKNOWN);
02840 
02841     OCI_RESULT(TRUE);
02842 
02843     return stmt->exec_mode;
02844 }
02845 
02846 /* ------------------------------------------------------------------------ *
02847  * OCI_SetBindMode
02848  * ------------------------------------------------------------------------ */
02849 
02850 boolean OCI_API OCI_SetBindMode(OCI_Statement *stmt, unsigned int mode)
02851 {
02852     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02853 
02854     stmt->bind_mode = mode;
02855 
02856     OCI_RESULT(TRUE);
02857 
02858     return TRUE;
02859 }
02860 
02861 /* ------------------------------------------------------------------------ *
02862  * OCI_GetBindMode
02863  * ------------------------------------------------------------------------ */
02864 
02865 unsigned int OCI_API OCI_GetBindMode(OCI_Statement *stmt)
02866 {
02867     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
02868 
02869     OCI_RESULT(TRUE);
02870 
02871     return stmt->bind_mode;
02872 }
02873 
02874 /* ------------------------------------------------------------------------ *
02875  * OCI_SetFetchSize
02876  * ------------------------------------------------------------------------ */
02877 
02878 boolean OCI_API OCI_SetFetchSize(OCI_Statement *stmt, unsigned int size)
02879 {
02880     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
02881 
02882     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
02883 
02884     stmt->fetch_size = size;
02885 
02886     OCI_RESULT(TRUE);
02887 
02888     return TRUE;
02889 }
02890 
02891 /* ------------------------------------------------------------------------ *
02892  * OCI_GetFetchSize
02893  * ------------------------------------------------------------------------ */
02894 
02895 unsigned int OCI_API OCI_GetFetchSize(OCI_Statement *stmt)
02896 {
02897     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
02898 
02899     OCI_RESULT(TRUE);
02900 
02901     return stmt->fetch_size;
02902 }
02903 
02904 /* ------------------------------------------------------------------------ *
02905  * OCI_SetPrefetchSize
02906  * ------------------------------------------------------------------------ */
02907 
02908 boolean OCI_API OCI_SetPrefetchSize(OCI_Statement *stmt, unsigned int size)
02909 {
02910     boolean res = TRUE;
02911 
02912     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
02913 
02914     OCI_CALL1
02915     (
02916         res, stmt->con, stmt,
02917 
02918         OCIAttrSet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
02919                    (dvoid *) &stmt->prefetch_size,
02920                    (ub4) sizeof(stmt->prefetch_size),
02921                    (ub4) OCI_ATTR_PREFETCH_ROWS, stmt->con->err)
02922     )
02923 
02924     if (res == TRUE)
02925         stmt->prefetch_size = size;
02926 
02927     OCI_RESULT(res);
02928 
02929     return res;
02930 }
02931 
02932 /* ------------------------------------------------------------------------ *
02933  * OCI_GetPrefetchSize
02934  * ------------------------------------------------------------------------ */
02935 
02936 unsigned int OCI_API OCI_GetPrefetchSize(OCI_Statement *stmt)
02937 {
02938     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
02939 
02940     OCI_RESULT(TRUE);
02941 
02942     return stmt->prefetch_size;
02943 }
02944 
02945 /* ------------------------------------------------------------------------ *
02946  * OCI_SetPrefetchMemory
02947  * ------------------------------------------------------------------------ */
02948 
02949 boolean OCI_API OCI_SetPrefetchMemory(OCI_Statement *stmt, unsigned int size)
02950 {
02951     boolean res = TRUE;
02952 
02953     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
02954 
02955     OCI_CALL1
02956     (
02957         res, stmt->con, stmt,
02958 
02959         OCIAttrSet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
02960                    (dvoid *) &stmt->prefetch_mem,
02961                    (ub4) sizeof(stmt->prefetch_mem),
02962                    (ub4) OCI_ATTR_PREFETCH_MEMORY, stmt->con->err)
02963     )
02964 
02965     if (res == TRUE)
02966         stmt->prefetch_mem = size;
02967 
02968     OCI_RESULT(res);
02969 
02970     return res;
02971 }
02972 
02973 /* ------------------------------------------------------------------------ *
02974  * OCI_GetPrefetchMemory
02975  * ------------------------------------------------------------------------ */
02976 
02977 unsigned int OCI_API OCI_GetPrefetchMemory(OCI_Statement *stmt)
02978 {
02979     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
02980 
02981     OCI_RESULT(TRUE);
02982 
02983     return stmt->prefetch_mem;
02984 }
02985 
02986 /* ------------------------------------------------------------------------ *
02987  * OCI_SetLongMaxSize
02988  * ------------------------------------------------------------------------ */
02989 
02990 boolean OCI_API OCI_SetLongMaxSize(OCI_Statement *stmt, unsigned int size)
02991 {
02992     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
02993 
02994     OCI_CHECK_MIN(stmt->con, stmt, size, 1, FALSE);
02995 
02996     stmt->long_size = size;
02997 
02998     OCI_RESULT(TRUE);
02999 
03000     return TRUE;
03001 }
03002 
03003 /* ------------------------------------------------------------------------ *
03004  * OCI_GetLongMaxSize
03005  * ------------------------------------------------------------------------ */
03006 
03007 unsigned int OCI_API OCI_GetLongMaxSize(OCI_Statement *stmt)
03008 {
03009     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03010 
03011     OCI_RESULT(TRUE);
03012 
03013     return stmt->long_size;
03014 }
03015 
03016 /* ------------------------------------------------------------------------ *
03017  * OCI_SetLongMode
03018  * ------------------------------------------------------------------------ */
03019 
03020 boolean OCI_API OCI_SetLongMode(OCI_Statement *stmt, unsigned int mode)
03021 {
03022     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03023 
03024     stmt->long_mode = (ub1) mode;
03025 
03026     OCI_RESULT(TRUE);
03027 
03028     return TRUE;
03029 }
03030 
03031 /* ------------------------------------------------------------------------ *
03032  * OCI_GetLongMode
03033  * ------------------------------------------------------------------------ */
03034 
03035 unsigned int OCI_API OCI_GetLongMode(OCI_Statement *stmt)
03036 {
03037     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03038 
03039     OCI_RESULT(TRUE);
03040 
03041     return stmt->long_mode;
03042 }
03043 
03044 /* ------------------------------------------------------------------------ *
03045  * OCI_StatementGetConnection
03046  * ------------------------------------------------------------------------ */
03047 
03048 OCI_Connection * OCI_API OCI_StatementGetConnection(OCI_Statement *stmt)
03049 {
03050     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03051 
03052     OCI_RESULT(TRUE);
03053 
03054     return stmt->con;
03055 }
03056 
03057 /* ------------------------------------------------------------------------ *
03058  * OCI_GetSql
03059  * ------------------------------------------------------------------------ */
03060 
03061 const mtext * OCI_API OCI_GetSql(OCI_Statement *stmt)
03062 {
03063     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
03064 
03065     OCI_RESULT(TRUE);
03066 
03067     return stmt->sql;
03068 }
03069 
03070 /* ------------------------------------------------------------------------ *
03071  * OCI_GetSqlErrorPos
03072  * ------------------------------------------------------------------------ */
03073 
03074 unsigned int OCI_API OCI_GetSqlErrorPos(OCI_Statement *stmt)
03075 {
03076     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03077 
03078     OCI_RESULT(TRUE);
03079 
03080     return stmt->err_pos;
03081 }
03082 
03083 /* ------------------------------------------------------------------------ *
03084  * OCI_GetAffecteddRows
03085  * ------------------------------------------------------------------------ */
03086 
03087 unsigned int OCI_API OCI_GetAffectedRows(OCI_Statement *stmt)
03088 {
03089     boolean res = TRUE;
03090     ub4 count   = 0;
03091 
03092     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt,  FALSE);
03093 
03094     OCI_CALL1
03095     (
03096         res, stmt->con, stmt,
03097 
03098         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
03099                    (void *) &count, (ub4 *) NULL, (ub4) OCI_ATTR_ROW_COUNT,
03100                    stmt->con->err)
03101     )
03102 
03103     OCI_RESULT(res);
03104 
03105     return count;
03106 }
03107 
03108 /* ------------------------------------------------------------------------ *
03109  * OCI_GetBindCount
03110  * ------------------------------------------------------------------------ */
03111 
03112 unsigned int OCI_API OCI_GetBindCount(OCI_Statement *stmt)
03113 {
03114     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03115 
03116     OCI_RESULT(TRUE);
03117 
03118     return (unsigned int) stmt->nb_ubinds;
03119 }
03120 
03121 /* ------------------------------------------------------------------------ *
03122  * OCI_GetBind
03123  * ------------------------------------------------------------------------ */
03124 
03125 OCI_Bind * OCI_API OCI_GetBind(OCI_Statement *stmt, unsigned int index)
03126 {
03127     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
03128     OCI_CHECK_BOUND(stmt->con, index, 1, stmt->nb_ubinds, NULL);
03129 
03130     OCI_RESULT(TRUE);
03131 
03132     return stmt->ubinds[index-1];
03133 }
03134 
03135 /* ------------------------------------------------------------------------ *
03136  * OCI_GetBind2
03137  * ------------------------------------------------------------------------ */
03138 
03139 OCI_Bind * OCI_API OCI_GetBind2(OCI_Statement *stmt, const mtext *name)
03140 {
03141     OCI_Bind *bnd = NULL;
03142     int index     = -1;
03143 
03144     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
03145     OCI_CHECK_PTR(OCI_IPC_STRING, name, FALSE);
03146 
03147     index =  OCI_BindGetIndex(stmt, name);
03148 
03149     if (index > 0)
03150         bnd = stmt->ubinds[index-1];
03151 
03152     OCI_RESULT(bnd != NULL);
03153 
03154     return bnd;
03155 }
03156 
03157 
03158 /* ------------------------------------------------------------------------ *
03159  * OCI_GetSQLCommand
03160  * ------------------------------------------------------------------------ */
03161 
03162 unsigned int OCI_API OCI_GetSQLCommand(OCI_Statement *stmt)
03163 {
03164     boolean res = TRUE;
03165     ub2 code    = OCI_UNKNOWN;
03166 
03167     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03168 
03169     OCI_CALL1
03170     (
03171         res, stmt->con, stmt,
03172 
03173         OCIAttrGet((dvoid *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
03174                    (dvoid *) &code, (ub4 *) NULL,
03175                    (ub4) OCI_ATTR_SQLFNCODE, stmt->con->err)
03176     )
03177 
03178     OCI_RESULT(res);
03179 
03180     return (unsigned int) code;
03181 }
03182 
03183 /* ------------------------------------------------------------------------ *
03184  * OCI_GetSQLVerb
03185  * ------------------------------------------------------------------------ */
03186 
03187 const mtext * OCI_API OCI_GetSQLVerb(OCI_Statement *stmt)
03188 {
03189     mtext * desc       = NULL;
03190     unsigned int code  = OCI_UNKNOWN;
03191 
03192     int i;
03193 
03194     code = OCI_GetSQLCommand(stmt);
03195 
03196     if (code != OCI_UNKNOWN)
03197     {
03198         for (i = 0; i < OCI_SQLCMD_COUNT; i++)
03199         {
03200             if (code == SQLCmds[i].code)
03201             {
03202                 desc = SQLCmds[i].verb;
03203                 break;
03204             }
03205         }
03206     }
03207 
03208     return desc;
03209 }
03210 
03211 /* ------------------------------------------------------------------------ *
03212  * OCI_GetBatchError
03213  * ------------------------------------------------------------------------ */
03214 
03215 OCI_Error * OCI_API OCI_GetBatchError(OCI_Statement *stmt)
03216 {
03217     OCI_Error *err = NULL;
03218 
03219     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, OCI_UNKNOWN);
03220 
03221     if (stmt->batch->cur < stmt->batch->count)
03222     {
03223         err = &stmt->batch->errs[stmt->batch->cur++];
03224     }
03225 
03226     OCI_RESULT(TRUE);
03227 
03228     return err;
03229 }
03230 
03231 /* ------------------------------------------------------------------------ *
03232  * OCI_GetBatchErrorCount
03233  * ------------------------------------------------------------------------ */
03234 
03235 unsigned int OCI_API OCI_GetBatchErrorCount(OCI_Statement *stmt)
03236 {
03237     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, 0);
03238 
03239     OCI_RESULT(TRUE);
03240 
03241     return stmt->batch->count;
03242 }

Generated on Thu Jul 30 17:41:53 2009 for OCILIB (C Driver for Oracle) by  doxygen 1.5.4