00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "ocilib_internal.h"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 boolean OCI_ConnPoolClose(OCI_ConnPool *pool)
00046 {
00047 boolean res = TRUE;
00048
00049 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, FALSE);
00050
00051
00052
00053 OCI_ListForEach(pool->cons, (boolean (*)(void *)) OCI_ConnectionClose);
00054 OCI_ListClear(pool->cons);
00055 OCI_ListFree(pool->cons);
00056
00057 pool->cons = NULL;
00058
00059 if (OCI_LIB_THREADED)
00060 OCI_MutexFree(pool->mutex);
00061
00062 #if OCI_VERSION_COMPILE >= OCI_9_0
00063
00064 if (OCILib.version_runtime >= OCI_9_0)
00065 {
00066
00067
00068 if (pool->handle != NULL)
00069 {
00070 OCI_CALL0
00071 (
00072 res, pool->err,
00073
00074 OCIConnectionPoolDestroy(pool->handle, pool->err,
00075 (ub4) OCI_DEFAULT)
00076 )
00077
00078 OCI_HandleFree((void *) pool->handle, (ub4) OCI_HTYPE_CPOOL);
00079 }
00080
00081
00082
00083 if (pool->err != NULL)
00084 OCI_HandleFree((void *) pool->err, (ub4) OCI_HTYPE_ERROR);
00085 }
00086
00087 #endif
00088
00089 pool->err = NULL;
00090 pool->handle = NULL;
00091
00092
00093
00094 OCI_FREE(pool->name);
00095 OCI_FREE(pool->db);
00096 OCI_FREE(pool->user);
00097 OCI_FREE(pool->pwd);
00098
00099 return res;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 OCI_ConnPool * OCI_API OCI_ConnPoolCreate(const mtext *db, const mtext *user,
00111 const mtext *pwd,
00112 unsigned int mode,
00113 unsigned int min_con,
00114 unsigned int max_con,
00115 unsigned int incr_con)
00116 {
00117 OCI_ConnPool *pool = NULL;
00118 OCI_Item *item = NULL;
00119 boolean res = TRUE;
00120
00121 OCI_CHECK_MIN(NULL, NULL, max_con, 1, FALSE);
00122
00123
00124
00125 OCI_CHECK_INITIALIZED(NULL);
00126
00127
00128
00129 item = OCI_ListAppend(OCILib.pools, sizeof(*pool));
00130
00131 if (item != NULL)
00132 {
00133 pool = (OCI_ConnPool *) item->data;
00134
00135
00136
00137 pool->cons = OCI_ListCreate(OCI_IPC_CONNECTION);
00138
00139 if (OCI_LIB_THREADED)
00140 {
00141
00142
00143 pool->mutex = OCI_MutexCreateInternal();
00144
00145 res = (pool->mutex != NULL);
00146 }
00147 }
00148 else
00149 res = FALSE;
00150
00151
00152
00153 if (res == TRUE)
00154 {
00155
00156 pool->mode = mode;
00157 pool->min = min_con;
00158 pool->max = max_con;
00159 pool->incr = incr_con;
00160
00161 pool->db = mtsdup(db != NULL ? db : MT(""));
00162 pool->user = mtsdup(user != NULL ? user : MT(""));
00163 pool->pwd = mtsdup(pwd != NULL ? pwd : MT(""));
00164 }
00165
00166
00167 #if OCI_VERSION_COMPILE >= OCI_9_0
00168
00169 if (OCILib.version_runtime >= OCI_9_0)
00170 {
00171 int osize_name = -1;
00172 int osize_db = -1;
00173 int osize_user = -1;
00174 int osize_pwd = -1;
00175
00176 void *ostr_name = NULL;
00177 void *ostr_db = NULL;
00178 void *ostr_user = NULL;
00179 void *ostr_pwd = NULL;
00180
00181
00182
00183 if (res == TRUE)
00184 res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
00185 (dvoid **) (void *) &pool->err,
00186 (ub4) OCI_HTYPE_ERROR,
00187 (size_t) 0,
00188 (dvoid **) NULL));
00189
00190
00191
00192 if (res == TRUE)
00193 res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
00194 (dvoid **) (void *) &pool->handle,
00195 (ub4) OCI_HTYPE_CPOOL,
00196 (size_t) 0,
00197 (dvoid **) NULL));
00198
00199
00200
00201 if (res == TRUE)
00202 {
00203 ostr_db = OCI_GetInputMetaString(pool->db, &osize_db);
00204 ostr_user = OCI_GetInputMetaString(pool->user, &osize_user);
00205 ostr_pwd = OCI_GetInputMetaString(pool->pwd, &osize_pwd);
00206
00207 OCI_CALL3
00208 (
00209 res, pool->err,
00210
00211 OCIConnectionPoolCreate(OCILib.env, pool->err, pool->handle,
00212 (OraText **) (dvoid *) &ostr_name,
00213 (sb4*) &osize_name,
00214 (OraText *) ostr_db, (sb4) osize_db,
00215 (ub4) pool->min, (ub4) pool->max,
00216 (ub4) pool->incr, (OraText *) ostr_user,
00217 (sb4) osize_user, (OraText *) ostr_pwd,
00218 (sb4) osize_pwd, (ub4) OCI_DEFAULT)
00219 )
00220
00221 OCI_ReleaseMetaString(ostr_db);
00222 OCI_ReleaseMetaString(ostr_user);
00223 OCI_ReleaseMetaString(ostr_pwd);
00224 }
00225
00226 if ((res == TRUE) && (ostr_name != NULL))
00227 {
00228 pool->name = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
00229 (osize_name / (int) sizeof(omtext)) + 1,
00230 FALSE);
00231
00232 if (pool->name != NULL)
00233 {
00234 OCI_CopyString(ostr_name, pool->name, &osize_name,
00235 sizeof(omtext), sizeof(mtext));
00236 }
00237 else
00238 res = FALSE;
00239 }
00240 }
00241
00242 #endif
00243
00244
00245
00246
00247 if (res == TRUE)
00248 {
00249 OCI_Connection *cn;
00250
00251 while ((min_con--) > 0)
00252 {
00253 cn = OCI_ConnectionAllocate(pool, pool->db, pool->user,
00254 pool->pwd, pool->mode);
00255 }
00256 }
00257 else
00258 {
00259 OCI_ConnPoolFree(pool);
00260 pool = NULL;
00261 }
00262
00263 OCI_RESULT(res);
00264
00265 return pool;
00266 }
00267
00268
00269
00270
00271
00272 boolean OCI_API OCI_ConnPoolFree(OCI_ConnPool *pool)
00273 {
00274 boolean res = TRUE;
00275
00276 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, FALSE);
00277
00278 res = OCI_ConnPoolClose(pool);
00279
00280 OCI_ListRemove(OCILib.pools, pool);
00281
00282 OCI_FREE(pool);
00283
00284 OCI_RESULT(res);
00285
00286 return res;
00287 }
00288
00289
00290
00291
00292
00293 OCI_Connection * OCI_API OCI_ConnPoolGetConnection(OCI_ConnPool *pool)
00294 {
00295 OCI_Connection *con = NULL;
00296 OCI_Item *item = NULL;
00297 boolean res = FALSE;
00298 boolean found = FALSE;
00299
00300 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, NULL);
00301
00302 if (OCI_LIB_THREADED)
00303 OCI_MutexAcquire(pool->mutex);
00304
00305
00306
00307 item = pool->cons->head;
00308
00309 while (item != NULL)
00310 {
00311 con = (OCI_Connection *) item->data;
00312
00313 if (((OCILib.version_runtime >= OCI_9_0) && (con->cstate == OCI_CONN_ALLOCATED)) ||
00314 ((OCILib.version_runtime < OCI_9_0) && (con->cstate == OCI_CONN_ATTACHED )))
00315 {
00316 found = TRUE;
00317 break;
00318 }
00319
00320 item = item->next;
00321 }
00322
00323 if (found == FALSE)
00324 {
00325 con = NULL;
00326
00327
00328
00329 if (OCILib.version_runtime >= OCI_9_0 || pool->cons->count < pool->max)
00330 {
00331 ub4 i, nb;
00332 OCI_Connection *c = NULL;
00333
00334 nb = pool->nb_opened + pool->incr;
00335
00336 if (nb > pool->max)
00337 nb = pool->max;
00338
00339 for (i = pool->nb_opened; i < nb; i++)
00340 {
00341 c = OCI_ConnectionAllocate(pool, pool->db, pool->user,
00342 pool->pwd, pool->mode);
00343
00344 if (i == pool->nb_opened && c != NULL)
00345 con = c;
00346 }
00347 }
00348 }
00349
00350 if (con != NULL)
00351 {
00352 res = TRUE;
00353
00354 if (con->cstate == OCI_CONN_ALLOCATED)
00355 res = res && OCI_ConnectionAttach(con);
00356
00357 res = res && OCI_ConnectionLogon(con, NULL);
00358
00359 if (res == FALSE)
00360 {
00361 OCI_ConnectionFree(con);
00362 con = NULL;
00363 }
00364 }
00365 else
00366 {
00367 con = NULL;
00368 }
00369
00370 if (OCI_LIB_THREADED)
00371 OCI_MutexRelease(pool->mutex);
00372
00373 OCI_RESULT(res);
00374
00375 return con;
00376 }
00377
00378
00379
00380
00381
00382 unsigned int OCI_API OCI_ConnPoolGetTimeout(OCI_ConnPool *pool)
00383 {
00384 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, 0);
00385
00386 OCI_RESULT(TRUE);
00387
00388 return pool->timeout;
00389 }
00390
00391
00392
00393
00394
00395 boolean OCI_API OCI_ConnPoolSetTimeout(OCI_ConnPool *pool, unsigned int value)
00396 {
00397 boolean res = TRUE;
00398
00399 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, FALSE);
00400
00401 #if OCI_VERSION_COMPILE >= OCI_9_0
00402
00403 if (OCILib.version_runtime >= OCI_9_0)
00404 {
00405 ub4 timeout = value;
00406
00407 OCI_CALL3
00408 (
00409 res, pool->err,
00410
00411 OCIAttrSet((dvoid *) pool->handle, (ub4) OCI_HTYPE_CPOOL,
00412 (dvoid *) &timeout,(ub4) sizeof(timeout),
00413 (ub4) OCI_ATTR_CONN_TIMEOUT, pool->err)
00414 )
00415 }
00416
00417 #endif
00418
00419 if (res == TRUE)
00420 pool->timeout = value;
00421
00422 OCI_RESULT(res);
00423
00424 return res;
00425 }
00426
00427
00428
00429
00430
00431 boolean OCI_API OCI_ConnPoolGetNoWait(OCI_ConnPool *pool)
00432 {
00433 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, FALSE);
00434
00435 OCI_RESULT(TRUE);
00436
00437 return pool->nowait;
00438 }
00439
00440
00441
00442
00443
00444 boolean OCI_API OCI_ConnPoolSetNoWait(OCI_ConnPool *pool, boolean value)
00445 {
00446 boolean res = TRUE;
00447
00448 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, 0);
00449
00450 #if OCI_VERSION_COMPILE >= OCI_9_0
00451
00452 if (OCILib.version_runtime >= OCI_9_0)
00453 {
00454 ub1 nowait = (ub1) value;
00455
00456 OCI_CALL3
00457 (
00458 res, pool->err,
00459
00460 OCIAttrSet((dvoid *) pool->handle, (ub4) OCI_HTYPE_CPOOL,
00461 (dvoid *) &nowait, (ub4) sizeof(nowait),
00462 (ub4) OCI_ATTR_CONN_NOWAIT, pool->err)
00463 )
00464 }
00465
00466 #endif
00467
00468 if (res == TRUE)
00469 pool->nowait = value;
00470
00471 OCI_RESULT(res);
00472
00473 return TRUE;
00474 }
00475
00476
00477
00478
00479
00480 unsigned int OCI_API OCI_ConnPoolGetBusyCount(OCI_ConnPool *pool)
00481 {
00482 boolean res = TRUE;
00483
00484 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, 0);
00485
00486 #if OCI_VERSION_COMPILE >= OCI_9_0
00487
00488 if (OCILib.version_runtime >= OCI_9_0)
00489 {
00490 ub4 value = 0;
00491
00492 OCI_CALL3
00493 (
00494 res, pool->err,
00495
00496 OCIAttrGet((dvoid *) pool->handle,(ub4) OCI_HTYPE_CPOOL,
00497 (dvoid *) &value, (ub4 *) NULL,
00498 (ub4) OCI_ATTR_CONN_BUSY_COUNT, pool->err)
00499 )
00500
00501 if (res == TRUE)
00502 pool->nb_busy = value;
00503 }
00504
00505 #endif
00506
00507 OCI_RESULT(res);
00508
00509 return pool->nb_busy;
00510 }
00511
00512
00513
00514
00515
00516 unsigned int OCI_API OCI_ConnPoolGetOpenedCount(OCI_ConnPool *pool)
00517 {
00518 boolean res = TRUE;
00519
00520 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, 0);
00521
00522 #if OCI_VERSION_COMPILE >= OCI_9_0
00523
00524 if (OCILib.version_runtime >= OCI_9_0)
00525 {
00526 ub4 value = 0;
00527
00528 OCI_CALL3
00529 (
00530 res, pool->err,
00531
00532 OCIAttrGet((dvoid *) pool->handle, (ub4) OCI_HTYPE_CPOOL,
00533 (dvoid *) &value, (ub4 *) NULL,
00534 (ub4) OCI_ATTR_CONN_OPEN_COUNT, pool->err)
00535 )
00536
00537 if (res == TRUE)
00538 pool->nb_opened = value;
00539 }
00540
00541 #endif
00542
00543 OCI_RESULT(res);
00544
00545 return pool->nb_opened;
00546 }
00547
00548
00549
00550
00551
00552 unsigned int OCI_API OCI_ConnPoolGetMin(OCI_ConnPool *pool)
00553 {
00554 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, 0);
00555
00556 OCI_RESULT(TRUE);
00557
00558 return pool->min;
00559 }
00560
00561
00562
00563
00564
00565 unsigned int OCI_API OCI_ConnPoolGetMax(OCI_ConnPool *pool)
00566 {
00567 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, 0);
00568
00569 OCI_RESULT(TRUE);
00570
00571 return pool->max;
00572 }
00573
00574
00575
00576
00577
00578 unsigned int OCI_API OCI_ConnPoolGetIncrement(OCI_ConnPool *pool)
00579 {
00580 OCI_CHECK_PTR(OCI_IPC_CONNPOOL, pool, 0);
00581
00582 OCI_RESULT(TRUE);
00583
00584 return pool->incr;
00585 }