C:/Users/vincent/Data/Perso/dev/ocilib/ocilib/src/ref.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: ref.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_RefInit
00043  * ------------------------------------------------------------------------ */
00044 
00045 OCI_Ref * OCI_RefInit(OCI_Connection *con, OCI_TypeInfo *typinf, OCI_Ref **pref, 
00046                       void *handle)
00047 {
00048     boolean res   = TRUE;
00049     OCI_Ref * ref = NULL;
00050     
00051     OCI_CHECK(pref == NULL, NULL);
00052 
00053     if (*pref == NULL)
00054         *pref = (OCI_Ref *) OCI_MemAlloc(OCI_IPC_REF, sizeof(*ref), 1, TRUE);
00055 
00056     if (*pref != NULL)
00057     {
00058         ref = *pref;
00059 
00060         ref->handle = handle;
00061         ref->con    = con;
00062         ref->typinf = typinf;
00063 
00064         if (ref->handle == NULL)
00065         {
00066             /* allocates handle for non fetched object */
00067 
00068             ref->hstate = OCI_OBJECT_ALLOCATED;
00069 
00070             OCI_CALL2
00071             (
00072                 res, ref->con, 
00073                 
00074                 OCI_ObjectNew(OCILib.env,  con->err, con->cxt, 
00075                               (OCITypeCode) SQLT_REF, 
00076                               (OCIType*) NULL,
00077                               (dvoid *) NULL, 
00078                               (OCIDuration) OCI_DURATION_SESSION,
00079                               (boolean) FALSE, 
00080                               (dvoid **) &ref->handle)
00081            )
00082         }
00083         else
00084         {
00085             ref->hstate = OCI_OBJECT_FETCHED_CLEAN;
00086             
00087             OCI_RefUnpin(ref);
00088         }
00089     }
00090     else
00091         res = FALSE;
00092 
00093     /* check for failure */
00094 
00095     if (res == FALSE)
00096     {
00097         OCI_RefFree(ref);
00098         ref = NULL;
00099     }
00100 
00101     return ref;
00102 }
00103 
00104 /* ------------------------------------------------------------------------ *
00105  * OCI_RefPin
00106  * ------------------------------------------------------------------------ */
00107 
00108 boolean OCI_RefPin(OCI_Ref *ref)
00109 {
00110     boolean res      = TRUE;
00111     void *obj_handle = NULL;
00112 
00113     OCI_CHECK(ref == NULL, FALSE);
00114 
00115     OCI_RefUnpin(ref);
00116 
00117     OCI_CALL2
00118     (
00119         res, ref->con, 
00120         
00121         OCIObjectPin(OCILib.env, ref->con->err, ref->handle,
00122                      (OCIComplexObject *) 0, OCI_PIN_ANY, OCI_DURATION_SESSION,
00123                      OCI_LOCK_NONE, &obj_handle)
00124     )
00125 
00126     if (res == TRUE)
00127     {
00128         OCI_Object *obj = NULL;
00129 
00130         if (res == TRUE)
00131         {
00132             obj =  OCI_ObjectInit(ref->con, (OCI_Object **) &ref->obj,
00133                                   obj_handle, ref->typinf, NULL, -1, TRUE);
00134         }
00135 
00136         if (obj != NULL)
00137             ref->pinned = TRUE;
00138         else
00139             res = FALSE;
00140     }
00141 
00142     return res;
00143 }
00144 
00145 /* ------------------------------------------------------------------------ *
00146  * OCI_RefUnpin
00147  * ------------------------------------------------------------------------ */
00148 
00149 boolean OCI_RefUnpin(OCI_Ref *ref)
00150 {
00151     boolean res = TRUE;
00152 
00153     OCI_CHECK(ref == NULL, FALSE);
00154 
00155     if (ref->pinned == TRUE)
00156     {
00157         OCI_CALL2
00158         (
00159             res, ref->con, 
00160             
00161             OCIObjectUnpin(OCILib.env, ref->con->err, ref->obj->handle)
00162         )
00163 
00164         ref->pinned = FALSE;
00165     }
00166 
00167     if (ref->obj != NULL)
00168     {
00169         ref->obj->hstate = OCI_OBJECT_FETCHED_DIRTY;
00170         OCI_ObjectFree(ref->obj);
00171         ref->obj = NULL;
00172     }
00173 
00174     return res;           
00175 }
00176 
00177 /* ************************************************************************ *
00178  *                            PUBLIC FUNCTIONS
00179  * ************************************************************************ */
00180 
00181 /* ------------------------------------------------------------------------ *
00182  * OCI_RefCreate
00183  * ------------------------------------------------------------------------ */
00184 
00185 OCI_Ref * OCI_API OCI_RefCreate(OCI_Connection *con, OCI_TypeInfo *typinf)
00186 {
00187     OCI_Ref *ref = NULL;
00188     
00189     OCI_CHECK_INITIALIZED(NULL);
00190 
00191     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00192     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00193 
00194     ref = OCI_RefInit(con, typinf, &ref, NULL);
00195 
00196     OCI_RESULT(ref != NULL);
00197 
00198     return ref;
00199 }
00200 
00201 /* ------------------------------------------------------------------------ *
00202  * OCI_RefFree
00203  * ------------------------------------------------------------------------ */
00204 
00205 boolean OCI_API OCI_RefFree(OCI_Ref *ref)
00206 {
00207     OCI_CHECK_PTR(OCI_IPC_REF, ref, FALSE);
00208 
00209     OCI_CHECK_OBJECT_FETCHED(ref, FALSE);
00210 
00211     OCI_RefUnpin(ref);
00212 
00213     if (ref->hstate == OCI_OBJECT_ALLOCATED)
00214     {
00215         OCI_OCIObjectFree(OCILib.env, ref->con->err,  ref->handle, 
00216                           OCI_OBJECTFREE_NONULL);
00217     }
00218 
00219     OCI_FREE(ref);
00220 
00221     OCI_RESULT(TRUE);
00222 
00223     return TRUE;
00224 }
00225 
00226 /* ------------------------------------------------------------------------ *
00227  * OCI_RefGetObject
00228  * ------------------------------------------------------------------------ */
00229 
00230 OCI_Object * OCI_API OCI_RefGetObject(OCI_Ref *ref)
00231 {
00232     OCI_Object *obj = NULL;
00233 
00234     if (OCI_RefIsNull(ref) == FALSE)
00235     {
00236         boolean res = TRUE;
00237 
00238         res = OCI_RefPin(ref);
00239 
00240         OCI_RESULT(res);
00241     
00242         obj = ref->obj;
00243     }
00244 
00245         return obj;
00246 }
00247 
00248 /* ------------------------------------------------------------------------ *
00249  * OCI_RefAssign
00250  * ------------------------------------------------------------------------ */
00251 
00252 boolean OCI_API OCI_RefAssign(OCI_Ref *ref, OCI_Ref *ref_src)
00253 {
00254     boolean res = TRUE;
00255 
00256     OCI_CHECK_PTR(OCI_IPC_REF, ref,     FALSE);
00257     OCI_CHECK_PTR(OCI_IPC_REF, ref_src, FALSE);
00258 
00259     OCI_CHECK_COMPAT(ref->con, ref->typinf == ref_src->typinf, FALSE);
00260 
00261     OCI_CALL2
00262     (
00263         res, ref->con, 
00264 
00265         OCIRefAssign(OCILib.env, ref->con->err, ref_src->handle, &ref->handle)
00266     )
00267 
00268     if (res == TRUE)
00269     {
00270         if (ref->obj != NULL)
00271         {
00272             OCI_ObjectFree(ref->obj);
00273             ref->obj = NULL;
00274         }
00275 
00276         ref->typinf = ref_src->typinf;
00277         ref->pinned = ref_src->pinned;
00278 
00279     }
00280 
00281 
00282     OCI_RESULT(res);
00283 
00284     return res;
00285 }
00286 
00287 /* ------------------------------------------------------------------------ *
00288  * OCI_RefIsNull
00289  * ------------------------------------------------------------------------ */
00290 
00291 boolean OCI_API OCI_RefIsNull(OCI_Ref *ref)
00292 {
00293     OCI_CHECK_PTR(OCI_IPC_REF, ref, TRUE);
00294 
00295     OCI_RESULT(TRUE);
00296 
00297     return OCIRefIsNull(OCILib.env, ref->handle);
00298 }
00299 
00300 /* ------------------------------------------------------------------------ *
00301  * OCI_RefSetNull
00302  * ------------------------------------------------------------------------ */
00303 
00304 boolean OCI_API OCI_RefSetNull(OCI_Ref *ref)
00305 {
00306     boolean res = TRUE;
00307 
00308     OCI_CHECK_PTR(OCI_IPC_REF, ref, FALSE);
00309 
00310     res = OCI_RefUnpin(ref);
00311 
00312     if (res == TRUE)
00313     {
00314         OCIRefClear(OCILib.env, ref->handle);
00315 
00316         if (ref->obj != NULL)
00317         {
00318             OCI_ObjectFree(ref->obj);
00319             ref->obj = NULL;
00320         }
00321     }
00322 
00323     OCI_RESULT(res);
00324    
00325     return res;
00326 }
00327 
00328 /* ------------------------------------------------------------------------ *
00329  * OCI_RefToText
00330  * ------------------------------------------------------------------------ */
00331 
00332 boolean OCI_API OCI_RefToText(OCI_Ref *ref, int size, mtext *str)
00333 {
00334     boolean res = TRUE;
00335     void *ostr  = NULL;
00336     int osize   = size * sizeof(mtext);
00337 
00338     OCI_CHECK_PTR(OCI_IPC_REF, ref, FALSE);
00339     OCI_CHECK_PTR(OCI_IPC_STRING, str, FALSE);
00340  
00341     /* init output buffer in case of OCI failure */
00342     
00343     str[0] = 0;
00344 
00345     ostr = OCI_GetInputMetaString(str, &osize);
00346  
00347     OCI_CALL2
00348     (
00349         res, ref->con,
00350         
00351         OCIRefToHex((dvoid *) OCILib.env, ref->con->err, ref->handle, 
00352                     (OraText *) ostr, (ub4 *) &osize)
00353     )
00354  
00355     OCI_GetOutputMetaString(ostr, str, &osize);
00356     OCI_ReleaseMetaString(ostr);
00357 
00358     /* set null string terminator */
00359 
00360     str[osize/sizeof(mtext)] = 0;
00361 
00362     OCI_RESULT(res);
00363    
00364     return res;
00365 }
00366 
00367 /* ------------------------------------------------------------------------ *
00368  * OCI_RefGetHexSize
00369  * ------------------------------------------------------------------------ */
00370 
00371 unsigned int OCI_API OCI_RefGetHexSize(OCI_Ref *ref)
00372 {
00373     ub4 size = 0;
00374 
00375     OCI_CHECK_PTR(OCI_IPC_REF, ref, 0);
00376 
00377     size = OCIRefHexSize(OCILib.env, (const OCIRef *) ref->handle);
00378 
00379     size /= sizeof(mtext);
00380 
00381     OCI_RESULT(TRUE);
00382 
00383     return (unsigned int) size;
00384 }
00385 
00386 /* ------------------------------------------------------------------------ *
00387  * OCI_CollRefGetTypeInfo
00388  * ------------------------------------------------------------------------ */
00389 
00390 OCI_TypeInfo * OCI_API OCI_RefGetTypeInfo(OCI_Ref *ref)
00391 {
00392     OCI_CHECK_PTR(OCI_IPC_REF, ref, NULL);
00393 
00394     OCI_RESULT(TRUE);
00395 
00396     return ref->typinf;
00397 }
00398 
00399 

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