OCILIB (C Driver for Oracle) 3.12.1
|
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-2013 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, 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 OCI_CHECK(ref->obj == NULL, FALSE); 00177 00178 if (ref->pinned == TRUE) 00179 { 00180 OCI_CALL2 00181 ( 00182 res, ref->con, 00183 00184 OCIObjectUnpin(ref->con->env, ref->con->err, ref->obj->handle) 00185 ) 00186 00187 ref->pinned = FALSE; 00188 } 00189 00190 if (ref->obj != NULL) 00191 { 00192 ref->obj->hstate = OCI_OBJECT_FETCHED_DIRTY; 00193 OCI_ObjectFree(ref->obj); 00194 ref->obj = NULL; 00195 } 00196 00197 return res; 00198 } 00199 00200 /* ********************************************************************************************* * 00201 * PUBLIC FUNCTIONS 00202 * ********************************************************************************************* */ 00203 00204 /* --------------------------------------------------------------------------------------------- * 00205 * OCI_RefCreate 00206 * --------------------------------------------------------------------------------------------- */ 00207 00208 OCI_Ref * OCI_API OCI_RefCreate 00209 ( 00210 OCI_Connection *con, 00211 OCI_TypeInfo *typinf 00212 ) 00213 { 00214 OCI_Ref *ref = NULL; 00215 00216 OCI_CHECK_INITIALIZED(NULL); 00217 00218 OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL); 00219 OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL); 00220 00221 ref = OCI_RefInit(con, typinf, &ref, NULL); 00222 00223 OCI_RESULT(ref != NULL); 00224 00225 return ref; 00226 } 00227 00228 /* --------------------------------------------------------------------------------------------- * 00229 * OCI_RefFree 00230 * --------------------------------------------------------------------------------------------- */ 00231 00232 boolean OCI_API OCI_RefFree 00233 ( 00234 OCI_Ref *ref 00235 ) 00236 { 00237 OCI_CHECK_PTR(OCI_IPC_REF, ref, FALSE); 00238 00239 OCI_CHECK_OBJECT_FETCHED(ref, FALSE); 00240 00241 OCI_RefUnpin(ref); 00242 00243 if ((ref->hstate == OCI_OBJECT_ALLOCATED) || (ref->hstate == OCI_OBJECT_ALLOCATED_ARRAY)) 00244 { 00245 OCI_OCIObjectFree(ref->con->env, ref->con->err, ref->handle, OCI_OBJECTFREE_NONULL); 00246 } 00247 00248 if (ref->hstate != OCI_OBJECT_ALLOCATED_ARRAY) 00249 { 00250 OCI_FREE(ref); 00251 } 00252 00253 OCI_RESULT(TRUE); 00254 00255 return TRUE; 00256 } 00257 00258 /* --------------------------------------------------------------------------------------------- * 00259 * OCI_RefArrayCreate 00260 * --------------------------------------------------------------------------------------------- */ 00261 00262 OCI_Ref ** OCI_API OCI_RefArrayCreate 00263 ( 00264 OCI_Connection *con, 00265 OCI_TypeInfo *typinf, 00266 unsigned int nbelem 00267 ) 00268 { 00269 OCI_Array *arr = NULL; 00270 OCI_Ref **refs = NULL; 00271 00272 arr = OCI_ArrayCreate(con, nbelem, OCI_CDT_REF, 0, sizeof(OCIRef *), sizeof(OCI_Ref), 0, typinf); 00273 00274 if (arr != NULL) 00275 { 00276 refs = (OCI_Ref **) arr->tab_obj; 00277 } 00278 00279 return refs; 00280 } 00281 00282 /* --------------------------------------------------------------------------------------------- * 00283 * OCI_RefArrayFree 00284 * --------------------------------------------------------------------------------------------- */ 00285 00286 boolean OCI_API OCI_RefArrayFree 00287 ( 00288 OCI_Ref **refs 00289 ) 00290 { 00291 return OCI_ArrayFreeFromHandles((void **) refs); 00292 } 00293 00294 /* --------------------------------------------------------------------------------------------- * 00295 * OCI_RefGetObject 00296 * --------------------------------------------------------------------------------------------- */ 00297 00298 OCI_Object * OCI_API OCI_RefGetObject 00299 ( 00300 OCI_Ref *ref 00301 ) 00302 { 00303 boolean res = TRUE; 00304 OCI_Object *obj = NULL; 00305 00306 if (OCI_RefIsNull(ref) == FALSE) 00307 { 00308 res = OCI_RefPin(ref); 00309 00310 obj = ref->obj; 00311 } 00312 00313 OCI_RESULT(res); 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