C:/Users/vincent/Data/Perso/dev/ocilib/ocilib/src/resultset.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: resultset.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_ResultsetCreate
00043  * ------------------------------------------------------------------------ */
00044 
00045 OCI_Resultset * OCI_ResultsetCreate(OCI_Statement *stmt, int size)
00046 {
00047     OCI_Resultset* rs = NULL;
00048     boolean res       = TRUE;
00049     ub4 nb            = 0;
00050     ub4 i;
00051 
00052     /* allocate resultset structure */
00053 
00054     rs = (OCI_Resultset *) OCI_MemAlloc(OCI_IPC_RESULTSET, sizeof(*rs), 1, TRUE);
00055 
00056     /* set attributes */
00057 
00058     if (rs != NULL)
00059     {
00060         rs->stmt         = stmt;
00061         rs->bof          = TRUE;
00062         rs->eof          = FALSE;
00063         rs->fetch_size   = size;
00064         rs->fetch_status = OCI_SUCCESS;
00065         rs->row_count    = 0;
00066         rs->row_cur      = 0;
00067         rs->row_abs      = 0;
00068 
00069         /* is the resultset created from a SQL select statement ? */
00070 
00071         if (stmt->type == OCI_CST_SELECT)
00072         {
00073             OCI_CALL1
00074             (
00075                 res, stmt->con, stmt,
00076 
00077                 OCIAttrGet((void *) stmt->stmt, (ub4) OCI_HTYPE_STMT,
00078                            (void *) &nb, (ub4 *) NULL,
00079                            (ub4) OCI_ATTR_PARAM_COUNT, stmt->con->err)
00080             )
00081         }
00082         else
00083         {
00084             nb = stmt->nb_rbinds;
00085         }
00086 
00087         /* allocate columns array */
00088 
00089         if (res == TRUE)
00090         {
00091             rs->defs = (OCI_Define *) OCI_MemAlloc(OCI_IPC_DEFINE, sizeof(*rs->defs),
00092                                                    nb, TRUE);
00093 
00094             res = (rs->defs != NULL);
00095         }
00096 
00097         /* describe select list */
00098 
00099         if ((res == TRUE) && (stmt->type == OCI_CST_SELECT))
00100         {
00101             for (i=0; i < nb; i++)
00102             {
00103                 OCI_Define *def  = &rs->defs[i];
00104 
00105                 def->buf.count   = size;
00106                 def->buf.sizelen = sizeof(ub2);
00107 
00108                 def->rs = rs;
00109 
00110                 rs->nb_defs++;
00111 
00112                 /* get column description */
00113 
00114                 if (res == TRUE)
00115                     res = OCI_ColumnDescribe(&def->col, rs->stmt->con,
00116                                              rs->stmt, rs->stmt->stmt,
00117                                              rs->nb_defs, OCI_DESC_RESULTSET);
00118 
00119                 /* mapping to OCILIB internal types */
00120 
00121                 if (res == TRUE)
00122                     res = OCI_ColumnMap(&def->col, rs->stmt);
00123 
00124                 /* allocation of internal buffers for resultset content */
00125 
00126                 if (res == TRUE)
00127                     res = OCI_DefineAlloc(def);
00128 
00129                 /* register OCILIB result buffers to OCI */
00130 
00131                 if (res == TRUE)
00132                     res = OCI_DefineDef(def);
00133 
00134                 if (res == FALSE)
00135                     break;
00136             }
00137         }
00138         else
00139         {
00140             /* get info from register binds */
00141 
00142             for (i=0; i < stmt->nb_rbinds; i++)
00143             {
00144                 OCI_Bind   *bnd  = stmt->rbinds[i];
00145                 OCI_Define *def  = &rs->defs[bnd->dynpos];
00146 
00147                 def->buf.count   = size;
00148                 def->buf.sizelen = sizeof(ub4);
00149 
00150                 def->rs = rs;
00151 
00152                 rs->nb_defs++;
00153 
00154                 /* columns info */
00155 
00156                 def->col.ocode   = bnd->code;
00157                 def->col.name    = mtsdup(bnd->name);
00158                 def->col.size    = (ub2) bnd->size;
00159                 def->col.type    = bnd->type;
00160                 def->col.subtype = bnd->subtype;
00161 
00162                 /* check national attribute for nclobs */
00163 
00164                 if (bnd->type == OCI_CDT_LOB && bnd->subtype == OCI_NCLOB)
00165                     def->col.csfrm = SQLCS_NCHAR;
00166 
00167                 /* adjust column size from bind attributes */
00168 
00169                 if (def->col.type == OCI_CDT_TEXT)
00170                     def->col.size = (ub2) (def->col.size / (sizeof(dtext)) - 1);
00171 
00172                 /* for integer types, set the bufsize here in order to
00173                    retrieve later the integer type (short, integer, big_int)
00174                    depending on the integer size */
00175 
00176                 if (def->col.type == OCI_CDT_NUMERIC)
00177                     def->col.bufsize = def->col.size;
00178 
00179                 /* preset bufsize here to let OCI_ColumnMap() know we don't
00180                    want the column to mapped to SQLT_ODT */
00181 
00182                 if (def->col.ocode == SQLT_DAT)
00183                     def->col.bufsize = def->col.size;
00184 
00185                 /* map column : failure means unsupported type */
00186 
00187                 if (res == TRUE)
00188                     res = OCI_ColumnMap(&def->col, rs->stmt);
00189 
00190                 /* allocation of internal buffers for resultset content */
00191 
00192                 if (res == TRUE)
00193                     res = OCI_DefineAlloc(def);
00194 
00195                 if (res == FALSE)
00196                     break;
00197             }
00198         }
00199     }
00200 
00201     return rs;
00202 }
00203 
00204 
00205 /* ------------------------------------------------------------------------ *
00206  * OCI_FetchPieces
00207  * ------------------------------------------------------------------------ */
00208 
00209 boolean OCI_FetchPieces(OCI_Resultset *rs)
00210 {
00211     boolean res  = TRUE;
00212 
00213     ub4 type, iter, dx;
00214     ub1 in_out, piece;
00215     void *handle;
00216     ub4 i, j;
00217 
00218     OCI_CHECK(rs == NULL, FALSE);
00219 
00220     /* reset long objects */
00221 
00222     for (i = 0; i < rs->nb_defs; i++)
00223     {
00224         OCI_Define *def = &rs->defs[i];
00225 
00226         if (def->col.type == OCI_CDT_LONG)
00227         {
00228             for (j = 0; j < def->buf.count; j++)
00229             {
00230                 OCI_LongInit(rs->stmt, (OCI_Long **) &def->buf.data[j],
00231                              def, def->col.subtype);
00232             }
00233         }
00234     }
00235 
00236     /* dynamic fetch */
00237 
00238     while ((res == TRUE) && (rs->fetch_status == OCI_NEED_DATA))
00239     {
00240         piece  = OCI_NEXT_PIECE;
00241         iter   = 0;
00242         handle = NULL;
00243 
00244         /* get piece information */
00245 
00246         OCI_CALL1
00247         (
00248             res, rs->stmt->con, rs->stmt,
00249 
00250             OCIStmtGetPieceInfo(rs->stmt->stmt, rs->stmt->con->err,
00251                                 &handle,  &type, &in_out, &iter, &dx, &piece)
00252         )
00253 
00254         /* search for the given column */
00255 
00256         for (i = 0; (res == TRUE) && (i < rs->nb_defs); i++)
00257         {
00258             OCI_Define *def = &(rs->defs[i]);
00259 
00260             if (def->col.type == OCI_CDT_LONG && def->buf.handle == handle)
00261             {
00262                 /* get the long object for the given internal row */
00263 
00264                 OCI_Long *lg = (OCI_Long *) def->buf.data[iter];
00265 
00266                 /* setup up piece size */
00267 
00268                 ub4 bufsize = rs->stmt->long_size;
00269 
00270                 if (lg->type == OCI_CLONG)
00271                     bufsize += sizeof(dtext);
00272 
00273                 /* check buffer */
00274 
00275                 if (lg->buffer == NULL)
00276                 {
00277                     lg->maxsize = bufsize;
00278 
00279                     lg->buffer  = (ub1 *) OCI_MemAlloc(OCI_IPC_LONG_BUFFER,
00280                                                        lg->maxsize, 1, FALSE);
00281 
00282                     lg->buffer[0] = 0;
00283                 }
00284                 else if (lg->size >= lg->maxsize)
00285                 {
00286                     lg->maxsize = lg->size + bufsize;
00287 
00288                     lg->buffer  = (ub1 *) OCI_MemRealloc(lg->buffer,
00289                                                          OCI_IPC_LONG_BUFFER,
00290                                                          lg->maxsize, 1);
00291                 }
00292 
00293                 res = (lg->buffer != NULL);
00294 
00295                 /* update piece info */
00296 
00297                 if (res == TRUE)
00298                 {
00299                     lg->piecesize = bufsize;
00300 
00301                     OCI_CALL1
00302                     (
00303                         res, rs->stmt->con, rs->stmt,
00304 
00305                         OCIStmtSetPieceInfo((dvoid *) handle,
00306                                             (ub4) OCI_HTYPE_DEFINE,
00307                                             lg->stmt->con->err,
00308                                             (dvoid *) (lg->buffer + lg->size),
00309                                             &lg->piecesize, piece,
00310                                             lg->def->buf.inds, (ub2 *) NULL)
00311                      )
00312 
00313                 }
00314 
00315                 break;
00316             }
00317         }
00318 
00319         /* fetch data */
00320 
00321 #if defined(OCI_STMT_SCROLLABLE_READONLY)
00322 
00323         if (OCILib.use_scrollable_cursors == TRUE)
00324         {
00325             rs->fetch_status = OCIStmtFetch2(rs->stmt->stmt, rs->stmt->con->err,
00326                                              rs->fetch_size, (ub2) OCI_FETCH_NEXT,
00327                                              (sb4) 0, (ub4) OCI_DEFAULT);
00328         }
00329         else
00330 #endif
00331         {
00332             rs->fetch_status = OCIStmtFetch(rs->stmt->stmt, rs->stmt->con->err,
00333                                             rs->fetch_size, (ub2) OCI_FETCH_NEXT,
00334                                             (ub4) OCI_DEFAULT);
00335         }
00336 
00337         if (rs->fetch_status == OCI_NO_DATA)
00338             rs->fetch_status = rs->fetch_status;
00339 
00340         /* check for return value of fetch call */
00341 
00342         if (rs->fetch_status == OCI_ERROR)
00343         {
00344               OCI_ExceptionOCI(rs->stmt->con->err, rs->stmt->con, rs->stmt);
00345               res = FALSE;
00346         }
00347         else
00348         {
00349             /* search for the given column */
00350 
00351             for (i = 0; i < rs->nb_defs; i++)
00352             {
00353                 OCI_Define *def = &rs->defs[i];
00354 
00355                 if (def->col.type == OCI_CDT_LONG && def->buf.handle == handle)
00356                 {
00357                     /* get the long object for the given internal row */
00358 
00359                     OCI_Long *lg = (OCI_Long *) def->buf.data[iter];
00360 
00361                     lg->size += lg->piecesize;
00362 
00363                     break;
00364                 }
00365             }
00366         }
00367     }
00368 
00369     /* for LONG columns, set the zero terminal string */
00370 
00371     for (i = 0; i < rs->nb_defs; i++)
00372     {
00373         OCI_Define *def = &rs->defs[i];
00374 
00375         if (def->col.type == OCI_CDT_LONG && def->col.subtype == OCI_CLONG)
00376         {
00377             for (j = 0; j < def->buf.count; j++)
00378             {
00379                 OCI_Long *lg = (OCI_Long *) def->buf.data[j];
00380 
00381                 if (lg->buffer != NULL)
00382                     lg->buffer[lg->size] = 0;
00383             }
00384         }
00385     }
00386 
00387     return res;
00388 }
00389 
00390 /* ------------------------------------------------------------------------ *
00391  * OCI_FetchData
00392  * ------------------------------------------------------------------------ */
00393 
00394 boolean OCI_FetchData(OCI_Resultset *rs, int mode, int offset, boolean *err)
00395 {
00396     boolean res  = TRUE;
00397 
00398     /* let's initialize the error flag to TRUE until the process completes */
00399 
00400     *err = TRUE;
00401 
00402     /* internal fetch */
00403 
00404 #if defined(OCI_STMT_SCROLLABLE_READONLY)
00405 
00406     if (OCILib.use_scrollable_cursors == TRUE)
00407     {
00408         rs->fetch_status = OCIStmtFetch2(rs->stmt->stmt, rs->stmt->con->err,
00409                                          rs->fetch_size, (ub2) mode, (sb4) offset,
00410                                          (ub4) OCI_DEFAULT);
00411     }
00412     else
00413 #endif
00414     {
00415         rs->fetch_status = OCIStmtFetch(rs->stmt->stmt, rs->stmt->con->err,
00416                                         rs->fetch_size, (ub2) OCI_FETCH_NEXT,
00417                                         (ub4) OCI_DEFAULT);
00418     }
00419 
00420     /* check failure */
00421 
00422     if (rs->fetch_status == OCI_ERROR)
00423     {
00424           OCI_ExceptionOCI(rs->stmt->con->err, rs->stmt->con, rs->stmt);
00425           res = FALSE;
00426     }
00427 
00428     /* do we need to do a piecewise fetch */
00429 
00430     if (rs->fetch_status == OCI_NEED_DATA)
00431         res = OCI_FetchPieces(rs);
00432 
00433     /* check string buffer for Unicode builds that need buffer expansion */
00434 
00435 #ifdef OCI_CHECK_DATASTRINGS
00436 
00437     OCI_ResultsetExpandStrings(rs);
00438 
00439 #endif
00440 
00441     /* check for success */
00442 
00443     res = ((res == TRUE) && ((rs->fetch_status == OCI_SUCCESS) ||
00444                              (rs->fetch_status == OCI_NO_DATA) ||
00445                              (rs->fetch_status == OCI_SUCCESS_WITH_INFO)));
00446 
00447     /* update internal fetch status and variables */
00448 
00449     if (res == TRUE)
00450     {
00451         ub4 row_count      = 0;
00452         ub4 row_fetched    = 0;
00453 
00454 #if defined(OCI_STMT_SCROLLABLE_READONLY)
00455 
00456         if (rs->stmt->exec_mode  == OCI_SFM_SCROLLABLE)
00457         {
00458             OCI_CALL1
00459             (
00460                 res, rs->stmt->con, rs->stmt,
00461 
00462                 OCIAttrGet((dvoid *) rs->stmt->stmt, (ub4) OCI_HTYPE_STMT,
00463                            (dvoid *) &row_count, (ub4 *) NULL,
00464                            (ub4) OCI_ATTR_CURRENT_POSITION, rs->stmt->con->err)
00465             )
00466 
00467             OCI_CALL1
00468             (
00469                 res, rs->stmt->con, rs->stmt,
00470 
00471                 OCIAttrGet((dvoid *) rs->stmt->stmt, (ub4) OCI_HTYPE_STMT,
00472                            (dvoid *) &row_fetched, (ub4 *) NULL,
00473                            (ub4) OCI_ATTR_ROWS_FETCHED, rs->stmt->con->err)
00474             )
00475         }
00476         else
00477 #endif
00478         {
00479             row_count   = OCI_GetAffectedRows(rs->stmt);
00480             row_fetched = row_count - rs->row_count;
00481 
00482         }
00483 
00484         if (rs->row_count < row_count)
00485             rs->row_count = row_count;
00486 
00487         if (row_fetched > 0)
00488             rs->row_fetched = row_fetched;
00489 
00490         /* so far, no OCI error occurred, let's clear the error flag */
00491 
00492         *err = FALSE;
00493 
00494         /* check if internal fetch was successful */
00495 
00496         if ((rs->fetch_status == OCI_NO_DATA) && (row_fetched == 0))
00497         {
00498             if ((mode == OCI_SFD_NEXT) || (offset > 0))
00499                 rs->eof = TRUE;
00500 
00501             if (offset < 0)
00502                 rs->bof = TRUE;
00503 
00504             res = FALSE;
00505         }
00506     }
00507 
00508     return res;
00509 }
00510 
00511 /* ------------------------------------------------------------------------ *
00512  * OCI_FetchCustom
00513  * ------------------------------------------------------------------------ */
00514 
00515 boolean OCI_FetchCustom(OCI_Resultset *rs, int mode, int offset, boolean *err)
00516 {
00517     boolean res = TRUE;
00518 
00519     switch (mode)
00520     {
00521         case OCI_SFD_RELATIVE:
00522         {
00523             int offset_save = 0;
00524 
00525             if (((offset > 0) && (rs->eof == TRUE)) ||
00526                 ((offset < 0) && (rs->bof == TRUE)) ||
00527                 (offset == 0))
00528             {
00529                 res = FALSE;
00530             }
00531             else
00532             {
00533                 offset_save = offset;
00534                 offset      = offset - rs->row_fetched + rs->row_cur;
00535                 rs->row_cur = 1;
00536 
00537                 res = OCI_FetchData(rs, mode, offset, err);
00538 
00539                 if (res == TRUE)
00540                     rs->row_abs += offset_save;
00541             }
00542 
00543             break;
00544        }
00545         case OCI_SFD_ABSOLUTE:
00546         {
00547             if (offset == 0)
00548             {
00549                 res = FALSE;
00550             }
00551             else
00552             {
00553                 rs->row_abs   = 1;
00554                 rs->row_cur   = 1;
00555 
00556                 res = OCI_FetchData(rs, mode, offset, err);
00557 
00558                 if (res == TRUE)
00559                 {
00560                     rs->row_abs = offset;
00561 
00562                     rs->bof       = FALSE;
00563                     rs->eof       = FALSE;
00564                 }
00565             }
00566 
00567             break;
00568         }
00569         default:
00570         {
00571             res = FALSE;
00572         }
00573     }
00574 
00575     return res;
00576 }
00577 
00578 #ifdef OCI_CHECK_DATASTRINGS
00579 
00580 /* ------------------------------------------------------------------------ *
00581  * OCI_ResultsetExpandStrings
00582  * ------------------------------------------------------------------------ */
00583 
00584 boolean OCI_ResultsetExpandStrings(OCI_Resultset *rs)
00585 {
00586     ub4 i;
00587     int j;
00588 
00589     OCI_CHECK(rs == NULL, FALSE)
00590 
00591     for (i = 0; i < rs->nb_defs; i++)
00592     {
00593         OCI_Define *def = &rs->defs[i];
00594 
00595         if (def->col.type == OCI_CDT_TEXT)
00596         {
00597             for (j = (int) (def->buf.count-1); j >= 0; j--)
00598             {
00599                 OCI_ConvertString(((ub1*) def->buf.data) + (def->col.bufsize * j),
00600                                   def->col.bufsize / sizeof(dtext), sizeof(odtext),
00601                                   sizeof(dtext));
00602             }
00603         }
00604     }
00605 
00606     return TRUE;
00607 }
00608 
00609 #endif
00610 
00611 /* ************************************************************************ *
00612  *                            PUBLIC FUNCTIONS
00613  * ************************************************************************ */
00614 
00615 /* ------------------------------------------------------------------------ *
00616  * OCI_GetResultset
00617  * ------------------------------------------------------------------------ */
00618 
00619 OCI_Resultset * OCI_API OCI_GetResultset(OCI_Statement *stmt)
00620 {
00621     OCI_Resultset *rs = NULL;
00622     boolean res       = TRUE;
00623 
00624     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, NULL);
00625 
00626     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_CLOSED, FALSE);
00627     OCI_CHECK_STMT_STATUS(stmt, OCI_STMT_PREPARED, FALSE);
00628 
00629     /* if the sql statement does not return a result, we just return NULL and not
00630        throwing any exception */
00631 
00632     if ((stmt->type != OCI_CST_SELECT) || (stmt->nb_rbinds == 0))
00633     {
00634         /* if the resultset exists, let's use it */
00635 
00636         if ((stmt->rsts != NULL) && (stmt->rsts[0] != NULL))
00637         {
00638             rs = stmt->rsts[0];
00639         }
00640 
00641         /* allocate resultset for select statements */
00642 
00643         if ((rs == NULL)  && (stmt->type == OCI_CST_SELECT))
00644         {
00645             /* allocate memory for one resultset handle */
00646 
00647             stmt->rsts = (OCI_Resultset **) OCI_MemAlloc(OCI_IPC_RESULTSET_ARRAY,
00648                                                          sizeof(*stmt->rsts),
00649                                                          1, TRUE);
00650             if (stmt->rsts != NULL)
00651             {
00652                 stmt->nb_rs   = 1;
00653                 stmt->cur_rs  = 0;
00654 
00655                 /* create resultset object */
00656 
00657                 rs = OCI_ResultsetCreate(stmt, stmt->fetch_size);
00658 
00659                 if (rs != NULL)
00660                     stmt->rsts[0] = rs;
00661                 else
00662                     res = FALSE;
00663             }
00664             else
00665                 res = FALSE;
00666         }
00667     }
00668 
00669     OCI_RESULT(res);
00670 
00671     return rs;
00672 }
00673 
00674 /* ------------------------------------------------------------------------ v*
00675  * OCI_GetNextResultset
00676  * ------------------------------------------------------------------------ */
00677 
00678 OCI_Resultset * OCI_API OCI_GetNextResultset(OCI_Statement *stmt)
00679 {
00680     OCI_Resultset *rs = NULL;
00681 
00682     OCI_CHECK_PTR(OCI_IPC_STATEMENT, stmt, FALSE);
00683 
00684     if (stmt->cur_rs < (stmt->nb_rs-1))
00685         rs = stmt->rsts[++stmt->cur_rs];
00686 
00687     OCI_RESULT(TRUE);
00688 
00689     return rs;
00690 }
00691 
00692 /* ------------------------------------------------------------------------ *
00693  * OCI_ResultsetFree
00694  * ------------------------------------------------------------------------ */
00695 
00696 boolean OCI_ResultsetFree(OCI_Resultset *rs)
00697 {
00698     boolean res = TRUE;
00699     ub4 i, j;
00700 
00701     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, FALSE);
00702 
00703     for (i = 0; i < rs->nb_defs; i++)
00704     {
00705         OCI_Define *def = &(rs->defs[i]);
00706 
00707         /* free buffer objects */
00708 
00709         if (def->obj != NULL)
00710         {
00711             /* handy cast to set object state flag */
00712 
00713            ((OCI_Datatype *) def->obj)->hstate = OCI_OBJECT_FETCHED_DIRTY;
00714 
00715            switch (def->col.type)
00716             {
00717                 case OCI_CDT_DATETIME:
00718 
00719                     OCI_DateFree((OCI_Date *) def->obj);
00720                     break;
00721 
00722                 case OCI_CDT_LOB:
00723 
00724                     OCI_LobFree((OCI_Lob *) def->obj);
00725                     break;
00726 
00727                case OCI_CDT_FILE:
00728 
00729                     OCI_FileFree((OCI_File *) def->obj);
00730                     break;
00731 
00732                case OCI_CDT_CURSOR:
00733 
00734                     OCI_StatementClose((OCI_Statement *) def->obj);
00735                     OCI_FREE(def->obj);
00736                     break;
00737 
00738               case OCI_CDT_OBJECT:
00739 
00740                     OCI_ObjectFree((OCI_Object *) def->obj);
00741                     break;
00742 
00743               case OCI_CDT_COLLECTION:
00744 
00745                     OCI_CollFree((OCI_Coll *) def->obj);
00746                     break;
00747 
00748               case OCI_CDT_REF:
00749 
00750                     OCI_RefFree((OCI_Ref *) def->obj);
00751                     break;
00752 
00753                case OCI_CDT_TIMESTAMP:
00754 
00755                     OCI_TimestampFree((OCI_Timestamp *) def->obj);
00756                     break;
00757 
00758                case OCI_CDT_INTERVAL:
00759 
00760                     OCI_IntervalFree((OCI_Interval *) def->obj);
00761                     break;
00762             }
00763 
00764             def->obj = NULL;
00765         }
00766 
00767         /* free OCI handles */
00768 
00769         if (def->col.dtype != 0)
00770         {
00771             for(j=0; j < def->buf.count; j++)
00772             {
00773                 if (def->col.type == OCI_CDT_CURSOR)
00774                 {
00775                     OCI_HandleFree((dvoid *) def->buf.data[j],
00776                                    (ub4    ) def->col.dtype);
00777                 }
00778                 else
00779                 {
00780                     OCI_DescriptorFree((dvoid *) def->buf.data[j],
00781                                        (ub4    ) def->col.dtype);
00782                 }
00783 
00784             }
00785         }
00786 
00787         /* free OCI long buffers */
00788 
00789         if (def->col.type == OCI_CDT_LONG && def->buf.data != NULL)
00790         {
00791             for(j=0; j < def->buf.count; j++)
00792             {
00793                 if (def->buf.data[j] != NULL)
00794                 {
00795                    ((OCI_Datatype *) def->buf.data[j])->hstate = OCI_OBJECT_FETCHED_DIRTY;
00796 
00797                     OCI_LongFree((OCI_Long *) def->buf.data[j]);
00798                 }
00799             }
00800         }
00801 
00802         /* free column pointers */
00803 
00804         OCI_FREE(def->col.name);
00805 
00806         /* free buffer pointers */
00807 
00808         OCI_FREE(def->buf.data);
00809         OCI_FREE(def->buf.inds);
00810         OCI_FREE(def->buf.lens);
00811         OCI_FREE(def->buf.temp);
00812    }
00813 
00814     /* free column map */
00815 
00816     if (rs->map != NULL)
00817     {
00818         OCI_HashFree(rs->map);
00819     }
00820 
00821     /* free defines (column array) */
00822 
00823     OCI_FREE(rs->defs);
00824 
00825     OCI_FREE(rs);
00826 
00827     OCI_RESULT(res);
00828 
00829     return res;
00830 }
00831 
00832 /* ------------------------------------------------------------------------ *
00833  * OCI_FetchPrev
00834  * ------------------------------------------------------------------------ */
00835 
00836 boolean OCI_API OCI_FetchPrev(OCI_Resultset *rs)
00837 {
00838     boolean res = TRUE;
00839     boolean err = FALSE;
00840 
00841     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, FALSE);
00842 
00843     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(rs->stmt->con, FALSE);
00844 
00845 #if OCI_VERSION_COMPILE >= OCI_9_0
00846 
00847     OCI_CHECK_SCROLLABLE_CURSOR_ACTIVATED(rs->stmt, FALSE);
00848 
00849     if (rs->bof == FALSE)
00850     {
00851         if (rs->row_cur == 1)
00852         {
00853             if (rs->row_abs == 1)
00854             {
00855                 rs->bof = TRUE;
00856             }
00857             else
00858             {
00859                 int offset = 0;
00860                 
00861                 if (rs->fetch_size > rs->row_abs)
00862                     offset = 1 - rs->row_abs;  
00863                 else
00864                     offset = 1 - (rs->fetch_size + rs->row_fetched);
00865 
00866                 res = OCI_FetchData(rs, OCI_SFD_RELATIVE, offset, &err);
00867 
00868                 if (res == TRUE)
00869                 {
00870                     if (rs->fetch_size > rs->row_abs)
00871                         rs->row_cur = rs->row_abs-1;
00872                     else
00873                         rs->row_cur = rs->fetch_size;
00874 
00875                     rs->row_abs--;
00876                 }
00877             }
00878         }
00879         else
00880         {
00881             rs->row_cur--;
00882             rs->row_abs--;
00883         }
00884 
00885         rs->eof = FALSE;
00886 
00887         res = ((res == TRUE) && (rs->bof == FALSE));
00888     }
00889     else
00890         res = FALSE;
00891 
00892 #else
00893 
00894     res = FALSE;
00895 
00896 #endif
00897 
00898     OCI_RESULT(err);
00899 
00900     return res;
00901 }
00902 
00903 /* ------------------------------------------------------------------------ *
00904  * OCI_FetchNext
00905  * ------------------------------------------------------------------------ */
00906 
00907 boolean OCI_API OCI_FetchNext(OCI_Resultset *rs)
00908 {
00909     boolean res = TRUE;
00910     boolean err = FALSE;
00911 
00912     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, FALSE);
00913 
00914     if (rs->eof == FALSE)
00915     {
00916         if (rs->stmt->nb_rbinds == 0)
00917         {
00918             /* for regular resultsets */
00919 
00920             if ((rs->row_cur == rs->row_fetched))
00921             {
00922                 if (rs->fetch_status == OCI_NO_DATA)
00923                 {
00924                     rs->eof = TRUE;
00925                 }
00926                 else
00927                 {
00928                     res = OCI_FetchData(rs, OCI_SFD_NEXT, 0, &err);
00929 
00930                     if (res == TRUE)
00931                     {
00932                         rs->bof     = FALSE;
00933                         rs->row_cur = 1;
00934 
00935                         rs->row_abs++;
00936                     }
00937                 }
00938             }
00939             else
00940             {
00941                 rs->row_cur++;
00942                 rs->row_abs++;
00943             }
00944         }
00945         else
00946         {
00947             /* for resultset from returning into clause */
00948 
00949             if (rs->row_abs == 0)
00950             {
00951                 /* check string buffer once for Unicode build */
00952 
00953             #ifdef OCI_CHECK_DATASTRINGS
00954 
00955                 OCI_ResultsetExpandStrings(rs);
00956 
00957             #endif
00958 
00959             }
00960 
00961             if (rs->row_abs >= rs->row_count)
00962             {
00963                 rs->eof = TRUE;
00964             }
00965             else
00966             {
00967                 rs->row_cur++;
00968                 rs->row_abs++;
00969             }
00970         }
00971     }
00972     else
00973         res = FALSE;
00974 
00975     OCI_RESULT(err);
00976 
00977     return ((res == TRUE) && (rs->eof == FALSE));
00978 }
00979 
00980 /* ------------------------------------------------------------------------ *
00981  * OCI_FetchFirst
00982  * ------------------------------------------------------------------------ */
00983 
00984 boolean OCI_API OCI_FetchFirst(OCI_Resultset *rs)
00985 {
00986     boolean res = TRUE;
00987     boolean err = FALSE;
00988 
00989     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, FALSE);
00990 
00991     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(rs->stmt->con, FALSE);
00992 
00993 #if OCI_VERSION_COMPILE >= OCI_9_0
00994 
00995     OCI_CHECK_SCROLLABLE_CURSOR_ACTIVATED(rs->stmt, FALSE);
00996 
00997     rs->bof       = FALSE;
00998     rs->eof       = FALSE;
00999 
01000     rs->row_abs   = 1;
01001     rs->row_cur   = 1;
01002 
01003     res = OCI_FetchData(rs, OCI_SFD_FIRST, 0, &err);
01004 
01005 #else
01006 
01007     res = FALSE;
01008     err = TRUE;
01009 
01010 #endif
01011 
01012     OCI_RESULT(err);
01013 
01014     return ((res == TRUE) && (rs->bof == FALSE));
01015 }
01016 
01017 /* ------------------------------------------------------------------------ *
01018  * OCI_FetchLast
01019  * ------------------------------------------------------------------------ */
01020 
01021 boolean OCI_API OCI_FetchLast(OCI_Resultset *rs)
01022 {
01023     boolean res = TRUE;
01024     boolean err = FALSE;
01025 
01026     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, FALSE);
01027 
01028     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(rs->stmt->con, FALSE);
01029 
01030 #if OCI_VERSION_COMPILE >= OCI_9_0
01031 
01032     OCI_CHECK_SCROLLABLE_CURSOR_ACTIVATED(rs->stmt, FALSE);
01033 
01034     rs->bof       = FALSE;
01035     rs->eof       = FALSE;
01036 
01037     rs->row_abs   = 0;
01038     rs->row_cur   = 1;
01039 
01040     res = OCI_FetchData(rs, OCI_SFD_LAST, 0, &err);
01041 
01042     rs->row_abs = rs->row_count;
01043 
01044 #else
01045 
01046     res = FALSE;
01047     err = TRUE;
01048 
01049 #endif
01050 
01051     OCI_RESULT(err);
01052 
01053     return ((res == TRUE) && (rs->eof != TRUE));
01054 }
01055 
01056 /* ------------------------------------------------------------------------ *
01057  * OCI_FetchSeek
01058  * ------------------------------------------------------------------------ */
01059 
01060 boolean OCI_API OCI_FetchSeek(OCI_Resultset *rs, unsigned int mode, int offset)
01061 {
01062     boolean res = TRUE;
01063     boolean err = FALSE;
01064 
01065     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, FALSE);
01066 
01067     OCI_CHECK_SCROLLABLE_CURSOR_ENABLED(rs->stmt->con, FALSE);
01068 
01069 #if OCI_VERSION_COMPILE >= OCI_9_0
01070 
01071     OCI_CHECK_SCROLLABLE_CURSOR_ACTIVATED(rs->stmt, FALSE);
01072 
01073     res = OCI_FetchCustom(rs, mode, offset, &err);
01074 
01075 #else
01076 
01077     OCI_NOT_USED(mode);
01078     OCI_NOT_USED(offset);
01079 
01080     res = FALSE;
01081     err = TRUE;
01082 
01083 #endif
01084 
01085     OCI_RESULT(err);
01086 
01087     return res;
01088 }
01089 
01090 /* ------------------------------------------------------------------------ *
01091  * OCI_GetRowCount
01092  * ------------------------------------------------------------------------ */
01093 
01094 unsigned int OCI_API OCI_GetRowCount(OCI_Resultset *rs)
01095 {
01096     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, 0);
01097 
01098     OCI_RESULT(TRUE);
01099 
01100     return rs->row_count;
01101 }
01102 
01103 /* ------------------------------------------------------------------------ *
01104  * OCI_GetRowCount
01105  * ------------------------------------------------------------------------ */
01106 
01107 unsigned int OCI_API OCI_GetCurrentRow(OCI_Resultset *rs)
01108 {
01109     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, 0);
01110 
01111     OCI_RESULT(TRUE);
01112 
01113     return rs->row_abs;
01114 }
01115 
01116 /* ------------------------------------------------------------------------ *
01117  * OCI_GetColumnCount
01118  * ------------------------------------------------------------------------ */
01119 
01120 unsigned int OCI_API OCI_GetColumnCount(OCI_Resultset *rs)
01121 {
01122     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, 0);
01123 
01124     OCI_RESULT(TRUE);
01125 
01126     return rs->nb_defs;
01127 }
01128 
01129 /* ------------------------------------------------------------------------ *
01130  * OCI_GetColumn
01131  * ------------------------------------------------------------------------ */
01132 
01133 OCI_Column * OCI_API OCI_GetColumn(OCI_Resultset *rs, unsigned int index)
01134 {
01135     OCI_Define *def = NULL;
01136     OCI_Column *col = NULL;
01137 
01138     def = OCI_GetDefine(rs, index);
01139 
01140     if (def != NULL)
01141         col = &def->col;
01142 
01143     OCI_RESULT(col != NULL);
01144 
01145     return col;
01146 
01147 }
01148 
01149 /* ------------------------------------------------------------------------ *
01150  * OCI_GetColumn2
01151  * ------------------------------------------------------------------------ */
01152 
01153 OCI_Column * OCI_API OCI_GetColumn2(OCI_Resultset *rs, const mtext *name)
01154 {
01155     OCI_Define *def = NULL;
01156     OCI_Column *col = NULL;
01157 
01158     def = OCI_GetDefine(rs, OCI_GetDefineIndex(rs, name));
01159 
01160     if (def != NULL)
01161         col = &def->col;
01162 
01163     OCI_RESULT(col != NULL);
01164 
01165     return col;
01166 }
01167 
01168 /* ------------------------------------------------------------------------ *
01169  * OCI_GetColumnIndex
01170  * ------------------------------------------------------------------------ */
01171 
01172 unsigned int OCI_API OCI_GetColumnIndex(OCI_Resultset *rs, const mtext *name)
01173 {
01174    unsigned int index = OCI_GetDefineIndex(rs, name);
01175 
01176    OCI_RESULT(index >= 1);
01177 
01178    return index;
01179 }
01180 
01181 /* ------------------------------------------------------------------------ *
01182  * OCI_GetShort
01183  * ------------------------------------------------------------------------ */
01184 
01185 short OCI_API OCI_GetShort(OCI_Resultset *rs, unsigned int index)
01186 {
01187     short value = 0;
01188 
01189     OCI_DefineGetNumber(rs, index, &value, OCI_NUM_SHORT, sizeof(value));
01190 
01191     return value;
01192 }
01193 
01194 /* ------------------------------------------------------------------------ *
01195  * OCI_GetShort2
01196  * ------------------------------------------------------------------------ */
01197 
01198 short OCI_API OCI_GetShort2(OCI_Resultset *rs, const mtext *name)
01199 {
01200     return OCI_GetShort(rs, OCI_GetDefineIndex(rs, name));
01201 }
01202 
01203 /* ------------------------------------------------------------------------ *
01204  * OCI_GetUnsignedShort
01205  * ------------------------------------------------------------------------ */
01206 
01207 unsigned short OCI_API OCI_GetUnsignedShort(OCI_Resultset *rs, unsigned int index)
01208 {
01209     unsigned short value = 0;
01210 
01211     OCI_DefineGetNumber(rs, index, &value, OCI_NUM_USHORT, sizeof(value));
01212 
01213     return value;
01214 }
01215 
01216 /* ------------------------------------------------------------------------ *
01217  * OCI_GetUnsignedShort2
01218  * ------------------------------------------------------------------------ */
01219 
01220 unsigned short OCI_API OCI_GetUnsignedShort2(OCI_Resultset *rs, const mtext *name)
01221 {
01222     return OCI_GetUnsignedShort(rs, OCI_GetDefineIndex(rs, name));
01223 }
01224 
01225 /* ------------------------------------------------------------------------ *
01226  * OCI_GetInt
01227  * ------------------------------------------------------------------------ */
01228 
01229 int OCI_API OCI_GetInt(OCI_Resultset *rs, unsigned int index)
01230 {
01231     int value = 0;
01232 
01233     OCI_DefineGetNumber(rs, index, &value, OCI_NUM_INT, sizeof(value));
01234 
01235     return value;
01236 }
01237 
01238 /* ------------------------------------------------------------------------ *
01239  * OCI_GetInt2
01240  * ------------------------------------------------------------------------ */
01241 
01242 int OCI_API OCI_GetInt2(OCI_Resultset *rs, const mtext *name)
01243 {
01244     return OCI_GetInt(rs, OCI_GetDefineIndex(rs, name));
01245 }
01246 
01247 /* ------------------------------------------------------------------------ *
01248  * OCI_GetUnsignedInt
01249  * ------------------------------------------------------------------------ */
01250 
01251 unsigned int OCI_API OCI_GetUnsignedInt(OCI_Resultset *rs, unsigned int index)
01252 {
01253     unsigned int value = 0;
01254 
01255     OCI_DefineGetNumber(rs, index, &value, OCI_NUM_UINT, sizeof(value));
01256 
01257     return value;
01258 }
01259 
01260 /* ------------------------------------------------------------------------ *
01261  * OCI_GetUnsignedInt2
01262  * ------------------------------------------------------------------------ */
01263 
01264 unsigned int OCI_API OCI_GetUnsignedInt2(OCI_Resultset *rs, const mtext *name)
01265 {
01266     return OCI_GetUnsignedInt(rs, OCI_GetDefineIndex(rs, name));
01267 }
01268 
01269 /* ------------------------------------------------------------------------ *
01270  * OCI_GetBigInt
01271  * ------------------------------------------------------------------------ */
01272 
01273 big_int OCI_API OCI_GetBigInt(OCI_Resultset *rs, unsigned int index)
01274 {
01275     big_int value = 0;
01276 
01277     OCI_DefineGetNumber(rs, index, &value, OCI_NUM_BIGINT, sizeof(value));
01278 
01279     return value;
01280 }
01281 
01282 /* ------------------------------------------------------------------------ *
01283  * OCI_GetBigInt2
01284  * ------------------------------------------------------------------------ */
01285 
01286 big_int OCI_API OCI_GetBigInt2(OCI_Resultset *rs, const mtext *name)
01287 {
01288     return OCI_GetBigInt(rs, OCI_GetDefineIndex(rs, name));
01289 }
01290 
01291 /* ------------------------------------------------------------------------ *
01292  * OCI_GetUnsignedBigInt
01293  * ------------------------------------------------------------------------ */
01294 
01295 big_uint OCI_API OCI_GetUnsignedBigInt(OCI_Resultset *rs, unsigned int index)
01296 {
01297     big_uint value = 0;
01298 
01299     OCI_DefineGetNumber(rs, index, &value, OCI_NUM_BIGUINT, sizeof(value));
01300 
01301     return value;
01302 }
01303 
01304 /* ------------------------------------------------------------------------ *
01305  * OCI_GetUnsignedInt2
01306  * ------------------------------------------------------------------------ */
01307 
01308 big_uint OCI_API OCI_GetUnsignedBigInt2(OCI_Resultset *rs, const mtext *name)
01309 {
01310     return OCI_GetUnsignedBigInt(rs, OCI_GetDefineIndex(rs, name));
01311 }
01312 
01313 /* ------------------------------------------------------------------------ *
01314  * OCI_GetString
01315  * ------------------------------------------------------------------------ */
01316 
01317 const dtext * OCI_API OCI_GetString(OCI_Resultset *rs, unsigned int index)
01318 {
01319     OCI_Define *def  = OCI_GetDefine(rs, index);
01320     dtext *str       = NULL;
01321     boolean res      = TRUE;
01322 
01323     res = (def != NULL);
01324 
01325     if ((res == TRUE) && (OCI_NOT_NULL(def) == TRUE))
01326     {
01327         void *data   = OCI_DefineGetData(def);
01328 
01329         if (def->col.type == OCI_CDT_TEXT)
01330         {
01331             str = (dtext *) data;
01332 
01333             /* for long mapped to string, the zero terminal character is not
01334                always added by Oracle ? or OCILIB issue ? Anyway we check the
01335                length returned by Oracle and set it properly */
01336 
01337             if (def->col.subtype == OCI_CLONG)
01338             {
01339                 ub2* lens = (ub2 *) def->buf.lens;
01340 
01341                 str[lens[rs->row_cur-1]] = 0;
01342             }
01343         }
01344         else
01345         {
01346             /* tries an implicit conversion if possible */
01347 
01348             if (def->buf.temp == NULL)
01349             {
01350                 def->buf.temp = (dtext *) OCI_MemAlloc(OCI_IPC_STRING,
01351                                                        sizeof(dtext),
01352                                                        (OCI_SIZE_BUFFER+1),
01353                                                        FALSE);
01354 
01355                 res = (def->buf.temp != NULL);
01356             }
01357 
01358             if (res == TRUE)
01359             {
01360                 def->buf.temp[0] = 0;
01361 
01362                 switch (def->col.type)
01363                 {
01364                     case OCI_CDT_NUMERIC:
01365                     {
01366                         void *ostr1 = NULL;
01367                         void *ostr2 = NULL;
01368                         int  osize1 = OCI_SIZE_FORMAT_NUML * sizeof(mtext);
01369                         int  osize2 = OCI_SIZE_BUFFER      * sizeof(dtext);
01370                         const mtext *fmt;
01371                         int pos;
01372 
01373                         def->buf.temp[0] = 0;
01374 
01375                         /* init output buffer in case of OCI failure */
01376 
01377                         fmt   = OCI_GetDefaultFormatNumeric(rs->stmt->con);
01378                         ostr1 = OCI_GetInputMetaString(fmt, &osize1);
01379                         
01380 #ifndef OCI_CHARSET_MIXED
01381 
01382                         ostr2 = OCI_GetInputString(def->buf.temp, &osize2,
01383                                                    sizeof(dtext), sizeof(omtext));
01384 #else
01385 
01386                         ostr2 = (void* ) def->buf.temp;
01387 
01388 #endif
01389 
01390                         /* check for decimal character */
01391 
01392                         OCI_CALL1
01393                         (
01394                             res, rs->stmt->con, rs->stmt,
01395 
01396                                 OCINumberToText(rs->stmt->con->err,
01397                                                 (OCINumber *) data,
01398                                                 (oratext *) ostr1,
01399                                                 (ub4) osize1,
01400                                                 (oratext *) NULL,
01401                                                 (ub4) 0,
01402                                                 (ub4 *) &osize2,
01403                                                 (oratext *) ostr2)
01404                         )
01405 
01406 #ifndef OCI_CHARSET_MIXED
01407 
01408                         OCI_GetOutputString(ostr2, def->buf.temp, &osize2,
01409                                             sizeof(omtext), sizeof(dtext));
01410 
01411 #else
01412                         
01413                         OCI_ConvertString(ostr2, osize2/sizeof(omtext)+1,
01414                                           sizeof(omtext), sizeof(dtext));
01415 
01416                         osize2 = (osize2/sizeof(omtext)) * sizeof(dtext);                   
01417 
01418 #endif
01419                         /* do we need to suppress last '.' or ',' from integers */
01420 
01421                         pos = (osize2 / sizeof(dtext)) - 1;
01422 
01423                         if (pos >= 0)
01424                         {
01425                             if ((def->buf.temp[pos] == DT('.')) ||
01426                                 (def->buf.temp[pos] == DT(',')))
01427                             {
01428                                 def->buf.temp[pos] = 0;
01429                             }
01430                         }
01431 
01432                         OCI_ReleaseMetaString(ostr1);
01433                         
01434 #ifndef OCI_CHARSET_MIXED
01435                         OCI_ReleaseDataString(ostr2);
01436 #endif
01437                         if (res == TRUE)
01438                             str = def->buf.temp;
01439 
01440                         break;
01441                     }
01442                     case OCI_CDT_DATETIME:
01443                     {
01444                         OCI_Date *date   = OCI_GetDate(rs, index);
01445                         const mtext *fmt = OCI_GetDefaultFormatDate(rs->stmt->con);
01446 
01447                         if (date != NULL)
01448                         {
01449 #ifndef OCI_CHARSET_MIXED
01450                              res = OCI_DateToText(date, fmt, OCI_SIZE_BUFFER,
01451                                                   (mtext *) def->buf.temp);
01452 #else
01453 
01454                             /* mixed mode... conversion needed ! */
01455 
01456                             mtext temp[OCI_SIZE_BUFFER+1];
01457 
01458                             temp[0] = 0;
01459 
01460                             res = OCI_DateToText(date, fmt, OCI_SIZE_BUFFER, temp);
01461 
01462                             mbstowcs(def->buf.temp, temp, strlen(temp) + OCI_CVT_CHAR);
01463  #endif
01464 
01465                             str = def->buf.temp;
01466                         }
01467 
01468                         break;
01469                     }
01470                     case OCI_CDT_TIMESTAMP:
01471                     {
01472                         OCI_Timestamp *tmsp = OCI_GetTimestamp(rs, index);
01473                         const mtext *fmt    = OCI_GetDefaultFormatDate(rs->stmt->con);
01474 
01475                         if (tmsp != NULL)
01476                         {
01477 #ifndef OCI_CHARSET_MIXED
01478 
01479                             OCI_TimestampToText(tmsp, fmt, OCI_SIZE_BUFFER,
01480                                                 (mtext *) def->buf.temp,  0);
01481 #else
01482 
01483                             /* mixed mode... conversion needed ! */
01484 
01485                             mtext temp[OCI_SIZE_BUFFER+1];
01486 
01487                             temp[0] = 0;
01488 
01489                             OCI_TimestampToText(tmsp, fmt, OCI_SIZE_BUFFER,
01490                                                 (mtext *) temp, 0);
01491 
01492                             mbstowcs(def->buf.temp, temp, strlen(temp) + OCI_CVT_CHAR);
01493          #endif
01494                             str = def->buf.temp;
01495                         }
01496 
01497                         break;
01498                     }
01499                     case OCI_CDT_INTERVAL:
01500                     {
01501                          OCI_Interval *itv = OCI_GetInterval(rs, index);
01502 
01503                          if (itv != NULL)
01504                          {
01505 #ifndef OCI_CHARSET_MIXED
01506                              OCI_IntervalToText(OCI_GetInterval(rs, index),
01507                                                 OCI_STRING_DEFAULT_PREC,
01508                                                 OCI_STRING_DEFAULT_PREC,
01509                                                 OCI_SIZE_BUFFER,
01510                                                 (mtext *) def->buf.temp);
01511 #else
01512 
01513                             /* mixed mode... conversion needed ! */
01514 
01515                             mtext temp[OCI_SIZE_BUFFER+1];
01516 
01517                             temp[0] = 0;
01518 
01519                             OCI_IntervalToText(OCI_GetInterval(rs, index),
01520                                                OCI_STRING_DEFAULT_PREC,
01521                                                OCI_STRING_DEFAULT_PREC,
01522                                                OCI_SIZE_BUFFER, (mtext *) temp);
01523 
01524                             mbstowcs(def->buf.temp, temp, strlen(temp) + OCI_CVT_CHAR);
01525  #endif
01526                            str = def->buf.temp;
01527                         }
01528 
01529                         break;
01530                     }
01531                     case OCI_CDT_LONG:
01532                     {
01533                         OCI_Long *lg = OCI_GetLong(rs, index);
01534 
01535                         if (lg != NULL)
01536                             str = OCI_LongGetBuffer(lg);
01537 
01538                         break;
01539 
01540                     }
01541                     case OCI_CDT_RAW:
01542                     {
01543                         str = (dtext *) data;
01544 
01545                         break;
01546 
01547                     }
01548                     case OCI_CDT_LOB:
01549                     {
01550                         OCI_Lob *lob = OCI_GetLob(rs, index);
01551                         unsigned int len = 0;
01552 
01553                         len = OCI_LobRead(lob, def->buf.temp, OCI_SIZE_BUFFER);
01554 
01555                         def->buf.temp[len] = 0;
01556 
01557                         OCI_LobSeek(lob, 0, OCI_SEEK_SET);
01558 
01559                         str = def->buf.temp;
01560 
01561                         break;
01562 
01563                     }
01564                     case OCI_CDT_FILE:
01565                     {
01566                         OCI_File *file = OCI_GetFile(rs, index);
01567                         unsigned int len = 0;
01568 
01569                         len = OCI_FileRead(file, def->buf.temp, OCI_SIZE_BUFFER);
01570 
01571                         def->buf.temp[len] = 0;
01572 
01573                         OCI_FileSeek(file, 0, OCI_SEEK_SET);
01574 
01575                         str = def->buf.temp;
01576 
01577                         break;
01578 
01579                     }
01580                     case OCI_CDT_REF:
01581                     {
01582                         OCI_Ref *ref = OCI_GetRef(rs, index);
01583 
01584                         if (ref != NULL)
01585                         {
01586 
01587 #ifndef OCI_CHARSET_MIXED
01588 
01589                             OCI_RefToText(ref, OCI_SIZE_BUFFER, (mtext *) def->buf.temp);
01590 
01591 #else
01592                             /* mixed mode... conversion needed ! */
01593 
01594                             mtext temp[OCI_SIZE_BUFFER+1];
01595 
01596                             temp[0] = 0;
01597 
01598                             OCI_RefToText(ref, OCI_SIZE_BUFFER, (mtext *) temp);
01599 
01600                             mbstowcs(def->buf.temp, temp, strlen(temp) + OCI_CVT_CHAR);
01601  #endif
01602 
01603                            str = def->buf.temp;
01604                         }
01605 
01606                         break;
01607                     }
01608                     default:
01609                     {
01610                         res = FALSE;
01611                     }
01612                 }
01613             }
01614         }
01615     }
01616 
01617     OCI_RESULT(res);
01618 
01619     return str;
01620 }
01621 
01622 /* ------------------------------------------------------------------------ *
01623  * OCI_GetString2
01624  * ------------------------------------------------------------------------ */
01625 
01626 const dtext * OCI_API OCI_GetString2(OCI_Resultset *rs, const mtext *name)
01627 {
01628     return OCI_GetString(rs, OCI_GetDefineIndex(rs, name));
01629 }
01630 
01631 /* ------------------------------------------------------------------------ *
01632  * OCI_GetRaw
01633  * ------------------------------------------------------------------------ */
01634 
01635 unsigned int OCI_API OCI_GetRaw(OCI_Resultset *rs, unsigned int index,
01636                                 void *buffer, unsigned int len)
01637 {
01638     OCI_Define *def = OCI_GetDefine(rs, index);
01639     boolean res     = TRUE;
01640     ub2 count       = (ub2) len;
01641 
01642     OCI_CHECK_PTR(OCI_IPC_VOID, buffer, 0);
01643 
01644     res = (def != NULL);
01645 
01646     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_RAW))
01647     {
01648         ub2 size = ((ub2*)def->buf.lens)[def->rs->row_cur-1];
01649 
01650         if (count > size)
01651             count = size;
01652 
01653         /* for RAWs, we copy the data in the destination buffer instead of
01654            returning internal buffer as we do for strings */
01655 
01656         memcpy(buffer, OCI_DefineGetData(def), count);
01657 
01658     }
01659 
01660     OCI_RESULT(res);
01661 
01662     if (res == FALSE)
01663         count  = 0;
01664 
01665     return (unsigned int) count;
01666 }
01667 
01668 /* ------------------------------------------------------------------------ *
01669  * OCI_GetRaw2
01670  * ------------------------------------------------------------------------ */
01671 
01672 unsigned int OCI_API OCI_GetRaw2(OCI_Resultset *rs, const mtext *name,
01673                                  void *buffer, unsigned int len)
01674 {
01675     return OCI_GetRaw(rs, OCI_GetDefineIndex(rs, name), buffer, len);
01676 }
01677 
01678 /* ------------------------------------------------------------------------ *
01679  * OCI_GetDouble
01680  * ------------------------------------------------------------------------ */
01681 
01682 double OCI_API OCI_GetDouble(OCI_Resultset *rs, unsigned int index)
01683 {
01684     double value = 0.0;
01685 
01686     OCI_DefineGetNumber(rs, index, &value, OCI_NUM_DOUBLE, sizeof(value));
01687 
01688     return value;
01689 }
01690 
01691 /* ------------------------------------------------------------------------ *
01692  * OCI_GetDouble2
01693  * ------------------------------------------------------------------------ */
01694 
01695 double OCI_API OCI_GetDouble2(OCI_Resultset *rs, const mtext *name)
01696 {
01697     return OCI_GetDouble(rs, OCI_GetDefineIndex(rs, name));
01698 }
01699 
01700 /* ------------------------------------------------------------------------ *
01701  * OCI_GetDate
01702  * ------------------------------------------------------------------------ */
01703 
01704 OCI_Date * OCI_API OCI_GetDate(OCI_Resultset *rs, unsigned int index)
01705 {
01706     OCI_Define *def = OCI_GetDefine(rs, index);
01707     OCI_Date *date  = NULL;
01708 
01709     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_DATETIME))
01710     {
01711          date =  OCI_DateInit(rs->stmt->con,
01712                              (OCI_Date **) &def->obj,
01713                              (OCIDate *) OCI_DefineGetData(def), FALSE,
01714                              (def->col.icode == SQLT_DAT));
01715     }
01716 
01717     OCI_RESULT(date != NULL);
01718 
01719     return date;
01720 }
01721 
01722 /* ------------------------------------------------------------------------ *
01723  * OCI_GetDate2
01724  * ------------------------------------------------------------------------ */
01725 
01726 OCI_Date * OCI_API OCI_GetDate2(OCI_Resultset *rs, const mtext *name)
01727 {
01728     return OCI_GetDate(rs, OCI_GetDefineIndex(rs, name));
01729 }
01730 
01731 /* ------------------------------------------------------------------------ *
01732  * OCI_GetTimestamp
01733  * ------------------------------------------------------------------------ */
01734 
01735 OCI_Timestamp * OCI_API OCI_GetTimestamp(OCI_Resultset *rs, unsigned int index)
01736 {
01737     OCI_Define *def     = OCI_GetDefine(rs, index);
01738     OCI_Timestamp *tmsp = NULL;
01739 
01740     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_TIMESTAMP))
01741     {
01742         tmsp =  OCI_TimestampInit(rs->stmt->con,
01743                                   (OCI_Timestamp **) &def->obj,
01744                                   (OCIDateTime *) OCI_DefineGetData(def),
01745                                   def->col.subtype);
01746     }
01747 
01748     OCI_RESULT(tmsp != NULL);
01749 
01750     return tmsp;
01751 }
01752 
01753 /* ------------------------------------------------------------------------ *
01754  * OCI_GetTimestamp2
01755  * ------------------------------------------------------------------------ */
01756 
01757 OCI_Timestamp * OCI_API OCI_GetTimestamp2(OCI_Resultset *rs, const mtext *name)
01758 {
01759     return OCI_GetTimestamp(rs, OCI_GetDefineIndex(rs, name));
01760 }
01761 
01762 /* ------------------------------------------------------------------------ *
01763  * OCI_GetInterval
01764  * ------------------------------------------------------------------------ */
01765 
01766 OCI_Interval * OCI_API OCI_GetInterval(OCI_Resultset *rs, unsigned int index)
01767 {
01768     OCI_Define *def   = OCI_GetDefine(rs, index);
01769     OCI_Interval *itv = NULL;
01770 
01771     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_INTERVAL))
01772     {
01773         itv = OCI_IntervalInit(rs->stmt->con,
01774                                (OCI_Interval **) &def->obj,
01775                                (OCIInterval *) OCI_DefineGetData(def),
01776                                def->col.subtype);
01777     }
01778 
01779     OCI_RESULT(itv != NULL);
01780 
01781     return itv;
01782 }
01783 
01784 /* ------------------------------------------------------------------------ *
01785  * OCI_GetInterval2
01786  * ------------------------------------------------------------------------ */
01787 
01788 OCI_Interval * OCI_API OCI_GetInterval2(OCI_Resultset *rs, const mtext *name)
01789 {
01790     return OCI_GetInterval(rs, OCI_GetDefineIndex(rs, name));
01791 }
01792 
01793 /* ------------------------------------------------------------------------ *
01794  * OCI_Object
01795  * ------------------------------------------------------------------------ */
01796 
01797 OCI_Object * OCI_API OCI_GetObject(OCI_Resultset *rs, unsigned int index)
01798 {
01799     OCI_Define *def = OCI_GetDefine(rs, index);
01800     OCI_Object *obj =  NULL;
01801 
01802     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_OBJECT))
01803     {
01804         obj =  OCI_ObjectInit(rs->stmt->con,
01805                               (OCI_Object **) &def->obj,
01806                               OCI_DefineGetData(def), def->col.typinf, NULL, -1,
01807                               TRUE);
01808     }
01809 
01810     OCI_RESULT(obj != NULL);
01811 
01812     return obj;
01813 }
01814 
01815 /* ------------------------------------------------------------------------ *
01816  * OCI_GetObject2
01817  * ------------------------------------------------------------------------ */
01818 
01819 OCI_Object * OCI_API OCI_GetObject2(OCI_Resultset *rs, const mtext *name)
01820 {
01821     return OCI_GetObject(rs, OCI_GetDefineIndex(rs, name));
01822 }
01823 
01824 /* ------------------------------------------------------------------------ *
01825  * OCI_GetColl
01826  * ------------------------------------------------------------------------ */
01827 
01828 OCI_Coll * OCI_API OCI_GetColl(OCI_Resultset *rs, unsigned int index)
01829 {
01830     OCI_Define *def = OCI_GetDefine(rs, index);
01831     OCI_Coll *coll  = NULL;
01832 
01833     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_COLLECTION))
01834     {
01835             coll = OCI_CollInit(rs->stmt->con, (OCI_Coll **) &def->obj,
01836                                 OCI_DefineGetData(def), def->col.typinf);
01837     }
01838 
01839     OCI_RESULT(coll != NULL);
01840 
01841     return coll;
01842 }
01843 
01844 /* ------------------------------------------------------------------------ *
01845  * OCI_GetColl2
01846  * ------------------------------------------------------------------------ */
01847 
01848 OCI_Coll * OCI_API OCI_GetColl2(OCI_Resultset *rs, const mtext *name)
01849 {
01850     return OCI_GetColl(rs, OCI_GetDefineIndex(rs, name));
01851 }
01852 
01853 /* ------------------------------------------------------------------------ *
01854  * OCI_GetRef
01855  * ------------------------------------------------------------------------ */
01856 
01857 OCI_Ref * OCI_API OCI_GetRef(OCI_Resultset *rs, unsigned int index)
01858 {
01859     OCI_Define *def = OCI_GetDefine(rs, index);
01860     OCI_Ref    *ref = NULL;
01861 
01862     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_REF))
01863     {
01864             ref = OCI_RefInit(rs->stmt->con, def->col.typinf,
01865                               (OCI_Ref **) &def->obj, OCI_DefineGetData(def));
01866 
01867             /* if the ref object is retrieved from a register bind that has 
01868                no type info object associated, the type info object is retrieved
01869                at the first fetch call by pinning the ref and we affect the type 
01870                info object handle to the define object */
01871 
01872             if ((def->col.typinf == NULL) && (ref != NULL) && (ref->typinf != NULL))
01873             {
01874                 def->col.typinf = ref->typinf;
01875             }
01876     }
01877 
01878     OCI_RESULT(ref != NULL);
01879 
01880     return ref;
01881 }
01882 
01883 /* ------------------------------------------------------------------------ *
01884  * OCI_GetRef2
01885  * ------------------------------------------------------------------------ */
01886 
01887 OCI_Ref * OCI_API OCI_GetRef2(OCI_Resultset *rs, const mtext *name)
01888 {
01889     return OCI_GetRef(rs, OCI_GetDefineIndex(rs, name));
01890 }
01891 
01892 /* ------------------------------------------------------------------------ *
01893  * OCI_GetStatement
01894  * ------------------------------------------------------------------------ */
01895 
01896 OCI_Statement * OCI_API OCI_GetStatement(OCI_Resultset *rs, unsigned int index)
01897 {
01898     OCI_Define *def   = OCI_GetDefine(rs, index);
01899     OCI_Statement *st = NULL;
01900 
01901     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_CURSOR))
01902     {
01903         st = OCI_StatementInit(rs->stmt->con,
01904                                (OCI_Statement **) &def->obj,
01905                                (OCIStmt *) OCI_DefineGetData(def), def);
01906     }
01907 
01908     OCI_RESULT(st != NULL);
01909 
01910     return st;
01911 }
01912 
01913 /* ------------------------------------------------------------------------ *
01914  * OCI_GetStatement2
01915  * ------------------------------------------------------------------------ */
01916 
01917 OCI_Statement * OCI_API OCI_GetStatement2(OCI_Resultset *rs, const mtext *name)
01918 {
01919     return OCI_GetStatement(rs, OCI_GetDefineIndex(rs, name));
01920 }
01921 
01922 /* ------------------------------------------------------------------------ *
01923  * OCI_GetLob
01924  * ------------------------------------------------------------------------ */
01925 
01926 OCI_Lob * OCI_API OCI_GetLob(OCI_Resultset *rs, unsigned int index)
01927 {
01928     OCI_Define *def = OCI_GetDefine(rs, index);
01929     OCI_Lob * lob   = NULL;
01930 
01931     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_LOB))
01932     {
01933         lob =  OCI_LobInit(rs->stmt->con,(OCI_Lob **) &def->obj,
01934                            (OCILobLocator *) OCI_DefineGetData(def),
01935                            def->col.subtype);
01936     }
01937 
01938     OCI_RESULT(lob != NULL);
01939 
01940     return lob;
01941 }
01942 
01943 /* ------------------------------------------------------------------------ *
01944  * OCI_GetLob2
01945  * ------------------------------------------------------------------------ */
01946 
01947 OCI_Lob * OCI_API OCI_GetLob2(OCI_Resultset *rs, const mtext *name)
01948 {
01949     return OCI_GetLob(rs, OCI_GetDefineIndex(rs, name));
01950 }
01951 
01952 /* ------------------------------------------------------------------------ *
01953  * OCI_GetFile
01954  * ------------------------------------------------------------------------ */
01955 
01956 OCI_File * OCI_API OCI_GetFile(OCI_Resultset *rs, unsigned int index)
01957 {
01958     OCI_Define *def = OCI_GetDefine(rs, index);
01959     OCI_File *file  = NULL;
01960 
01961     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_FILE))
01962     {
01963         file = OCI_FileInit(rs->stmt->con,(OCI_File **) &def->obj,
01964                             (OCILobLocator *) OCI_DefineGetData(def),
01965                             def->col.subtype);
01966     }
01967 
01968     OCI_RESULT(file != NULL);
01969 
01970     return file;
01971 }
01972 
01973 /* ------------------------------------------------------------------------ *
01974  * OCI_GetFile2
01975  * ------------------------------------------------------------------------ */
01976 
01977 OCI_File * OCI_API OCI_GetFile2(OCI_Resultset *rs, const mtext *name)
01978 {
01979     return OCI_GetFile(rs, OCI_GetDefineIndex(rs, name));
01980 }
01981 
01982 /* ------------------------------------------------------------------------ *
01983  * OCI_GetLong
01984  * ------------------------------------------------------------------------ */
01985 
01986 OCI_Long * OCI_API OCI_GetLong(OCI_Resultset *rs, unsigned int index)
01987 {
01988     OCI_Define *def = OCI_GetDefine(rs, index);
01989     OCI_Long *lg    = NULL;
01990 
01991     if ((OCI_NOT_NULL(def) == TRUE) && (def->col.type == OCI_CDT_LONG))
01992     {
01993         lg = (OCI_Long *) OCI_DefineGetData(def);
01994     }
01995 
01996     OCI_RESULT(lg != NULL);
01997 
01998     return lg;
01999 }
02000 
02001 /* ------------------------------------------------------------------------ *
02002  * OCI_GetLong2
02003  * ------------------------------------------------------------------------ */
02004 
02005 OCI_Long * OCI_API OCI_GetLong2(OCI_Resultset *rs, const mtext *name)
02006 {
02007     return OCI_GetLong(rs, OCI_GetDefineIndex(rs, name));
02008 }
02009 
02010 /* ------------------------------------------------------------------------ *
02011  * OCI_IsNull
02012  * ------------------------------------------------------------------------ */
02013 
02014 boolean OCI_API OCI_IsNull(OCI_Resultset *rs, unsigned int index)
02015 {
02016     OCI_Define *def = OCI_GetDefine(rs, index);
02017 
02018     OCI_RESULT(def != NULL);
02019 
02020     return (OCI_NOT_NULL(def) == FALSE);
02021 }
02022 
02023 /* ------------------------------------------------------------------------ *
02024  * OCI_IsNull2
02025  * ------------------------------------------------------------------------ */
02026 
02027 boolean OCI_API OCI_IsNull2(OCI_Resultset *rs, const mtext *name)
02028 {
02029     return OCI_IsNull(rs, OCI_GetDefineIndex(rs, name));
02030 }
02031 
02032 /* ------------------------------------------------------------------------ *
02033  * OCI_ResultsetGetStatment
02034  * ------------------------------------------------------------------------ */
02035 
02036 OCI_Statement * OCI_API OCI_ResultsetGetStatement(OCI_Resultset *rs)
02037 {
02038     OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs, FALSE);
02039 
02040     OCI_RESULT(TRUE);
02041 
02042     return rs->stmt;
02043 }
02044 
02045 /* ------------------------------------------------------------------------ *
02046  * OCI_GetDataLength
02047  * ------------------------------------------------------------------------ */
02048 
02049 unsigned int OCI_API OCI_GetDataLength(OCI_Resultset *rs, unsigned int index)
02050 {
02051     OCI_Define *def     = OCI_GetDefine(rs, index);
02052     unsigned int length = 0;
02053     boolean res         = FALSE;
02054 
02055     if ((def != NULL) && (rs->row_cur > 0)) 
02056     {
02057         length = (unsigned int) ((ub2 *) def->buf.lens)[rs->row_cur-1];
02058         res    = TRUE;
02059     }
02060 
02061     OCI_RESULT(res);
02062 
02063     return length;
02064 }
02065 

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