OCILIB (C Driver for Oracle) 3.9.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-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: collection.c, v 3.9.1 2011-07-08 00:00 Vincent Rogier $ 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 00046 ( 00047 OCI_Connection *con, 00048 OCI_Coll **pcoll, 00049 void *handle, 00050 OCI_TypeInfo *typinf 00051 ) 00052 { 00053 OCI_Coll *coll = NULL; 00054 boolean res = TRUE; 00055 00056 OCI_CHECK(pcoll == NULL, NULL); 00057 00058 if (*pcoll == NULL) 00059 { 00060 *pcoll = (OCI_Coll *) OCI_MemAlloc(OCI_IPC_COLLECTION, sizeof(*coll), (size_t) 1, TRUE); 00061 } 00062 00063 if (*pcoll != NULL) 00064 { 00065 coll = *pcoll; 00066 00067 coll->con = con; 00068 coll->handle = handle; 00069 coll->typinf = typinf; 00070 00071 if ((coll->handle == NULL) || (coll->hstate == OCI_OBJECT_ALLOCATED_ARRAY)) 00072 { 00073 /* allocates handle for non fetched collection */ 00074 00075 if (coll->hstate != OCI_OBJECT_ALLOCATED_ARRAY) 00076 { 00077 coll->hstate = OCI_OBJECT_ALLOCATED; 00078 } 00079 00080 OCI_CALL2 00081 ( 00082 res, con, 00083 00084 OCI_ObjectNew(coll->con->env, coll->con->err, coll->con->cxt, 00085 typinf->ccode, typinf->tdo, (void *) NULL, 00086 OCI_DURATION_SESSION, TRUE, (dvoid **) &coll->handle) 00087 ) 00088 } 00089 else 00090 { 00091 coll->hstate = OCI_OBJECT_FETCHED_CLEAN; 00092 } 00093 } 00094 else 00095 { 00096 res = FALSE; 00097 } 00098 00099 /* check for failure */ 00100 00101 if (res == FALSE) 00102 { 00103 OCI_CollFree(coll); 00104 coll = NULL; 00105 } 00106 00107 return coll; 00108 } 00109 00110 /* ********************************************************************************************* * 00111 * PUBLIC FUNCTIONS 00112 * ********************************************************************************************* */ 00113 00114 /* --------------------------------------------------------------------------------------------- * 00115 * OCI_CollCreate 00116 * --------------------------------------------------------------------------------------------- */ 00117 00118 OCI_Coll * OCI_API OCI_CollCreate 00119 ( 00120 OCI_TypeInfo *typinf 00121 ) 00122 { 00123 OCI_Coll *coll = NULL; 00124 00125 OCI_CHECK_INITIALIZED(NULL); 00126 00127 OCI_CHECK_PTR(OCI_IPC_TYPE_INFO, typinf, NULL); 00128 OCI_CHECK(typinf->ccode == OCI_UNKNOWN, NULL) 00129 00130 coll = OCI_CollInit(typinf->con, &coll, (OCIColl *) NULL, typinf); 00131 00132 OCI_RESULT(coll != NULL); 00133 00134 return coll; 00135 } 00136 00137 /* --------------------------------------------------------------------------------------------- * 00138 * OCI_CollFree 00139 * --------------------------------------------------------------------------------------------- */ 00140 00141 boolean OCI_API OCI_CollFree 00142 ( 00143 OCI_Coll *coll 00144 ) 00145 { 00146 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE); 00147 OCI_CHECK_OBJECT_FETCHED(coll, FALSE); 00148 00149 /* free data element accessor */ 00150 00151 if (coll->elem != NULL) 00152 { 00153 coll->elem->hstate = OCI_OBJECT_FETCHED_DIRTY; 00154 OCI_ElemFree(coll->elem); 00155 coll->elem = NULL; 00156 } 00157 00158 /* free collection for local object */ 00159 00160 if ((coll->hstate == OCI_OBJECT_ALLOCATED ) || 00161 (coll->hstate == OCI_OBJECT_ALLOCATED_ARRAY)) 00162 { 00163 OCI_OCIObjectFree(coll->con->env, coll->typinf->con->err, coll->handle, OCI_OBJECTFREE_NONULL); 00164 } 00165 00166 if (coll->hstate != OCI_OBJECT_ALLOCATED_ARRAY) 00167 { 00168 OCI_FREE(coll); 00169 } 00170 00171 OCI_RESULT(TRUE); 00172 00173 return TRUE; 00174 } 00175 00176 /* --------------------------------------------------------------------------------------------- * 00177 * OCI_CollArrayCreate 00178 * --------------------------------------------------------------------------------------------- */ 00179 00180 OCI_Coll ** OCI_API OCI_CollArrayCreate 00181 ( 00182 OCI_Connection *con, 00183 OCI_TypeInfo *typinf, 00184 unsigned int nbelem 00185 ) 00186 { 00187 OCI_Array *arr = NULL; 00188 OCI_Coll **colls = NULL; 00189 00190 arr = OCI_ArrayCreate(con, nbelem, OCI_CDT_COLLECTION, 0, sizeof(OCIColl *), 00191 sizeof(OCI_Coll), 0, typinf); 00192 00193 if (arr != NULL) 00194 { 00195 colls = (OCI_Coll **) arr->tab_obj; 00196 } 00197 00198 return colls; 00199 } 00200 00201 /* --------------------------------------------------------------------------------------------- * 00202 * OCI_CollArrayFree 00203 * --------------------------------------------------------------------------------------------- */ 00204 00205 boolean OCI_API OCI_CollArrayFree 00206 ( 00207 OCI_Coll **colls 00208 ) 00209 { 00210 return OCI_ArrayFreeFromHandles((void **) colls); 00211 } 00212 00213 /* --------------------------------------------------------------------------------------------- * 00214 * OCI_CollAssign 00215 * --------------------------------------------------------------------------------------------- */ 00216 00217 boolean OCI_API OCI_CollAssign 00218 ( 00219 OCI_Coll *coll, 00220 OCI_Coll *coll_src 00221 ) 00222 { 00223 boolean res = TRUE; 00224 00225 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE); 00226 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll_src, FALSE); 00227 00228 OCI_CHECK_COMPAT(coll->con, coll->typinf->cols[0].icode == coll_src->typinf->cols[0].icode, FALSE); 00229 00230 OCI_CALL2 00231 ( 00232 res, coll->con, 00233 00234 OCICollAssign(coll->con->env, coll->con->err, coll_src->handle, coll->handle) 00235 ) 00236 00237 OCI_RESULT(res); 00238 00239 return res; 00240 } 00241 00242 /* --------------------------------------------------------------------------------------------- * 00243 * OCI_CollGetType 00244 * --------------------------------------------------------------------------------------------- */ 00245 00246 unsigned int OCI_API OCI_CollGetType 00247 ( 00248 OCI_Coll *coll 00249 ) 00250 { 00251 unsigned int type = OCI_UNKNOWN; 00252 00253 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, OCI_UNKNOWN); 00254 00255 if (coll->typinf->ccode == OCI_TYPECODE_TABLE) 00256 { 00257 type = OCI_COLL_NESTED_TABLE; 00258 } 00259 else if(coll->typinf->ccode == OCI_TYPECODE_VARRAY) 00260 { 00261 type = OCI_COLL_VARRAY; 00262 } 00263 00264 OCI_RESULT(TRUE); 00265 00266 return type; 00267 } 00268 00269 /* --------------------------------------------------------------------------------------------- * 00270 * OCI_CollGetMax 00271 * --------------------------------------------------------------------------------------------- */ 00272 00273 unsigned int OCI_API OCI_CollGetMax 00274 ( 00275 OCI_Coll *coll 00276 ) 00277 { 00278 int max = 0; 00279 00280 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, 0); 00281 00282 max = OCICollMax(coll->con->env, coll->handle); 00283 00284 OCI_RESULT(TRUE); 00285 00286 return (unsigned int) max; 00287 } 00288 00289 /* --------------------------------------------------------------------------------------------- * 00290 * OCI_CollGetSize 00291 * --------------------------------------------------------------------------------------------- */ 00292 00293 unsigned int OCI_API OCI_CollGetSize 00294 ( 00295 OCI_Coll *coll 00296 ) 00297 { 00298 boolean res = TRUE; 00299 sb4 size = 0; 00300 00301 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, 0); 00302 00303 OCI_CALL2 00304 ( 00305 res, coll->con, 00306 00307 OCICollSize(coll->con->env, coll->con->err, coll->handle, &size) 00308 ) 00309 00310 OCI_RESULT(res); 00311 00312 return (unsigned int) size; 00313 } 00314 00315 /* --------------------------------------------------------------------------------------------- * 00316 * OCI_CollTrim 00317 * --------------------------------------------------------------------------------------------- */ 00318 00319 boolean OCI_API OCI_CollTrim 00320 ( 00321 OCI_Coll *coll, 00322 unsigned int nb_elem 00323 ) 00324 { 00325 boolean res = TRUE; 00326 unsigned int size = 0; 00327 00328 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE); 00329 00330 size = OCI_CollGetSize(coll); 00331 00332 OCI_CHECK_BOUND(coll->con, (sb4) nb_elem, (sb4) 0, (sb4) size, FALSE); 00333 00334 OCI_CALL2 00335 ( 00336 res, coll->con, 00337 00338 OCICollTrim(coll->con->env, coll->con->err, (sb4) nb_elem, coll->handle) 00339 ) 00340 00341 OCI_RESULT(res); 00342 00343 return res; 00344 } 00345 00346 /* --------------------------------------------------------------------------------------------- * 00347 * OCI_CollGetAt 00348 * --------------------------------------------------------------------------------------------- */ 00349 00350 OCI_Elem * OCI_API OCI_CollGetAt 00351 ( 00352 OCI_Coll *coll, 00353 unsigned int index 00354 ) 00355 { 00356 boolean res = TRUE; 00357 boolean exists = FALSE; 00358 void *data = NULL; 00359 OCIInd *p_ind = NULL; 00360 OCI_Elem *elem = NULL; 00361 00362 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, NULL); 00363 00364 OCI_CALL2 00365 ( 00366 res, coll->con, 00367 00368 OCICollGetElem(coll->con->env, coll->con->err, coll->handle, (sb4) index-1, 00369 &exists, &data, (dvoid **) (dvoid *) &p_ind) 00370 ) 00371 00372 if (res == TRUE && exists == TRUE && data != NULL) 00373 { 00374 elem = coll->elem = OCI_ElemInit(coll->con, &coll->elem, data, p_ind, coll->typinf); 00375 } 00376 00377 OCI_RESULT(res); 00378 00379 return elem; 00380 } 00381 00382 /* --------------------------------------------------------------------------------------------- * 00383 * OCI_CollGetAt2 00384 * --------------------------------------------------------------------------------------------- */ 00385 00386 boolean OCI_API OCI_CollGetAt2 00387 ( 00388 OCI_Coll *coll, 00389 unsigned int index, 00390 OCI_Elem *elem 00391 ) 00392 { 00393 boolean res = TRUE; 00394 boolean exists = FALSE; 00395 void *data = NULL; 00396 OCIInd *p_ind = NULL; 00397 00398 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE); 00399 OCI_CHECK_PTR(OCI_IPC_ELEMENT, elem, FALSE); 00400 00401 OCI_CHECK_COMPAT(coll->con, elem->typinf->cols[0].type == coll->typinf->cols[0].type, FALSE); 00402 00403 OCI_CALL2 00404 ( 00405 res, coll->con, 00406 00407 OCICollGetElem(coll->con->env, coll->con->err, coll->handle, (sb4) index-1, 00408 &exists, &data, (dvoid **) (dvoid *) &p_ind) 00409 ) 00410 00411 if (res == TRUE && exists == TRUE && data != NULL) 00412 { 00413 res = (OCI_ElemInit(coll->con, &elem, data, p_ind, coll->typinf) != NULL); 00414 } 00415 else 00416 { 00417 OCI_ElemSetNullIndicator(elem, OCI_IND_NULL); 00418 } 00419 00420 OCI_RESULT(res); 00421 00422 return res; 00423 } 00424 00425 /* --------------------------------------------------------------------------------------------- * 00426 * OCI_CollSetAt 00427 * --------------------------------------------------------------------------------------------- */ 00428 00429 boolean OCI_API OCI_CollSetAt 00430 ( 00431 OCI_Coll *coll, 00432 unsigned int index, 00433 OCI_Elem *elem 00434 ) 00435 { 00436 boolean res = TRUE; 00437 00438 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE); 00439 OCI_CHECK_PTR(OCI_IPC_ELEMENT, elem, FALSE); 00440 00441 OCI_CHECK_COMPAT(coll->con, elem->typinf->cols[0].type == coll->typinf->cols[0].type, FALSE); 00442 00443 OCI_CALL2 00444 ( 00445 res, coll->con, 00446 00447 OCICollAssignElem(coll->con->env, coll->con->err, (sb4) index-1, elem->handle, 00448 elem->pind, coll->handle) 00449 ) 00450 00451 OCI_RESULT(res); 00452 00453 return res; 00454 } 00455 00456 /* --------------------------------------------------------------------------------------------- * 00457 * OCI_CollAppend 00458 * --------------------------------------------------------------------------------------------- */ 00459 00460 boolean OCI_API OCI_CollAppend 00461 ( 00462 OCI_Coll *coll, 00463 OCI_Elem *elem 00464 ) 00465 { 00466 boolean res = TRUE; 00467 00468 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, FALSE); 00469 OCI_CHECK_PTR(OCI_IPC_ELEMENT, elem, FALSE); 00470 00471 OCI_CHECK_COMPAT(coll->con, elem->typinf->cols[0].type == coll->typinf->cols[0].type, FALSE); 00472 00473 OCI_CALL2 00474 ( 00475 res, coll->con, 00476 00477 OCICollAppend(coll->con->env, coll->con->err, elem->handle, elem->pind, coll->handle) 00478 ) 00479 00480 OCI_RESULT(res); 00481 00482 return res; 00483 } 00484 00485 /* --------------------------------------------------------------------------------------------- * 00486 * OCI_CollGetTypeInfo 00487 * --------------------------------------------------------------------------------------------- */ 00488 00489 OCI_TypeInfo * OCI_API OCI_CollGetTypeInfo 00490 ( 00491 OCI_Coll *coll 00492 ) 00493 { 00494 OCI_CHECK_PTR(OCI_IPC_COLLECTION, coll, NULL); 00495 00496 OCI_RESULT(TRUE); 00497 00498 return coll->typinf; 00499 } 00500 00501 /* --------------------------------------------------------------------------------------------- * 00502 * OCI_CollClear 00503 * --------------------------------------------------------------------------------------------- */ 00504 00505 boolean OCI_API OCI_CollClear 00506 ( 00507 OCI_Coll *coll 00508 ) 00509 { 00510 boolean res = TRUE; 00511 00512 unsigned int size = OCI_CollGetSize(coll); 00513 00514 if (size > 0) 00515 { 00516 res = OCI_CollTrim(coll, size); 00517 } 00518 00519 OCI_RESULT(res); 00520 00521 return res; 00522 } 00523