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: array.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_ArrayInit 00043 * --------------------------------------------------------------------------------------------- */ 00044 00045 boolean OCI_ArrayInit 00046 ( 00047 OCI_Array *arr, 00048 OCI_TypeInfo *typinf 00049 ) 00050 { 00051 unsigned int i; 00052 00053 for (i = 0; i < arr->nb_elem; i++) 00054 { 00055 void *handle = NULL; 00056 00057 if (arr->elem_type == OCI_CDT_DATETIME) 00058 { 00059 handle = &(((OCIDate *)(arr->mem_handle))[i]); 00060 } 00061 else 00062 { 00063 handle = ((void **)(arr->mem_handle))[i]; 00064 } 00065 00066 arr->tab_obj[i] = ((char *) arr->mem_struct) + (arr->struct_size * i); 00067 00068 ((OCI_Datatype *) (arr->tab_obj[i]))->hstate = OCI_OBJECT_ALLOCATED_ARRAY; 00069 00070 switch (arr->elem_type) 00071 { 00072 case OCI_CDT_DATETIME: 00073 { 00074 OCI_DateInit(arr->con, (OCI_Date **) &arr->tab_obj[i], 00075 (OCIDate *) handle, FALSE, FALSE); 00076 00077 break; 00078 } 00079 case OCI_CDT_LOB: 00080 { 00081 OCI_LobInit(arr->con, (OCI_Lob **) &arr->tab_obj[i], 00082 (OCILobLocator *) handle, arr->elem_subtype); 00083 00084 break; 00085 } 00086 case OCI_CDT_FILE: 00087 { 00088 OCI_FileInit(arr->con, (OCI_File **) &arr->tab_obj[i], 00089 (OCILobLocator *) handle, arr->elem_subtype); 00090 break; 00091 } 00092 case OCI_CDT_TIMESTAMP: 00093 { 00094 OCI_TimestampInit(arr->con, (OCI_Timestamp **) &arr->tab_obj[i], 00095 (OCIDateTime *) handle, arr->elem_subtype); 00096 00097 break; 00098 } 00099 case OCI_CDT_INTERVAL: 00100 { 00101 OCI_IntervalInit(arr->con, (OCI_Interval **) &arr->tab_obj[i], 00102 (OCIInterval *) handle, arr->elem_subtype); 00103 00104 break; 00105 } 00106 case OCI_CDT_OBJECT: 00107 { 00108 OCI_ObjectInit(arr->con, (OCI_Object **) &arr->tab_obj[i], 00109 handle, typinf, NULL, -1, TRUE); 00110 00111 break; 00112 } 00113 case OCI_CDT_COLLECTION: 00114 { 00115 OCI_CollInit(arr->con, (OCI_Coll **) &arr->tab_obj[i], handle, typinf); 00116 00117 break; 00118 } 00119 case OCI_CDT_REF: 00120 { 00121 OCI_RefInit(arr->con, typinf, (OCI_Ref **) &arr->tab_obj[i], handle); 00122 00123 break; 00124 } 00125 } 00126 } 00127 00128 return TRUE; 00129 } 00130 00131 /* --------------------------------------------------------------------------------------------- * 00132 * OCI_ArrayClose 00133 * --------------------------------------------------------------------------------------------- */ 00134 00135 boolean OCI_ArrayClose 00136 ( 00137 OCI_Array *arr 00138 ) 00139 { 00140 unsigned int i; 00141 00142 OCI_CHECK_PTR(OCI_IPC_ARRAY, arr, FALSE); 00143 00144 /* Cleanup OCILIB Objects */ 00145 00146 for (i = 0; i < arr->nb_elem; i++) 00147 { 00148 switch (arr->elem_type) 00149 { 00150 case OCI_CDT_DATETIME: 00151 { 00152 OCI_DateFree((OCI_Date *) arr->tab_obj[i]); 00153 00154 break; 00155 } 00156 case OCI_CDT_LOB: 00157 { 00158 OCI_LobFree((OCI_Lob *) arr->tab_obj[i]); 00159 00160 break; 00161 } 00162 case OCI_CDT_FILE: 00163 { 00164 OCI_FileFree((OCI_File *) arr->tab_obj[i]); 00165 00166 break; 00167 } 00168 case OCI_CDT_TIMESTAMP: 00169 { 00170 OCI_TimestampFree((OCI_Timestamp *) arr->tab_obj[i]); 00171 00172 break; 00173 } 00174 case OCI_CDT_INTERVAL: 00175 { 00176 OCI_IntervalFree((OCI_Interval *) arr->tab_obj[i]); 00177 00178 break; 00179 } 00180 case OCI_CDT_OBJECT: 00181 { 00182 OCI_ObjectFree((OCI_Object *) arr->tab_obj[i]); 00183 00184 break; 00185 } 00186 case OCI_CDT_COLLECTION: 00187 { 00188 OCI_CollFree((OCI_Coll *) arr->tab_obj[i]); 00189 00190 break; 00191 } 00192 case OCI_CDT_REF: 00193 { 00194 OCI_RefFree((OCI_Ref *) arr->tab_obj[i]); 00195 00196 break; 00197 } 00198 } 00199 } 00200 00201 /* free OCI descriptors */ 00202 00203 if (arr->handle_type != 0) 00204 { 00205 OCI_DescriptorArrayFree 00206 ( 00207 (dvoid **) arr->mem_handle, 00208 (ub4 ) arr->handle_type, 00209 (ub4 ) arr->nb_elem 00210 ); 00211 } 00212 00213 OCI_FREE(arr->mem_handle); 00214 OCI_FREE(arr->mem_struct); 00215 OCI_FREE(arr->tab_obj); 00216 00217 return TRUE; 00218 } 00219 00220 /* --------------------------------------------------------------------------------------------- * 00221 * OCI_ArrayCreate 00222 * --------------------------------------------------------------------------------------------- */ 00223 00224 OCI_Array * OCI_ArrayCreate 00225 ( 00226 OCI_Connection *con, 00227 unsigned int nb_elem, 00228 unsigned int elem_type, 00229 unsigned int elem_subtype, 00230 unsigned int elem_size, 00231 unsigned int struct_size, 00232 unsigned int handle_type, 00233 OCI_TypeInfo *typinf 00234 ) 00235 { 00236 boolean res = TRUE; 00237 OCI_Array *arr = NULL; 00238 OCI_Item *item = NULL; 00239 00240 OCI_CHECK_INITIALIZED(NULL); 00241 OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL); 00242 00243 /* create array object */ 00244 00245 item = OCI_ListAppend(OCILib.arrs, sizeof(*arr)); 00246 00247 if (item != NULL) 00248 { 00249 arr = (OCI_Array *) item->data; 00250 00251 arr->con = con; 00252 arr->elem_type = elem_type; 00253 arr->elem_subtype = elem_subtype; 00254 arr->elem_size = elem_size; 00255 arr->nb_elem = nb_elem; 00256 arr->struct_size = struct_size; 00257 arr->handle_type = handle_type; 00258 00259 /* allocate OCILIB Object array */ 00260 00261 if (res == TRUE) 00262 { 00263 if ( (arr->elem_type != OCI_CDT_NUMERIC ) && 00264 (arr->elem_type != OCI_CDT_TEXT ) && 00265 (arr->elem_type != OCI_CDT_RAW )) 00266 { 00267 arr->tab_obj = (void **) OCI_MemAlloc(OCI_IPC_VOID, sizeof(void *), nb_elem, TRUE); 00268 00269 res = (arr->tab_obj != NULL) ; 00270 } 00271 } 00272 00273 /* allocate OCI handle array */ 00274 00275 if (res == TRUE) 00276 { 00277 if (arr->elem_size > 0) 00278 { 00279 arr->mem_handle = (void **) OCI_MemAlloc(OCI_IPC_VOID, elem_size, nb_elem, TRUE); 00280 00281 res = (arr->mem_handle != NULL) ; 00282 } 00283 } 00284 00285 /* allocate OCILIB structure array */ 00286 00287 if (res == TRUE) 00288 { 00289 if (arr->struct_size > 0) 00290 { 00291 arr->mem_struct = (void **) OCI_MemAlloc(OCI_IPC_VOID, struct_size, nb_elem, TRUE); 00292 00293 res = (arr->mem_struct != NULL) ; 00294 } 00295 } 00296 00297 /* allocate OCI handle descriptors */ 00298 00299 if (res == TRUE) 00300 { 00301 if (handle_type != 0) 00302 { 00303 res = (OCI_SUCCESS == OCI_DescriptorArrayAlloc 00304 ( 00305 (dvoid *) arr->con->env, 00306 (dvoid **) arr->mem_handle, 00307 (ub4 ) handle_type, 00308 (ub4 ) nb_elem, 00309 (size_t ) 0, 00310 (dvoid **) NULL 00311 )); 00312 } 00313 } 00314 00315 if ((res == TRUE) && (arr->tab_obj != NULL) && (arr->mem_handle != NULL)) 00316 { 00317 res = OCI_ArrayInit(arr, typinf); 00318 } 00319 } 00320 else 00321 { 00322 res = FALSE; 00323 } 00324 00325 /* check for failure */ 00326 00327 if (res == FALSE) 00328 { 00329 OCI_ArrayClose(arr); 00330 OCI_FREE(arr); 00331 } 00332 00333 OCI_RESULT(res); 00334 00335 return arr; 00336 } 00337 00338 /* --------------------------------------------------------------------------------------------- * 00339 * OCI_ArrayFreeFromHandles 00340 * --------------------------------------------------------------------------------------------- */ 00341 00342 boolean OCI_ArrayFreeFromHandles 00343 ( 00344 void **handles 00345 ) 00346 { 00347 boolean res = FALSE; 00348 OCI_List *list = OCILib.arrs; 00349 OCI_Item *item = NULL; 00350 OCI_Array *arr = NULL; 00351 00352 OCI_CHECK_PTR(OCI_IPC_VOID, handles, FALSE); 00353 00354 OCI_CHECK(list == NULL, FALSE); 00355 00356 if (list->mutex != NULL) 00357 { 00358 OCI_MutexAcquire(list->mutex); 00359 } 00360 00361 item = list->head; 00362 00363 while (item != NULL) 00364 { 00365 OCI_Array * tmp_arr = (OCI_Array *) item->data; 00366 00367 if ((tmp_arr != NULL) && (tmp_arr->tab_obj == handles)) 00368 { 00369 arr = tmp_arr; 00370 break; 00371 } 00372 00373 item = item->next; 00374 } 00375 00376 if (list->mutex != NULL) 00377 { 00378 OCI_MutexRelease(list->mutex); 00379 } 00380 00381 if (arr != NULL) 00382 { 00383 res = OCI_ListRemove(OCILib.arrs, arr); 00384 OCI_ArrayClose(arr); 00385 OCI_FREE(arr); 00386 } 00387 00388 OCI_RESULT(res); 00389 00390 return res; 00391 } 00392 00393 /* --------------------------------------------------------------------------------------------- * 00394 * OCI_ArrayGetOCIHandlesFromHandles 00395 * --------------------------------------------------------------------------------------------- */ 00396 00397 void * OCI_ArrayGetOCIHandlesFromHandles 00398 ( 00399 void **handles 00400 ) 00401 { 00402 OCI_List *list = OCILib.arrs; 00403 void *ret = NULL; 00404 OCI_Item *item = NULL; 00405 OCI_Array *arr = NULL; 00406 00407 OCI_CHECK(list == NULL, NULL); 00408 OCI_CHECK(list == NULL, NULL); 00409 00410 if (list->mutex != NULL) 00411 { 00412 OCI_MutexAcquire(list->mutex); 00413 } 00414 00415 item = list->head; 00416 00417 while (item != NULL) 00418 { 00419 OCI_Array * tmp_arr = (OCI_Array *) item->data; 00420 00421 if ((tmp_arr != NULL) && (tmp_arr->tab_obj == handles)) 00422 { 00423 arr = tmp_arr; 00424 break; 00425 } 00426 00427 item = item->next; 00428 } 00429 00430 if (list->mutex != NULL) 00431 { 00432 OCI_MutexRelease(list->mutex); 00433 } 00434 00435 if (arr != NULL) 00436 { 00437 ret = arr->mem_handle; 00438 } 00439 00440 return ret; 00441 }