OCILIB (C Driver for Oracle) 3.9.2
D:/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     |                              Website : http://www.ocilib.net                            |
00009     |                                                                                         |
00010     |             Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net>            |
00011     |                                                                                         |
00012     +-----------------------------------------------------------------------------------------+
00013     |                                                                                         |
00014     |             This library is free software; you can redistribute it and/or               |
00015     |             modify it under the terms of the GNU Lesser General Public                  |
00016     |             License as published by the Free Software Foundation; either                |
00017     |             version 2 of the License, or (at your option) any later version.            |
00018     |                                                                                         |
00019     |             This library is distributed in the hope that it will be useful,             |
00020     |             but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00021     |             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           |
00022     |             Lesser General Public License for more details.                             |
00023     |                                                                                         |
00024     |             You should have received a copy of the GNU Lesser General Public            |
00025     |             License along with this library; if not, write to the Free                  |
00026     |             Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          |
00027     |                                                                                         |
00028     +-----------------------------------------------------------------------------------------+
00029 */
00030 
00031 /* --------------------------------------------------------------------------------------------- *
00032  * $Id: ref.c, v 3.9.2 2011-07-13 00:00 Vincent Rogier $
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
00046 (
00047     OCI_Connection *con,
00048     OCI_TypeInfo   *typinf,
00049     OCI_Ref       **pref,
00050     void           *handle
00051 )
00052 {
00053     boolean res   = TRUE;
00054     OCI_Ref * ref = NULL;
00055 
00056     OCI_CHECK(pref == NULL, NULL);
00057 
00058     if (*pref == NULL)
00059     {
00060         *pref = (OCI_Ref *) OCI_MemAlloc(OCI_IPC_REF, sizeof(*ref), (size_t) 1, TRUE);
00061     }
00062 
00063     if (*pref != NULL)
00064     {
00065         ref = *pref;
00066 
00067         ref->handle = handle;
00068         ref->con    = con;
00069         ref->typinf = typinf;
00070 
00071         if ((ref->handle == NULL) || (ref->hstate == OCI_OBJECT_ALLOCATED_ARRAY))
00072         {
00073             /* allocates handle for non fetched object */
00074 
00075             if (ref->hstate != OCI_OBJECT_ALLOCATED_ARRAY)
00076             {
00077                 ref->hstate = OCI_OBJECT_ALLOCATED;
00078             }
00079 
00080             OCI_CALL2
00081             (
00082                 res, ref->con,
00083 
00084                 OCI_ObjectNew(ref->con->env, ref->con->err, ref->con->cxt,
00085                               (OCITypeCode) SQLT_REF,
00086                               (OCIType*) NULL,
00087                               (dvoid *) NULL,
00088                               (OCIDuration) OCI_DURATION_SESSION,
00089                               (boolean) FALSE,
00090                               (dvoid **) &ref->handle)
00091             )
00092         }
00093         else
00094         {
00095             ref->hstate = OCI_OBJECT_FETCHED_CLEAN;
00096 
00097             OCI_RefUnpin(ref);
00098         }
00099     }
00100     else
00101     {
00102         res = FALSE;
00103     }
00104 
00105     /* check for failure */
00106 
00107     if (res == FALSE)
00108     {
00109         OCI_RefFree(ref);
00110         ref = NULL;
00111     }
00112 
00113     return ref;
00114 }
00115 
00116 /* --------------------------------------------------------------------------------------------- *
00117  * OCI_RefPin
00118  * --------------------------------------------------------------------------------------------- */
00119 
00120 boolean OCI_RefPin
00121 (
00122     OCI_Ref *ref
00123 )
00124 {
00125     boolean res      = TRUE;
00126     void *obj_handle = NULL;
00127 
00128     OCI_CHECK(ref == NULL, FALSE);
00129 
00130     OCI_RefUnpin(ref);
00131 
00132     OCI_CALL2
00133     (
00134         res, ref->con,
00135 
00136         OCIObjectPin(ref->con->env, ref->con->err, ref->handle,
00137                      (OCIComplexObject *) 0, OCI_PIN_ANY, OCI_DURATION_SESSION,
00138                      OCI_LOCK_NONE, &obj_handle)
00139     )
00140 
00141     if (res == TRUE)
00142     {
00143         OCI_Object *obj = NULL;
00144 
00145         if (res == TRUE)
00146         {
00147             obj =  OCI_ObjectInit(ref->con, (OCI_Object **) &ref->obj, obj_handle,
00148                                   ref->typinf, NULL, -1, TRUE);
00149         }
00150 
00151         if (obj != NULL)
00152         {
00153             ref->pinned = TRUE;
00154         }
00155         else
00156         {
00157             res = FALSE;
00158         }
00159     }
00160 
00161     return res;
00162 }
00163 
00164 /* --------------------------------------------------------------------------------------------- *
00165  * OCI_RefUnpin
00166  * --------------------------------------------------------------------------------------------- */
00167 
00168 boolean OCI_RefUnpin
00169 (
00170     OCI_Ref *ref
00171 )
00172 {
00173     boolean res = TRUE;
00174 
00175     OCI_CHECK(ref == NULL, FALSE);
00176 
00177     if (ref->pinned == TRUE)
00178     {
00179         OCI_CALL2
00180         (
00181             res, ref->con,
00182 
00183             OCIObjectUnpin(ref->con->env, ref->con->err, ref->obj->handle)
00184         )
00185 
00186         ref->pinned = FALSE;
00187     }
00188 
00189     if (ref->obj != NULL)
00190     {
00191         ref->obj->hstate = OCI_OBJECT_FETCHED_DIRTY;
00192         OCI_ObjectFree(ref->obj);
00193         ref->obj = NULL;
00194     }
00195 
00196     return res;
00197 }
00198 
00199 /* ********************************************************************************************* *
00200  *                            PUBLIC FUNCTIONS
00201  * ********************************************************************************************* */
00202 
00203 /* --------------------------------------------------------------------------------------------- *
00204  * OCI_RefCreate
00205  * --------------------------------------------------------------------------------------------- */
00206 
00207 OCI_Ref * OCI_API OCI_RefCreate
00208 (
00209     OCI_Connection *con,
00210     OCI_TypeInfo   *typinf
00211 )
00212 {
00213     OCI_Ref *ref = NULL;
00214 
00215     OCI_CHECK_INITIALIZED(NULL);
00216 
00217     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00218     OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL);
00219 
00220     ref = OCI_RefInit(con, typinf, &ref, NULL);
00221 
00222     OCI_RESULT(ref != NULL);
00223 
00224     return ref;
00225 }
00226 
00227 /* --------------------------------------------------------------------------------------------- *
00228  * OCI_RefFree
00229  * --------------------------------------------------------------------------------------------- */
00230 
00231 boolean OCI_API OCI_RefFree
00232 (
00233     OCI_Ref *ref
00234 )
00235 {
00236     OCI_CHECK_PTR(OCI_IPC_REF, ref, FALSE);
00237 
00238     OCI_CHECK_OBJECT_FETCHED(ref, FALSE);
00239 
00240     OCI_RefUnpin(ref);
00241 
00242     if ((ref->hstate == OCI_OBJECT_ALLOCATED) || (ref->hstate == OCI_OBJECT_ALLOCATED_ARRAY))
00243     {
00244         OCI_OCIObjectFree(ref->con->env, ref->con->err,  ref->handle, OCI_OBJECTFREE_NONULL);
00245     }
00246 
00247     if (ref->hstate != OCI_OBJECT_ALLOCATED_ARRAY)
00248     {
00249         OCI_FREE(ref);
00250     }
00251 
00252     OCI_RESULT(TRUE);
00253 
00254     return TRUE;
00255 }
00256 
00257 /* --------------------------------------------------------------------------------------------- *
00258  * OCI_RefArrayCreate
00259  * --------------------------------------------------------------------------------------------- */
00260 
00261 OCI_Ref ** OCI_API OCI_RefArrayCreate
00262 (
00263     OCI_Connection *con,
00264     OCI_TypeInfo   *typinf,
00265     unsigned int    nbelem
00266 )
00267 {
00268     OCI_Array *arr = NULL;
00269     OCI_Ref **refs = NULL;
00270 
00271     arr = OCI_ArrayCreate(con, nbelem, OCI_CDT_REF, 0, sizeof(OCIRef *), sizeof(OCI_Ref), 0, typinf);
00272 
00273     if (arr != NULL)
00274     {
00275         refs = (OCI_Ref **) arr->tab_obj;
00276     }
00277 
00278     return refs;
00279 }
00280 
00281 /* --------------------------------------------------------------------------------------------- *
00282  * OCI_RefArrayFree
00283  * --------------------------------------------------------------------------------------------- */
00284 
00285 boolean OCI_API OCI_RefArrayFree
00286 (
00287     OCI_Ref **refs
00288 )
00289 {
00290     return OCI_ArrayFreeFromHandles((void **) refs);
00291 }
00292 
00293 /* --------------------------------------------------------------------------------------------- *
00294  * OCI_RefGetObject
00295  * --------------------------------------------------------------------------------------------- */
00296 
00297 OCI_Object * OCI_API OCI_RefGetObject
00298 (
00299     OCI_Ref *ref
00300 )
00301 {
00302     OCI_Object *obj = NULL;
00303 
00304     if (OCI_RefIsNull(ref) == FALSE)
00305     {
00306         boolean res = TRUE;
00307 
00308         res = OCI_RefPin(ref);
00309 
00310         OCI_RESULT(res);
00311 
00312         obj = ref->obj;
00313     }
00314 
00315     return obj;
00316 }
00317 
00318 /* --------------------------------------------------------------------------------------------- *
00319  * OCI_RefAssign
00320  * --------------------------------------------------------------------------------------------- */
00321 
00322 boolean OCI_API OCI_RefAssign
00323 (
00324     OCI_Ref *ref,
00325     OCI_Ref *ref_src
00326 )
00327 {
00328     boolean res = TRUE;
00329 
00330     OCI_CHECK_PTR(OCI_IPC_REF, ref,     FALSE);
00331     OCI_CHECK_PTR(OCI_IPC_REF, ref_src, FALSE);
00332 
00333     OCI_CHECK_COMPAT(ref->con, ref->typinf->tdo == ref_src->typinf->tdo, FALSE);
00334 
00335     OCI_CALL2
00336     (
00337         res, ref->con,
00338 
00339         OCIRefAssign(ref->con->env, ref->con->err, ref_src->handle, &ref->handle)
00340     )
00341 
00342     if (res == TRUE)
00343     {
00344         if (ref->obj != NULL)
00345         {
00346             OCI_ObjectFree(ref->obj);
00347             ref->obj = NULL;
00348         }
00349 
00350         ref->typinf = ref_src->typinf;
00351         ref->pinned = ref_src->pinned;
00352     }
00353 
00354     OCI_RESULT(res);
00355 
00356     return res;
00357 }
00358 
00359 /* --------------------------------------------------------------------------------------------- *
00360  * OCI_RefIsNull
00361  * --------------------------------------------------------------------------------------------- */
00362 
00363 boolean OCI_API OCI_RefIsNull
00364 (
00365     OCI_Ref *ref
00366 )
00367 {
00368     OCI_CHECK_PTR(OCI_IPC_REF, ref, TRUE);
00369 
00370     OCI_RESULT(TRUE);
00371 
00372     return (OCIRefIsNull(ref->con->env, ref->handle) == TRUE);
00373 }
00374 
00375 /* --------------------------------------------------------------------------------------------- *
00376  * OCI_RefSetNull
00377  * --------------------------------------------------------------------------------------------- */
00378 
00379 boolean OCI_API OCI_RefSetNull
00380 (
00381     OCI_Ref *ref
00382 )
00383 {
00384     boolean res = TRUE;
00385 
00386     OCI_CHECK_PTR(OCI_IPC_REF, ref, FALSE);
00387 
00388     res = OCI_RefUnpin(ref);
00389 
00390     if (res == TRUE)
00391     {
00392         OCIRefClear(ref->con->env, ref->handle);
00393 
00394         if (ref->obj != NULL)
00395         {
00396             OCI_ObjectFree(ref->obj);
00397             ref->obj = NULL;
00398         }
00399     }
00400 
00401     OCI_RESULT(res);
00402 
00403     return res;
00404 }
00405 
00406 /* --------------------------------------------------------------------------------------------- *
00407  * OCI_RefToText
00408  * --------------------------------------------------------------------------------------------- */
00409 
00410 boolean OCI_API OCI_RefToText
00411 (
00412     OCI_Ref     *ref,
00413     unsigned int size,
00414     mtext       *str
00415 )
00416 {
00417     boolean res = TRUE;
00418     void *ostr  = NULL;
00419     int osize   = (int) size * (int) sizeof(mtext);
00420 
00421     OCI_CHECK_PTR(OCI_IPC_REF, ref, FALSE);
00422     OCI_CHECK_PTR(OCI_IPC_STRING, str, FALSE);
00423 
00424     /* init output buffer in case of OCI failure */
00425 
00426     str[0] = 0;
00427 
00428     ostr = OCI_GetInputMetaString(str, &osize);
00429 
00430     OCI_CALL2
00431     (
00432         res, ref->con,
00433 
00434         OCIRefToHex((dvoid *) ref->con->env, ref->con->err, ref->handle,
00435                     (OraText *) ostr, (ub4 *) &osize)
00436     )
00437 
00438     OCI_GetOutputMetaString(ostr, str, &osize);
00439     OCI_ReleaseMetaString(ostr);
00440 
00441     /* set null string terminator */
00442 
00443     str[osize/ (int) sizeof(mtext)] = 0;
00444 
00445     OCI_RESULT(res);
00446 
00447     return res;
00448 }
00449 
00450 /* --------------------------------------------------------------------------------------------- *
00451  * OCI_RefGetHexSize
00452  * --------------------------------------------------------------------------------------------- */
00453 
00454 unsigned int OCI_API OCI_RefGetHexSize
00455 (
00456     OCI_Ref *ref
00457 )
00458 {
00459     ub4 size = 0;
00460 
00461     OCI_CHECK_PTR(OCI_IPC_REF, ref, 0);
00462 
00463     size = OCIRefHexSize(ref->con->env, (const OCIRef *) ref->handle);
00464 
00465     size /= (ub4) sizeof(mtext);
00466 
00467     OCI_RESULT(TRUE);
00468 
00469     return (unsigned int) size;
00470 }
00471 
00472 /* --------------------------------------------------------------------------------------------- *
00473  * OCI_CollRefGetTypeInfo
00474  * --------------------------------------------------------------------------------------------- */
00475 
00476 OCI_TypeInfo * OCI_API OCI_RefGetTypeInfo
00477 (
00478     OCI_Ref *ref
00479 )
00480 {
00481     OCI_CHECK_PTR(OCI_IPC_REF, ref, NULL);
00482 
00483     OCI_RESULT(TRUE);
00484 
00485     return ref->typinf;
00486 }
00487