C:/Users/vincent/Data/Perso/dev/ocilib/ocilib/src/callback.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: callback.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_ProcInBind
00043  * ------------------------------------------------------------------------ */
00044 
00045 sb4 OCI_ProcInBind(dvoid *ictxp, OCIBind *bindp, ub4 iter, ub4 index,
00046                    dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indp)
00047 {
00048     OCI_Bind * bnd = (OCI_Bind *) ictxp;
00049     sb2 *ind       = (sb2 *) bnd->buf.inds;
00050     ub4 i          = 0;
00051 
00052     /* those checks may be not necessary but they keep away compilers warning
00053        away if the warning level is set to maximum !
00054     */
00055 
00056     OCI_NOT_USED(index);
00057     OCI_NOT_USED(bindp);
00058 
00059     /* check objects and bounds */
00060 
00061     OCI_CHECK(bnd  == NULL, OCI_ERROR);
00062     OCI_CHECK(iter >= bnd->buf.count, OCI_ERROR);
00063 
00064     /* indicators must be set to -1 depending on datatype,
00065        so let's do it for all */
00066 
00067     for (i = 0; i < bnd->buf.count; i++, ind++)
00068         *ind = -1;
00069 
00070     /* setup bind index because OCI_RegisterXXX() might not have been called
00071        in the same order than the variables in the returning clause */
00072 
00073     if (iter == 0)
00074         bnd->dynpos = bnd->stmt->dynidx++;
00075 
00076     /* we do not need to do anything here except setting indicators */
00077 
00078     *bufpp  = (dvoid *) 0;
00079     *alenp  = (ub4    ) 0;
00080     *indp   = (dvoid *) bnd->buf.inds;
00081     *piecep = (ub1    ) OCI_ONE_PIECE;
00082 
00083     return OCI_CONTINUE;
00084 }
00085 
00086 /* ------------------------------------------------------------------------ *
00087  * OCI_GetDefine
00088  * ------------------------------------------------------------------------ */
00089 
00090 sb4 OCI_ProcOutBind(dvoid *octxp, OCIBind *bindp, ub4 iter, ub4 index,
00091                     dvoid **bufpp, ub4 **alenp, ub1 *piecep, dvoid **indp,
00092                     ub2 **rcodep)
00093 {
00094     OCI_Bind * bnd    = (OCI_Bind *) octxp;
00095     OCI_Define *def   = NULL;
00096     OCI_Resultset *rs = NULL;
00097     boolean res       = TRUE;
00098     ub4 rows          = 0;
00099 
00100     /* those checks may be not necessary but they keep away compilers warning
00101        away if the warning level is set to maximum !
00102     */
00103 
00104     OCI_NOT_USED(bindp);
00105 
00106     /* check objects and bounds */
00107 
00108     OCI_CHECK(bnd  == NULL, OCI_ERROR);
00109     OCI_CHECK(iter >= bnd->buf.count, OCI_ERROR);
00110 
00111     /* update statmement status */
00112 
00113     bnd->stmt->status = OCI_STMT_EXECUTED;
00114 
00115     /* create resultset on the first row processed for each iteration */
00116 
00117     if (index == 0)
00118     {
00119         bnd->stmt->nb_rs   = bnd->stmt->nb_iters;
00120         bnd->stmt->cur_rs  = 0;
00121 
00122         /* allocate resultset handles array */
00123 
00124         if (bnd->stmt->rsts == NULL)
00125         {
00126             bnd->stmt->rsts = (OCI_Resultset **) OCI_MemAlloc(OCI_IPC_RESULTSET_ARRAY, 
00127                                                               sizeof(*bnd->stmt->rsts),
00128                                                               bnd->stmt->nb_rs, TRUE);
00129  
00130             if (bnd->stmt->rsts == NULL)
00131                 res = FALSE;
00132         }
00133         
00134         /* create resultset as needed */
00135 
00136         if (bnd->stmt->rsts[iter] == NULL)
00137         {
00138             OCI_CALL1
00139             (   
00140                 res, bnd->stmt->con, bnd->stmt,
00141                 
00142                 OCIAttrGet(bnd->buf.handle, (ub4) OCI_HTYPE_BIND, (void *) &rows, 
00143                            (ub4 *) NULL, (ub4) OCI_ATTR_ROWS_RETURNED,
00144                            bnd->stmt->con->err)
00145             )
00146 
00147             if (res == TRUE)
00148             {
00149                 bnd->stmt->rsts[iter] = OCI_ResultsetCreate(bnd->stmt, rows);
00150 
00151                 if (bnd->stmt->rsts[iter] != NULL)
00152                     bnd->stmt->rsts[iter]->row_count = rows;
00153             }
00154         }
00155     }
00156 
00157     OCI_CHECK(bnd->stmt->rsts == NULL, OCI_ERROR);
00158     
00159     rs = bnd->stmt->rsts[iter];
00160 
00161     OCI_CHECK(rs == NULL, OCI_ERROR);
00162  
00163     /* ok.. let's Oracle update its buffers */
00164 
00165     if (res == TRUE)
00166     {
00167         /* update pointers contents */
00168 
00169         def = &rs->defs[bnd->dynpos];
00170 
00171         switch (def->col.type)
00172         {
00173 
00174             case OCI_CDT_CURSOR:
00175             case OCI_CDT_TIMESTAMP:
00176             case OCI_CDT_INTERVAL:
00177             case OCI_CDT_LOB:
00178             case OCI_CDT_FILE:
00179 
00180                 *bufpp = def->buf.data[index];
00181                 break;
00182 
00183             default:
00184 
00185                 *bufpp = (((ub1*)def->buf.data) + (def->col.bufsize * index));
00186         }
00187 
00188         *alenp  = (ub4   *) (((ub1 *) def->buf.lens) + (def->buf.sizelen * index));
00189         *indp   = (dvoid *) (((ub1 *) def->buf.inds) + (sizeof(sb2) * index));
00190         *piecep = (ub1    ) OCI_ONE_PIECE;
00191         *rcodep = (ub2   *) NULL;                
00192     }
00193 
00194     return ((res == TRUE) ? OCI_CONTINUE : OCI_ERROR);
00195 }

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