OCILIB (C Driver for Oracle) 3.9.1
D:/Perso/dev/ocilib/ocilib/src/dirpath.c
00001 /*
00002     +-----------------------------------------------------------------------------------------+
00003     |                                                                                         |
00004     |                               OCILIB - C Driver for Oracle                              |
00005     |                                                                                         |
00006     |                                (C Wrapper for Oracle OCI)                               |
00007     |                                                                                         |
00008     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: dirpath.c, v 3.9.1 2011-07-08 00:00 Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                            PUBLIC FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_DirPathCreate
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_DirPath * OCI_API OCI_DirPathCreate
00046 (
00047     OCI_TypeInfo *typinf,
00048     const mtext  *partition,
00049     unsigned int  nb_cols,
00050     unsigned int  nb_rows
00051 )
00052 {
00053     OCI_DirPath *dp = NULL;
00054 
00055     void *ostr = NULL;
00056     int osize  = -1;
00057 
00058     boolean res = TRUE;
00059 
00060     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00061 
00062     OCI_CHECK_COMPAT(typinf->con, typinf->type != OCI_TIF_TYPE, NULL);
00063     OCI_CHECK_BOUND(typinf->con, nb_cols, 1, typinf->nb_cols, NULL);
00064 
00065     /* allocate direct path structure */
00066 
00067     dp = (OCI_DirPath *) OCI_MemAlloc(OCI_IPC_DIRPATH, sizeof(*dp), (size_t) 1, TRUE);
00068 
00069     if (dp != NULL)
00070     {
00071         dp->con      = typinf->con;
00072         dp->status   = OCI_DPS_NOT_PREPARED;
00073         dp->typinf   = typinf;
00074         dp->nb_rows  = (ub2) nb_rows;
00075         dp->nb_cols  = (ub2) nb_cols;
00076         dp->nb_cur   = (ub2) dp->nb_rows;
00077         dp->err_col  = 0;
00078         dp->err_row  = 0;
00079         dp->nb_prcsd = 0;
00080 
00081         /* allocates direct context handle */
00082 
00083         if (res == TRUE)
00084         {
00085             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) dp->con->env,
00086                                                   (dvoid **) (void *) &dp->ctx,
00087                                                   (ub4) OCI_HTYPE_DIRPATH_CTX,
00088                                                   (size_t) 0, (dvoid **) NULL));
00089         }
00090 
00091         /* set table name attribute */
00092 
00093         if (res == TRUE)
00094         {
00095             osize = -1;
00096             ostr  = OCI_GetInputMetaString(dp->typinf->name, &osize);
00097 
00098             OCI_CALL2
00099             (
00100                 res, dp->con,
00101 
00102                 OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
00103                            (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_NAME, dp->con->err)
00104             )
00105 
00106             OCI_ReleaseMetaString(ostr);
00107         }
00108 
00109         /* set schema name attribute */
00110 
00111         if ((res == TRUE) && (dp->typinf->schema != NULL) && (dp->typinf->schema[0] != 0))
00112         {
00113             osize = -1;
00114             ostr  = OCI_GetInputMetaString(dp->typinf->schema, &osize);
00115 
00116             OCI_CALL2
00117             (
00118                 res, dp->con,
00119 
00120                 OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
00121                            (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_SCHEMA_NAME, dp->con->err)
00122             )
00123 
00124             OCI_ReleaseMetaString(ostr);
00125         }
00126 
00127         /* set partition name attribute */
00128 
00129         if ((res == TRUE) && (partition != NULL) && (partition[0] != 0))
00130         {
00131             osize = -1;
00132             ostr  = OCI_GetInputMetaString(partition, &osize);
00133 
00134             OCI_CALL2
00135             (
00136                 res, dp->con,
00137 
00138                 OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
00139                            (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_SUB_NAME, dp->con->err)
00140             )
00141 
00142             OCI_ReleaseMetaString(ostr);
00143         }
00144 
00145         if (OCILib.version_runtime >= OCI_9_0)
00146         {
00147             ub4 num_rows = dp->nb_rows;
00148 
00149             /* set array size attribute */
00150 
00151             OCI_CALL2
00152             (
00153                 res, dp->con,
00154 
00155                 OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
00156                            (dvoid *) &num_rows, (ub4) sizeof(num_rows),
00157                            (ub4) OCI_ATTR_NUM_ROWS, dp->con->err)
00158             )
00159         }
00160 
00161         /* set columns count attribute */
00162 
00163         OCI_CALL2
00164         (
00165             res, dp->con,
00166 
00167             OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
00168                        (dvoid *) &dp->nb_cols, (ub4) sizeof(dp->nb_cols),
00169                        (ub4) OCI_ATTR_NUM_COLS, dp->con->err)
00170         )
00171 
00172         /* allocating the column array */
00173 
00174         if (res == TRUE)
00175         {
00176             dp->cols = (void *) OCI_MemAlloc(OCI_IPC_DP_COL_ARRAY, sizeof(OCI_DirPathColumn),
00177                                              (size_t) dp->nb_cols, TRUE);
00178 
00179             res = (dp->cols != NULL);
00180         }
00181     }
00182     else
00183     {
00184         res = FALSE;
00185     }
00186 
00187     /* handle errors */
00188 
00189     if (res == FALSE)
00190     {
00191         OCI_DirPathFree(dp);
00192         dp = NULL;
00193     }
00194 
00195     OCI_RESULT(res);
00196 
00197     return dp;
00198 }
00199 
00200 /* --------------------------------------------------------------------------------------------- *
00201  * OCI_DirPathFree
00202  * --------------------------------------------------------------------------------------------- */
00203 
00204 boolean OCI_API OCI_DirPathFree
00205 (
00206     OCI_DirPath *dp
00207 )
00208 {
00209     ub2 i;
00210 
00211     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
00212 
00213     for (i = 0; i < dp->nb_cols; i++)
00214     {
00215         OCI_FREE(dp->cols[i].data);
00216         OCI_FREE(dp->cols[i].lens);
00217         OCI_FREE(dp->cols[i].flags);
00218         OCI_FREE(dp->cols[i].format);
00219     }
00220 
00221     OCI_FREE(dp->cols);
00222 
00223     OCI_HandleFree(dp->strm, OCI_HTYPE_DIRPATH_STREAM);
00224     OCI_HandleFree(dp->arr,  OCI_HTYPE_DIRPATH_COLUMN_ARRAY);
00225     OCI_HandleFree(dp->ctx,  OCI_HTYPE_DIRPATH_CTX);
00226 
00227     OCI_FREE(dp);
00228 
00229     OCI_RESULT(TRUE);
00230 
00231     return TRUE;
00232 }
00233 
00234 /* --------------------------------------------------------------------------------------------- *
00235  * OCI_DirPathSetColumn
00236  * --------------------------------------------------------------------------------------------- */
00237 
00238 boolean OCI_API OCI_DirPathSetColumn
00239 (
00240     OCI_DirPath *dp,
00241     unsigned int index,
00242     const mtext *name,
00243     unsigned int maxsize,
00244     const mtext *format
00245 )
00246 {
00247     OCI_DirPathColumn *dpcol = NULL;
00248     OCI_Column *col          = NULL;
00249     OCIParam *hattr          = NULL;
00250     OCIParam *hlist          = NULL;
00251     void *ostr               = NULL;
00252     int osize                = -1;
00253     boolean res              = TRUE;
00254     ub2 i;
00255 
00256     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
00257     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_NOT_PREPARED, FALSE);
00258     OCI_CHECK_PTR(OCI_IPC_STRING, name, FALSE);
00259     OCI_CHECK_BOUND(dp->con, index, 1, dp->nb_cols, FALSE);
00260 
00261     /* check if column exists */
00262 
00263     for (i = 0; i < dp->typinf->nb_cols; i++)
00264     {
00265         if (mtscasecmp(name, dp->typinf->cols[i].name) == 0)
00266         {
00267             break;
00268         }
00269     }
00270 
00271     /* check if column was found */
00272 
00273     if (i >= dp->typinf->nb_cols)
00274     {
00275         OCI_ExceptionDirPathColNotFound(dp, name, dp->typinf->name);
00276 
00277         res = FALSE;
00278     }
00279 
00280     /* set column information */
00281 
00282     if (res == TRUE)
00283     {
00284         col   = &dp->typinf->cols[i];
00285         dpcol = &dp->cols[index-1];
00286 
00287         /* default column attributes */
00288 
00289         dpcol->maxsize     = (ub2) maxsize;
00290         dpcol->bufsize     = (ub2) maxsize + 1;
00291         dpcol->sqlcode     = SQLT_CHR;
00292         dpcol->type        = OCI_DDT_TEXT;
00293         dpcol->index       = i;
00294         dpcol->format_size = 0;
00295 
00296         switch (col->type)
00297         {
00298             case OCI_CDT_TEXT:
00299             {
00300                 dpcol->maxsize *= sizeof(dtext);
00301                 dpcol->bufsize *= sizeof(dtext);
00302 
00303                 if (OCILib.nls_utf8 == TRUE)
00304                 {
00305                     dpcol->bufsize *= UTF8_BYTES_PER_CHAR;
00306                 }
00307 
00308                 break;
00309             }
00310             case OCI_CDT_NUMERIC:
00311             {
00312                 if ((format != NULL) && (format[0] != 0))
00313                 {
00314                     dpcol->format      = mtsdup(format);
00315                     dpcol->format_size = (ub4) mtslen(format);
00316                     dpcol->type        = OCI_DDT_NUMBER;
00317                     dpcol->sqlcode     = SQLT_NUM;
00318                     dpcol->bufsize     = sizeof(OCINumber);
00319                     dpcol->maxsize     = sizeof(OCINumber);
00320                 }
00321                 else
00322                 {
00323                     dpcol->type = OCI_DDT_OTHERS;
00324                 }
00325 
00326                 break;
00327             }
00328             case OCI_CDT_DATETIME:
00329             case OCI_CDT_TIMESTAMP:
00330             case OCI_CDT_INTERVAL:
00331             {
00332                 dpcol->type = OCI_DDT_OTHERS;
00333 
00334                 if ((format != NULL) && (format[0] != 0))
00335                 {
00336                     dpcol->format      = mtsdup(format);
00337                     dpcol->format_size = (ub4) mtslen(format);
00338                     dpcol->maxsize     = (ub2) dpcol->format_size;
00339                     dpcol->bufsize    *= sizeof(dtext);
00340                 }
00341 
00342                 break;
00343             }
00344             case OCI_CDT_LOB:
00345             {
00346                 if (col->subtype == OCI_BLOB)
00347                 {
00348                     dpcol->type    = OCI_DDT_BINARY;
00349                     dpcol->sqlcode = SQLT_BIN;
00350                 }
00351 
00352                 break;
00353             }
00354             case OCI_CDT_LONG:
00355             {
00356                 if (col->subtype == OCI_BLONG)
00357                 {
00358                     dpcol->type    = OCI_DDT_BINARY;
00359                     dpcol->sqlcode = SQLT_BIN;
00360                 }
00361 
00362                 break;
00363             }
00364             case OCI_CDT_RAW:
00365             {
00366                 dpcol->type    = OCI_DDT_BINARY;
00367                 dpcol->sqlcode = SQLT_BIN;
00368 
00369                 break;
00370             }
00371             default:
00372             {
00373                 res = FALSE;
00374                 OCI_ExceptionDatatypeNotSupported(dp->con, NULL, col->ocode);
00375 
00376                 break;
00377             }
00378         }
00379     }
00380 
00381     /* if supported datatype, set direct path column attributes */
00382 
00383     if (res == TRUE)
00384     {
00385         /* get column parameter list handle */
00386 
00387         OCI_CALL2
00388         (
00389             res, dp->con,
00390 
00391             OCIAttrGet(dp->ctx, OCI_HTYPE_DIRPATH_CTX, &hlist, NULL, OCI_ATTR_LIST_COLUMNS, dp->con->err)
00392         )
00393 
00394         /* get colum attribute handle */
00395 
00396         OCI_CALL2
00397         (
00398             res, dp->con,
00399 
00400             OCIParamGet((dvoid *) hlist, OCI_DTYPE_PARAM, dp->con->err,
00401                         (dvoid** ) (dvoid *) &hattr, (ub4) index)
00402         )
00403 
00404         /* set column name */
00405 
00406         if (res == TRUE)
00407         {
00408             osize = -1;
00409             ostr  = OCI_GetInputMetaString(name, &osize);
00410 
00411             OCI_CALL2
00412             (
00413                 res, dp->con,
00414 
00415                 OCIAttrSet((dvoid *) hattr, (ub4) OCI_DTYPE_PARAM,
00416                            (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_NAME, dp->con->err)
00417             )
00418 
00419             OCI_ReleaseMetaString(ostr);
00420         }
00421 
00422         /* set column type */
00423 
00424         OCI_CALL2
00425         (
00426             res, dp->con,
00427 
00428             OCIAttrSet((dvoid *) hattr, (ub4) OCI_DTYPE_PARAM,
00429                        (dvoid *) &dpcol->sqlcode, sizeof(dpcol->sqlcode),
00430                        (ub4) OCI_ATTR_DATA_TYPE, dp->con->err)
00431         )
00432 
00433         /* set column size */
00434 
00435         OCI_CALL2
00436         (
00437             res, dp->con,
00438 
00439             OCIAttrSet((dvoid *) hattr, (ub4) OCI_DTYPE_PARAM,
00440                        (dvoid *) &dpcol->maxsize, sizeof(dpcol->maxsize),
00441                        (ub4) OCI_ATTR_DATA_SIZE, dp->con->err)
00442         )
00443 
00444         /* set column precision */
00445 
00446         if (col->prec != 0)
00447         {
00448             OCI_CALL2
00449             (
00450                 res, dp->con,
00451 
00452                 OCIAttrSet((dvoid *) hattr, (ub4) OCI_DTYPE_PARAM,
00453                            (dvoid *) &col->prec, sizeof(col->prec),
00454                            (ub4) OCI_ATTR_PRECISION, dp->con->err)
00455             )
00456         }
00457 
00458         /* set column scale */
00459 
00460         if (col->scale != 0)
00461         {
00462             OCI_CALL2
00463             (
00464                 res, dp->con,
00465 
00466                 OCIAttrSet((dvoid *) hattr, (ub4) OCI_DTYPE_PARAM,
00467                            (dvoid *) &col->scale, sizeof(col->scale),
00468                            (ub4) OCI_ATTR_SCALE, dp->con->err)
00469             )
00470         }
00471 
00472         /* set column date/time format attribute */
00473 
00474         if ((res == TRUE) && (dpcol->type != OCI_DDT_NUMBER) &&
00475             (dpcol->format != NULL) && (dpcol->format[0] != 0))
00476         {
00477             osize = -1;
00478             ostr  = OCI_GetInputMetaString(dpcol->format, &osize);
00479 
00480             OCI_CALL2
00481             (
00482                 res, dp->con,
00483 
00484                 OCIAttrSet((dvoid *) hattr, (ub4) OCI_DTYPE_PARAM,
00485                            (dvoid *) ostr, (ub4) osize,
00486                            (ub4) OCI_ATTR_DATEFORMAT, dp->con->err)
00487             )
00488 
00489             OCI_ReleaseMetaString(ostr);
00490         }
00491 
00492     #ifdef OCI_CHARSET_WIDE
00493 
00494         /* setup Unicode mode for Unicode user data */
00495 
00496         if (dpcol->type == OCI_DDT_TEXT)
00497         {
00498             ub2 csid = OCI_UTF16ID;
00499 
00500             OCI_CALL2
00501             (
00502                 res, dp->con,
00503 
00504                 OCIAttrSet((dvoid *) hattr, (ub4) OCI_DTYPE_PARAM,
00505                            (dvoid *) &csid,  (ub4) sizeof(csid),
00506                            (ub4) OCI_ATTR_CHARSET_ID,  dp->con->err)
00507             )
00508         }
00509 
00510     #endif
00511 
00512         /* free param handle */
00513 
00514         OCIDescriptorFree(hattr, OCI_DTYPE_PARAM);
00515     }
00516 
00517     OCI_RESULT(res);
00518 
00519     return res;
00520 }
00521 
00522 /* --------------------------------------------------------------------------------------------- *
00523  * OCI_DirPathPrepare
00524  * --------------------------------------------------------------------------------------------- */
00525 
00526 boolean OCI_API OCI_DirPathPrepare
00527 (
00528     OCI_DirPath *dp
00529 )
00530 {
00531     boolean res = TRUE;
00532     ub2 i;
00533 
00534     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
00535     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_NOT_PREPARED, FALSE);
00536 
00537     /* prepare direct path operation */
00538 
00539     OCI_CALL2
00540     (
00541         res, dp->con,
00542 
00543         OCIDirPathPrepare(dp->ctx, dp->con->cxt, dp->con->err)
00544     )
00545 
00546     /* allocate column array handle */
00547 
00548     if (res == TRUE)
00549     {
00550         res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) dp->ctx,
00551                                               (dvoid **) (void *) &dp->arr,
00552                                               (ub4) OCI_HTYPE_DIRPATH_COLUMN_ARRAY,
00553                                               (size_t) 0, (dvoid **) NULL));
00554     }
00555 
00556     /* allocate stream handle */
00557 
00558     if (res == TRUE)
00559     {
00560         res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) dp->ctx,
00561                                               (dvoid **) (void *) &dp->strm,
00562                                               (ub4) OCI_HTYPE_DIRPATH_STREAM,
00563                                               (size_t) 0, (dvoid **) NULL));
00564     }
00565 
00566     /* check the number of rows allocated */
00567 
00568     if (res == TRUE)
00569     {
00570         ub4 num_rows = 0;
00571         ub4 size     = sizeof(num_rows);
00572 
00573         OCI_CALL2
00574         (
00575             res, dp->con,
00576 
00577             OCIAttrGet(dp->arr, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, &num_rows,
00578                        &size, OCI_ATTR_NUM_ROWS, dp->con->err)
00579         )
00580 
00581         dp->nb_cur  = (ub2) num_rows;
00582         dp->nb_rows = (ub2) num_rows;
00583     }
00584 
00585     /* now, we need to allocate internal buffers */
00586 
00587     if (res == TRUE)
00588     {
00589 
00590         for (i = 0; i < dp->nb_cols; i++)
00591         {
00592             OCI_DirPathColumn *col = &dp->cols[i];
00593 
00594             /* data buffers */
00595 
00596             col->data = (ub1 *) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY,
00597                                              (size_t) col->bufsize,
00598                                              (size_t) dp->nb_cur, TRUE);
00599 
00600             if (col->data == NULL)
00601             {
00602                 res = FALSE;
00603                 break;
00604             }
00605 
00606             /* data sizes */
00607 
00608             col->lens = (ub4 *) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY, sizeof(ub4),
00609                                              (size_t) dp->nb_cur, TRUE);
00610 
00611             if (col->lens == NULL)
00612             {
00613                 res = FALSE;
00614                 break;
00615             }
00616 
00617             /* data flags */
00618 
00619             col->flags = (ub1 *) OCI_MemAlloc(OCI_IPC_BUFF_ARRAY, sizeof(ub1),
00620                                               (size_t) dp->nb_cur, TRUE);
00621 
00622             if (col->flags == NULL)
00623             {
00624                 res = FALSE;
00625                 break;
00626             }
00627         }
00628     }
00629 
00630     if (res == TRUE)
00631     {
00632         dp->status = OCI_DPS_PREPARED;
00633     }
00634 
00635     OCI_RESULT(res);
00636 
00637     return res;
00638 }
00639 
00640 /* --------------------------------------------------------------------------------------------- *
00641  * OCI_DirPathSetEntry
00642  * --------------------------------------------------------------------------------------------- */
00643 
00644 boolean OCI_API OCI_DirPathSetEntry
00645 (
00646     OCI_DirPath *dp,
00647     unsigned int row,
00648     unsigned int index,
00649     void        *value,
00650     unsigned int size,
00651     boolean      complete
00652 )
00653 {
00654     boolean res              = TRUE;
00655     OCI_DirPathColumn *dpcol = NULL;
00656     OCI_Column *col          = NULL;
00657 
00658     ub1 *data;
00659     ub1 flag;
00660 
00661     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
00662 
00663     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_PREPARED, FALSE);
00664     OCI_CHECK_BOUND(dp->con, index, 1, dp->nb_cols, FALSE);
00665     OCI_CHECK_BOUND(dp->con, row, 1, dp->nb_cur, FALSE);
00666 
00667     dpcol = &dp->cols[index-1];
00668     col   = &dp->typinf->cols[dpcol->index];
00669 
00670     /* check size */
00671 
00672     if (size > dpcol->maxsize)
00673     {
00674         size = (unsigned int) dpcol->maxsize;
00675     }
00676 
00677     /* setup column flag */
00678 
00679     if (value == NULL)
00680     {
00681         flag = OCI_DIRPATH_COL_NULL;
00682     }
00683     else if (complete == TRUE)
00684     {
00685         flag = OCI_DIRPATH_COL_COMPLETE;
00686     }
00687     else
00688     {
00689         flag = OCI_DIRPATH_COL_PARTIAL;
00690     }
00691 
00692     /* for character based column, parameter size was the number of characters
00693      **/
00694 
00695     if (dpcol->sqlcode == SQLT_CHR)
00696     {
00697         size *= (unsigned int) sizeof(dtext);
00698     }
00699 
00700     /* get internal data cell */
00701 
00702     data = ((ub1 *) dpcol->data) + (size_t) ((row-1) * dpcol->bufsize);
00703 
00704 #if defined(OCI_CHECK_DATASTRINGS)
00705 
00706     /* we weed to pack the buffer if wchar_t is 4 bytes */
00707 
00708     if (dpcol->type == OCI_DDT_TEXT)
00709     {
00710         int osize = -1;
00711 
00712         OCI_GetOutputString(value, data, &size, sizeof(dtext), sizeof(odtext));
00713     }
00714     else
00715 
00716 #endif
00717 
00718 #if defined(OCI_USERDATA_WIDE)
00719 
00720     /* input Unicode numeric values causes oracle conversion error.
00721        so, let's convert them to ansi */
00722 
00723     if (dpcol->type == OCI_DDT_OTHERS)
00724     {
00725         size = (unsigned int) wcstombs((char *) data, value, dpcol->bufsize - 1);
00726     }
00727     else
00728 
00729 #endif
00730 
00731     /* if a format was provided for a numeric column, we convert the input
00732        buffer to a OCINumber */
00733 
00734     if (dpcol->type == OCI_DDT_NUMBER)
00735     {
00736         OCINumber *num = (OCINumber *) data;
00737 
00738         res = OCI_NumberConvertStr(dp->con, num, (dtext *) value, size,
00739                                    dpcol->format, dpcol->format_size);
00740 
00741         if (res == TRUE)
00742         {
00743             size = (unsigned int) num->OCINumberPart[0];
00744         }
00745     }
00746     else
00747     {
00748 
00749     #if defined(OCI_CHARSET_MIXED)
00750 
00751         /* with mixed charset builds, OCIDirPrepare() causes a segfault if the
00752            attribute OCI_ATTR_CHARSET_ID has been set with OCI_UTF16.
00753            In the OCILIB direct path implementation, the code is the same for
00754            Unicode and mixed charset. This only difference is the
00755            environment mode set of UTF16...
00756            So let's convert the data back to ANSI until Oracle corrects this bug */
00757 
00758         if (dpcol->type == OCI_DDT_TEXT)
00759         {
00760             size = (unsigned int) wcstombs((char *) data, value, dpcol->bufsize - 1);
00761         }
00762         else
00763 
00764     #endif
00765 
00766         {
00767             memcpy(data, value, (size_t) size);
00768         }
00769 
00770     }
00771 
00772     dpcol->lens[row-1]  = size;
00773     dpcol->flags[row-1] = flag;
00774 
00775     OCI_RESULT(res);
00776 
00777     return res;
00778 }
00779 
00780 /* --------------------------------------------------------------------------------------------- *
00781  * OCI_DirPathReset
00782  * --------------------------------------------------------------------------------------------- */
00783 
00784 boolean OCI_API OCI_DirPathReset
00785 (
00786     OCI_DirPath *dp
00787 )
00788 {
00789     boolean res = TRUE;
00790 
00791     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
00792 
00793     /* reset array */
00794 
00795     OCI_CALL2
00796     (
00797         res, dp->con,
00798 
00799         OCIDirPathColArrayReset(dp->arr, dp->con->err)
00800     )
00801 
00802     /* reset stream */
00803 
00804     OCI_CALL2
00805     (
00806         res, dp->con,
00807 
00808         OCIDirPathStreamReset(dp->strm, dp->con->err)
00809     )
00810 
00811     OCI_RESULT(res);
00812 
00813     return res;
00814 }
00815 
00816 /* --------------------------------------------------------------------------------------------- *
00817  * OCI_DirPathConvert
00818  * --------------------------------------------------------------------------------------------- */
00819 
00820 unsigned int OCI_API OCI_DirPathConvert
00821 (
00822     OCI_DirPath *dp
00823 )
00824 {
00825     unsigned int res         = OCI_DPR_COMPLETE;
00826     OCI_DirPathColumn *dpcol = NULL;
00827     sword ret                = OCI_SUCCESS;
00828     ub1 *data;
00829     ub4 size;
00830     ub1 flag;
00831     ub2 i, j;
00832 
00833     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, OCI_DPR_ERROR);
00834 
00835     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_PREPARED, OCI_DPR_ERROR);
00836 
00837     dp->err_col  = 0;
00838     dp->nb_prcsd = 0;
00839 
00840     /* set entries */
00841 
00842     for (i = 0; (i < dp->nb_cols) && (res == TRUE); i++)
00843     {
00844         dpcol = &(dp->cols[i]);
00845 
00846         for (j = (ub2) 0; (j < dp->nb_cur) && (res == TRUE); j++)
00847         {
00848             /* get internal data cell */
00849 
00850             data = ((ub1 *) dpcol->data) +  (size_t) (j * dpcol->bufsize);
00851             size = dpcol->lens[j];
00852             flag = dpcol->flags[j];
00853 
00854             if (dpcol->sqlcode == SQLT_NUM)
00855             {
00856                 OCINumber *num = (OCINumber *) data;
00857 
00858                 data = &num->OCINumberPart[1];
00859             }
00860 
00861             /* set entry value */
00862 
00863             OCI_CALL2
00864             (
00865                 res, dp->con,
00866 
00867                 OCIDirPathColArrayEntrySet(dp->arr, dp->con->err, (ub4) j, (ub2) (i),
00868                                            (ub1*) data, (ub4) size, flag)
00869             )
00870         }
00871     }
00872 
00873     if (res == TRUE)
00874     {
00875         /* conversion */
00876 
00877         ret = OCIDirPathColArrayToStream(dp->arr, dp->ctx,  dp->strm, dp->con->err,
00878                                          (ub4) dp->nb_cur, (ub4) 0);
00879 
00880         switch (ret)
00881         {
00882             case OCI_SUCCESS:
00883             {
00884                 dp->status  = OCI_DPS_CONVERTED;
00885                 dp->err_col = 0;
00886                 dp->err_row = 0;
00887                 res         = OCI_DPR_COMPLETE;
00888 
00889                 break;
00890             }
00891             case OCI_ERROR:
00892             {
00893                 res = OCI_DPR_ERROR;
00894 
00895                 OCI_ExceptionOCI(dp->con->err, dp->con, NULL, FALSE);
00896 
00897                 break;
00898             }
00899             case OCI_CONTINUE:
00900             {
00901                 dp->status = OCI_DPS_CONVERTED;
00902                 res        = OCI_DPR_FULL;
00903 
00904                 break;
00905             }
00906             case OCI_NEED_DATA:
00907             {
00908                 res = OCI_DPR_PARTIAL;
00909 
00910                 break;
00911             }
00912         }
00913 
00914         if (ret != OCI_SUCCESS)
00915         {
00916             size = sizeof(dp->err_col);
00917 
00918             OCIAttrGet(dp->arr, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, &dp->err_col,
00919                        &size, OCI_ATTR_COL_COUNT, dp->con->err);
00920 
00921             size = sizeof(dp->err_row);
00922 
00923             OCIAttrGet(dp->arr, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, &dp->err_row,
00924                        &size, OCI_ATTR_ROW_COUNT, dp->con->err);
00925 
00926             dp->nb_prcsd = dp->err_row;
00927         }
00928         else
00929         {
00930             dp->nb_prcsd = dp->nb_cur;
00931         }
00932     }
00933     else
00934     {
00935         ret = OCI_ERROR;
00936     }
00937 
00938     OCI_RESULT(ret == OCI_SUCCESS);
00939 
00940     return res;
00941 }
00942 
00943 /* --------------------------------------------------------------------------------------------- *
00944  * OCI_DirPathLoad
00945  * --------------------------------------------------------------------------------------------- */
00946 
00947 unsigned int OCI_API OCI_DirPathLoad
00948 (
00949     OCI_DirPath *dp
00950 )
00951 {
00952     unsigned int res = OCI_DPR_COMPLETE;
00953     sword ret        = OCI_SUCCESS;
00954 
00955     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, OCI_DPR_ERROR);
00956 
00957     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_CONVERTED, OCI_DPR_ERROR);
00958 
00959     dp->err_col  = 0;
00960     dp->nb_prcsd = 0;
00961 
00962     ret = OCIDirPathLoadStream(dp->ctx, dp->strm, dp->con->err);
00963 
00964     switch (ret)
00965     {
00966         case OCI_SUCCESS:
00967         {
00968             dp->status     = OCI_DPS_PREPARED;
00969             dp->nb_prcsd   = dp->nb_cur;
00970             dp->nb_loaded += dp->nb_prcsd;
00971             res            = OCI_DPR_COMPLETE;
00972 
00973             break;
00974         }
00975         case OCI_ERROR:
00976         {
00977             res = OCI_DPR_ERROR;
00978 
00979             OCI_ExceptionOCI(dp->con->err, dp->con, NULL, FALSE);
00980 
00981             break;
00982         }
00983         case OCI_NO_DATA:
00984         {
00985             res = OCI_DPR_EMPTY;
00986 
00987             break;
00988         }
00989         case OCI_NEED_DATA:
00990         {
00991             res = OCI_DPR_PARTIAL;
00992 
00993             break;
00994         }
00995     }
00996 
00997     if (ret != OCI_SUCCESS)
00998     {
00999         ub4 size = sizeof(dp->nb_prcsd);
01000 
01001         OCIAttrGet(dp->arr, OCI_HTYPE_DIRPATH_COLUMN_ARRAY, &dp->nb_prcsd,
01002                    &size, OCI_ATTR_NUM_ROWS, dp->con->err);
01003     }
01004 
01005     OCI_RESULT(ret == OCI_SUCCESS);
01006 
01007     return res;
01008 }
01009 
01010 /* --------------------------------------------------------------------------------------------- *
01011  * OCI_DirPathFinish
01012  * --------------------------------------------------------------------------------------------- */
01013 
01014 boolean OCI_API OCI_DirPathFinish
01015 (
01016     OCI_DirPath *dp
01017 )
01018 {
01019     boolean res = TRUE;
01020 
01021     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01022 
01023     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_PREPARED, FALSE);
01024 
01025     OCI_CALL2
01026     (
01027         res, dp->con,
01028 
01029         OCIDirPathFinish(dp->ctx, dp->con->err)
01030     )
01031 
01032     if (res == TRUE)
01033     {
01034         dp->status = OCI_DPS_TERMINATED;
01035     }
01036 
01037     OCI_RESULT(res);
01038 
01039     return res;
01040 }
01041 
01042 /* --------------------------------------------------------------------------------------------- *
01043  * OCI_DirPathAbort
01044  * --------------------------------------------------------------------------------------------- */
01045 
01046 boolean OCI_API OCI_DirPathAbort
01047 (
01048     OCI_DirPath *dp
01049 )
01050 {
01051     boolean res = TRUE;
01052 
01053     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01054 
01055     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_PREPARED, FALSE);
01056 
01057     OCI_CALL2
01058     (
01059         res, dp->con,
01060 
01061         OCIDirPathAbort(dp->ctx, dp->con->err)
01062     )
01063 
01064     if (res == TRUE)
01065     {
01066         dp->status = OCI_DPS_TERMINATED;
01067     }
01068 
01069     OCI_RESULT(res);
01070 
01071     return res;
01072 }
01073 
01074 /* --------------------------------------------------------------------------------------------- *
01075  * OCI_DirPathSave
01076  * --------------------------------------------------------------------------------------------- */
01077 
01078 boolean OCI_API OCI_DirPathSave
01079 (
01080     OCI_DirPath *dp
01081 )
01082 {
01083     boolean res = TRUE;
01084 
01085     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01086 
01087     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_PREPARED, FALSE);
01088 
01089     OCI_CALL2
01090     (
01091         res, dp->con,
01092 
01093         OCIDirPathDataSave(dp->ctx, dp->con->err, OCI_DIRPATH_DATASAVE_SAVEONLY)
01094     )
01095 
01096     OCI_RESULT(res);
01097 
01098     return res;
01099 }
01100 
01101 /* --------------------------------------------------------------------------------------------- *
01102  * OCI_DirPathFlushRow
01103  * --------------------------------------------------------------------------------------------- */
01104 
01105 boolean OCI_API OCI_DirPathFlushRow
01106 (
01107     OCI_DirPath *dp
01108 )
01109 {
01110     boolean res = TRUE;
01111 
01112     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01113 
01114     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_PREPARED, FALSE);
01115 
01116     OCI_CALL2
01117     (
01118         res, dp->con,
01119 
01120         OCIDirPathFlushRow(dp->ctx, dp->con->err)
01121     )
01122 
01123     OCI_RESULT(res);
01124 
01125     return res;
01126 }
01127 
01128 /* --------------------------------------------------------------------------------------------- *
01129  * OCI_DirPathSetCurrentRows
01130  * --------------------------------------------------------------------------------------------- */
01131 
01132 boolean OCI_API OCI_DirPathSetCurrentRows
01133 (
01134     OCI_DirPath *dp,
01135     unsigned int nb_rows
01136 )
01137 {
01138     boolean res = TRUE;
01139 
01140     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01141 
01142     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_PREPARED, FALSE);
01143 
01144     OCI_CHECK_BOUND(dp->con, nb_rows, 1, dp->nb_rows, FALSE);
01145 
01146     dp->nb_cur = (ub2) nb_rows;
01147 
01148     OCI_RESULT(res);
01149 
01150     return res;
01151 }
01152 
01153 /* --------------------------------------------------------------------------------------------- *
01154  * OCI_DirPathGetCurrentRows
01155  * --------------------------------------------------------------------------------------------- */
01156 
01157 unsigned int OCI_API OCI_DirPathGetCurrentRows
01158 (
01159     OCI_DirPath *dp
01160 )
01161 {
01162     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, 0);
01163 
01164     OCI_RESULT(TRUE);
01165 
01166     return dp->nb_cur;
01167 }
01168 
01169 /* --------------------------------------------------------------------------------------------- *
01170  * OCI_DirPathGetMaxRows
01171  * --------------------------------------------------------------------------------------------- */
01172 
01173 unsigned int OCI_API OCI_DirPathGetMaxRows
01174 (
01175     OCI_DirPath *dp
01176 )
01177 {
01178     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, 0);
01179 
01180     OCI_RESULT(TRUE);
01181 
01182     return dp->nb_rows;
01183 }
01184 
01185 /* --------------------------------------------------------------------------------------------- *
01186  * OCI_DirPathSetDateFormat
01187  * --------------------------------------------------------------------------------------------- */
01188 
01189 boolean OCI_API OCI_DirPathSetDateFormat
01190 (
01191     OCI_DirPath *dp,
01192     const mtext *format
01193 )
01194 {
01195     boolean res = TRUE;
01196     void *ostr  = NULL;
01197     int osize   = -1;
01198 
01199     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01200 
01201     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_NOT_PREPARED, FALSE);
01202 
01203     osize = -1;
01204     ostr  = OCI_GetInputMetaString(format, &osize);
01205 
01206     OCI_CALL2
01207     (
01208         res, dp->con,
01209 
01210         OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
01211                    (dvoid *) ostr, (ub4) osize, (ub4) OCI_ATTR_DATEFORMAT, dp->con->err)
01212     )
01213 
01214     OCI_ReleaseMetaString(ostr);
01215 
01216     OCI_RESULT(res);
01217 
01218     return res;
01219 }
01220 
01221 /* --------------------------------------------------------------------------------------------- *
01222  * OCI_DirPathSetParallel
01223  * --------------------------------------------------------------------------------------------- */
01224 
01225 boolean OCI_API OCI_DirPathSetParallel
01226 (
01227     OCI_DirPath *dp,
01228     boolean      value
01229 )
01230 {
01231     boolean res = TRUE;
01232     ub1 enabled = (ub1) value;
01233 
01234     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01235 
01236     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_NOT_PREPARED, FALSE);
01237 
01238     OCI_CALL2
01239     (
01240         res, dp->con,
01241 
01242         OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
01243                    (dvoid *) &enabled, (ub4) sizeof(enabled),
01244                    (ub4) OCI_ATTR_DIRPATH_PARALLEL, dp->con->err)
01245     )
01246 
01247     OCI_RESULT(res);
01248 
01249     return res;
01250 }
01251 
01252 /* --------------------------------------------------------------------------------------------- *
01253  * OCI_DirPathSetNoLog
01254  * --------------------------------------------------------------------------------------------- */
01255 
01256 boolean OCI_API OCI_DirPathSetNoLog
01257 (
01258     OCI_DirPath *dp,
01259     boolean      value
01260 )
01261 {
01262     boolean res = TRUE;
01263     ub1 nolog   = (ub1) value;
01264 
01265     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01266 
01267     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_NOT_PREPARED, FALSE);
01268 
01269     OCI_CALL2
01270     (
01271         res, dp->con,
01272 
01273         OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
01274                    (dvoid *) &nolog, (ub4) sizeof(nolog),
01275                    (ub4) OCI_ATTR_DIRPATH_NOLOG, dp->con->err)
01276     )
01277 
01278     OCI_RESULT(res);
01279 
01280     return res;
01281 }
01282 
01283 /* --------------------------------------------------------------------------------------------- *
01284  * OCI_DirPathSetCacheSize
01285  * --------------------------------------------------------------------------------------------- */
01286 
01287 boolean OCI_API OCI_DirPathSetCacheSize
01288 (
01289     OCI_DirPath *dp,
01290     unsigned int size
01291 )
01292 {
01293     boolean res     = TRUE;
01294     ub4 cache_size  = size;
01295     boolean enabled = FALSE;
01296 
01297     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01298 
01299     OCI_CHECK_DIRPATH_DATE_CACHE_ENABLED(dp, FALSE);
01300 
01301     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_NOT_PREPARED, FALSE);
01302 
01303 #if OCI_VERSION_COMPILE >= OCI_9_2
01304 
01305     OCI_CALL2
01306     (
01307         res, dp->con,
01308 
01309         OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
01310                    (dvoid *) &cache_size, (ub4) sizeof(cache_size),
01311                    (ub4) OCI_ATTR_DIRPATH_DCACHE_SIZE, dp->con->err)
01312     )
01313 
01314     OCI_CALL2
01315     (
01316         res, dp->con,
01317 
01318         OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
01319                    (dvoid *) &enabled, (ub4) sizeof(enabled),
01320                    (ub4) OCI_ATTR_DIRPATH_DCACHE_DISABLE, dp->con->err)
01321     )
01322 
01323 #else
01324 
01325     OCI_NOT_USED(cache_size);
01326     OCI_NOT_USED(enabled);
01327 
01328 #endif
01329 
01330     OCI_RESULT(res);
01331 
01332     return res;
01333 }
01334 
01335 /* --------------------------------------------------------------------------------------------- *
01336  * OCI_DirPathSetBufferSize
01337  * --------------------------------------------------------------------------------------------- */
01338 
01339 boolean OCI_API OCI_DirPathSetBufferSize
01340 (
01341     OCI_DirPath *dp,
01342     unsigned int size
01343 )
01344 {
01345     boolean res = TRUE;
01346     ub4 bufsize = (ub4) size;
01347 
01348     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01349 
01350     OCI_CHECK_DIRPATH_STATUS(dp, OCI_DPS_NOT_PREPARED, FALSE);
01351 
01352     OCI_CALL2
01353     (
01354         res, dp->con,
01355 
01356         OCIAttrSet((dvoid *) dp->ctx, (ub4) OCI_HTYPE_DIRPATH_CTX,
01357                    (dvoid *) &bufsize, (ub4) sizeof(bufsize),
01358                    (ub4) OCI_ATTR_BUF_SIZE, dp->con->err)
01359     )
01360 
01361     OCI_RESULT(res);
01362 
01363     return res;
01364 }
01365 
01366 /* --------------------------------------------------------------------------------------------- *
01367  * OCI_DirPathGetRowCount
01368  * --------------------------------------------------------------------------------------------- */
01369 
01370 unsigned int OCI_API OCI_DirPathGetRowCount
01371 (
01372     OCI_DirPath *dp
01373 )
01374 {
01375     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01376 
01377     OCI_RESULT(TRUE);
01378 
01379     return dp->nb_loaded;
01380 }
01381 
01382 /* --------------------------------------------------------------------------------------------- *
01383  * OCI_DirPathGetAffectedRows
01384  * --------------------------------------------------------------------------------------------- */
01385 
01386 unsigned int OCI_API OCI_DirPathGetAffectedRows
01387 (
01388     OCI_DirPath *dp
01389 )
01390 {
01391     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01392 
01393     OCI_RESULT(TRUE);
01394 
01395     return dp->nb_prcsd;
01396 }
01397 
01398 /* --------------------------------------------------------------------------------------------- *
01399  * OCI_DirPathGetErrorColumn
01400  * --------------------------------------------------------------------------------------------- */
01401 
01402 unsigned int OCI_API OCI_DirPathGetErrorColumn
01403 (
01404     OCI_DirPath *dp
01405 )
01406 {
01407     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01408 
01409     OCI_RESULT(TRUE);
01410 
01411     return dp->err_col;
01412 }
01413 
01414 /* --------------------------------------------------------------------------------------------- *
01415  * OCI_DirPathGetErrorRow
01416  * --------------------------------------------------------------------------------------------- */
01417 
01418 unsigned int OCI_API OCI_DirPathGetErrorRow
01419 (
01420     OCI_DirPath *dp
01421 )
01422 {
01423     OCI_CHECK_PTR(OCI_IPC_DIRPATH, dp, FALSE);
01424 
01425     OCI_RESULT(TRUE);
01426 
01427     return dp->err_row;
01428 }