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

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