C:/Users/vincent/Data/Perso/dev/ocilib/ocilib/src/collection.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: collection.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_CollInit
00043  * ------------------------------------------------------------------------ */
00044 
00045 OCI_Coll * OCI_CollInit(OCI_Connection *con, OCI_Coll **pcoll, void *handle,
00046                         OCI_TypeInfo *typinf)
00047 {
00048     OCI_Coll *coll = NULL;
00049     boolean res    = TRUE;
00050 
00051     OCI_CHECK(pcoll == NULL, NULL);
00052 
00053     if (*pcoll == NULL)
00054         *pcoll = (OCI_Coll *) OCI_MemAlloc(OCI_IPC_COLLECTION, sizeof(*coll), 1, TRUE);
00055 
00056     if (*pcoll != NULL)
00057     {
00058         coll = *pcoll;
00059 
00060         coll->con    = con;
00061         coll->handle = handle;
00062         coll->typinf = typinf;
00063 
00064         if (coll->handle == NULL)
00065         {
00066             /* allocates handle for non fetched collection */
00067 
00068             coll->hstate = OCI_OBJECT_ALLOCATED;
00069 
00070             OCI_CALL2
00071             (
00072                 res, con,
00073 
00074                 OCI_ObjectNew(OCILib.env, con->err, con->cxt, typinf->ccode,
00075                               typinf->tdo, (void *) NULL, OCI_DURATION_SESSION,
00076                               TRUE, (dvoid **) &coll->handle)
00077             )
00078         }
00079         else
00080             coll->hstate = OCI_OBJECT_FETCHED_CLEAN;
00081     }
00082     else
00083         res = FALSE;
00084 
00085     /* check for failure */
00086 
00087     if (res == FALSE)
00088     {
00089         OCI_CollFree(coll);
00090         coll = NULL;
00091     }
00092 
00093     return coll;
00094 }
00095 
00096 /* ************************************************************************ *
00097  *                             PUBLIC FUNCTIONS
00098  * ************************************************************************ */
00099 
00100 /* ------------------------------------------------------------------------ *
00101  * OCI_CollCreate
00102  * ------------------------------------------------------------------------ */
00103 
00104 OCI_Coll * OCI_API OCI_CollCreate(OCI_TypeInfo *typinf)
00105 {
00106     OCI_Coll *coll = NULL;
00107 
00108     OCI_CHECK_INITIALIZED(NULL);
00109 
00110     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00111     OCI_CHECK(typinf->ccode == OCI_UNKNOWN, NULL)
00112 
00113     coll = OCI_CollInit(typinf->con, &coll, (OCIColl *) NULL, typinf);
00114 
00115     OCI_RESULT(coll != NULL);
00116 
00117     return coll;
00118 }
00119 
00120 /* ------------------------------------------------------------------------ *
00121  * OCI_CollFree
00122  * ------------------------------------------------------------------------ */
00123 
00124 boolean OCI_API OCI_CollFree(OCI_Coll *coll)
00125 {
00126     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE);
00127     OCI_CHECK_OBJECT_FETCHED(coll, FALSE);
00128 
00129     /* free data element accessor */
00130 
00131     if (coll->elem != NULL)
00132     {
00133         coll->elem->hstate = OCI_OBJECT_FETCHED_DIRTY;
00134         OCI_ElemFree(coll->elem);
00135         coll->elem = NULL;
00136     }
00137 
00138     /* create collection for local object */
00139 
00140     if (coll->hstate == OCI_OBJECT_ALLOCATED)
00141     {
00142         OCI_OCIObjectFree(OCILib.env, coll->typinf->con->err,
00143                           coll->handle, OCI_OBJECTFREE_NONULL);
00144     }
00145 
00146     OCI_FREE(coll);
00147 
00148     OCI_RESULT(TRUE);
00149 
00150     return TRUE;
00151 }
00152 
00153 /* ------------------------------------------------------------------------ *
00154  * OCI_CollAssign
00155  * ------------------------------------------------------------------------ */
00156 
00157 boolean OCI_API OCI_CollAssign(OCI_Coll *coll, OCI_Coll *coll_src)
00158 {
00159     boolean res = TRUE;
00160 
00161     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll,     FALSE);
00162     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll_src, FALSE);
00163 
00164     OCI_CHECK_COMPAT(coll->con,
00165                      coll->typinf->cols[0].icode == coll_src->typinf->cols[0].icode,
00166                      FALSE);
00167 
00168     OCI_CALL2
00169     (
00170         res, coll->con,
00171 
00172         OCICollAssign(OCILib.env, coll->con->err, coll_src->handle, coll->handle)
00173     )
00174 
00175     OCI_RESULT(res);
00176 
00177     return res;
00178 }
00179 
00180 /* ------------------------------------------------------------------------ *
00181  * OCI_CollGetType
00182  * ------------------------------------------------------------------------ */
00183 
00184 unsigned int OCI_API OCI_CollGetType(OCI_Coll *coll)
00185 {
00186     unsigned int type = OCI_UNKNOWN;
00187 
00188     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, OCI_UNKNOWN);
00189 
00190     if (coll->typinf->ccode == OCI_TYPECODE_TABLE)
00191         type = OCI_COLL_NESTED_TABLE;
00192     else if(coll->typinf->ccode == OCI_TYPECODE_VARRAY)
00193         type = OCI_COLL_VARRAY;
00194 
00195     OCI_RESULT(TRUE);
00196 
00197     return type;
00198 }
00199 
00200 /* ------------------------------------------------------------------------ *
00201  * OCI_CollGetCount
00202  * ------------------------------------------------------------------------ */
00203 
00204 unsigned int OCI_API OCI_CollGetMax(OCI_Coll *coll)
00205 {
00206     int max = 0;
00207 
00208     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, 0);
00209 
00210     max = OCICollMax(OCILib.env, coll->handle);
00211 
00212     OCI_RESULT(TRUE);
00213 
00214     return (unsigned int) max;
00215 }
00216 
00217 /* ------------------------------------------------------------------------ *
00218  * OCI_CollGetSize
00219  * ------------------------------------------------------------------------ */
00220 
00221 unsigned int OCI_API OCI_CollGetSize(OCI_Coll *coll)
00222 {
00223     boolean res = TRUE;
00224     sb4 size    = 0;
00225 
00226     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, 0);
00227 
00228     OCI_CALL2
00229     (
00230         res, coll->con,
00231 
00232         OCICollSize(OCILib.env, coll->con->err, coll->handle, &size)
00233     )
00234 
00235     OCI_RESULT(res);
00236 
00237     return (unsigned int) size;
00238 }
00239 
00240 /* ------------------------------------------------------------------------ *
00241  * OCI_CollTrim
00242  * ------------------------------------------------------------------------ */
00243 
00244 boolean OCI_API OCI_CollTrim(OCI_Coll *coll, unsigned int nb_elem)
00245 {
00246     boolean res      = TRUE;
00247     unsigned int size = 0;
00248 
00249     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE);
00250 
00251     size = OCI_CollGetSize(coll);
00252 
00253     OCI_CHECK_BOUND(coll->con, (sb4) nb_elem, (sb4) 0, (sb4) size, FALSE);
00254 
00255     OCI_CALL2
00256     (
00257         res, coll->con,
00258 
00259         OCICollTrim(OCILib.env, coll->con->err, (sb4) nb_elem, coll->handle)
00260     )
00261 
00262     OCI_RESULT(res);
00263 
00264     return res;
00265 }
00266 
00267 /* ------------------------------------------------------------------------ *
00268  * OCI_CollGetAt
00269  * ------------------------------------------------------------------------ */
00270 
00271 OCI_Elem * OCI_API OCI_CollGetAt(OCI_Coll *coll, unsigned int index)
00272 {
00273     boolean res    = TRUE;
00274     boolean exists = FALSE;
00275     void *data     = NULL;
00276     OCIInd *p_ind  = NULL;
00277     OCI_Elem *elem = NULL;
00278 
00279     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, NULL);
00280 
00281     OCI_CALL2
00282     (
00283         res, coll->con,
00284 
00285         OCICollGetElem(OCILib.env, coll->con->err, coll->handle, (sb4) index-1,
00286                        &exists, &data, (dvoid **) (dvoid *) &p_ind)
00287     )
00288 
00289     if (res == TRUE && exists == TRUE && data != NULL)
00290     {
00291         elem = coll->elem = OCI_ElemInit(coll->con, &coll->elem,
00292                                          data, p_ind, coll->typinf);
00293     }
00294 
00295     OCI_RESULT(res);
00296 
00297     return elem;
00298 }
00299 
00300 /* ------------------------------------------------------------------------ *
00301  * OCI_CollSetAt
00302  * ------------------------------------------------------------------------ */
00303 
00304 boolean OCI_API OCI_CollSetAt(OCI_Coll *coll, unsigned int index, OCI_Elem *elem)
00305 {
00306     boolean res = TRUE;
00307 
00308     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE);
00309     OCI_CHECK_PTR(OCI_IPC_ELEMENT, elem, FALSE);
00310 
00311     OCI_CHECK_COMPAT(coll->con, elem->typinf->cols[0].type == coll->typinf->cols[0].type, FALSE);
00312 
00313     OCI_CALL2
00314     (
00315         res, coll->con,
00316 
00317         OCICollAssignElem(OCILib.env, coll->con->err, (sb4) index-1, elem->handle,
00318                           elem->pind,coll->handle)
00319     )
00320 
00321     OCI_RESULT(res);
00322 
00323     return res;
00324 }
00325 
00326 /* ------------------------------------------------------------------------ *
00327  * OCI_CollAppend
00328  * ------------------------------------------------------------------------ */
00329 
00330 boolean OCI_API OCI_CollAppend(OCI_Coll *coll, OCI_Elem *elem)
00331 {
00332     boolean res = TRUE;
00333 
00334     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE);
00335     OCI_CHECK_PTR(OCI_IPC_ELEMENT, elem, FALSE);
00336 
00337     OCI_CHECK_COMPAT(coll->con, elem->typinf->cols[0].type == coll->typinf->cols[0].type, FALSE);
00338 
00339     OCI_CALL2
00340     (
00341         res, coll->con,
00342 
00343         OCICollAppend(OCILib.env, coll->con->err, elem->handle, elem->pind,
00344                       coll->handle)
00345     )
00346 
00347     OCI_RESULT(res);
00348 
00349     return res;
00350 }
00351 
00352 /* ------------------------------------------------------------------------ *
00353  * OCI_CollGetTypeInfo
00354  * ------------------------------------------------------------------------ */
00355 
00356 OCI_TypeInfo * OCI_API OCI_CollGetTypeInfo(OCI_Coll *coll)
00357 {
00358     OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, NULL);
00359 
00360     OCI_RESULT(TRUE);
00361 
00362     return coll->typinf;
00363 }
00364 
00365 /* ------------------------------------------------------------------------ *
00366  * OCI_CollTrim
00367  * ------------------------------------------------------------------------ */
00368 
00369 boolean OCI_API OCI_CollClear(OCI_Coll *coll)
00370 {
00371     boolean res = TRUE;
00372 
00373     unsigned int size = OCI_CollGetSize(coll);
00374 
00375     if (size > 0)
00376     {
00377         res = OCI_CollTrim(coll, size);
00378     }
00379 
00380     OCI_RESULT(res);
00381 
00382     return res;
00383 }
00384 

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