OCILIB (C Driver for Oracle) 3.12.1
connection.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-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: connection.c, Vincent Rogier $
00033  * --------------------------------------------------------------------------------------------- */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 /* ********************************************************************************************* *
00038  *                             PRIVATE FUNCTIONS
00039  * ********************************************************************************************* */
00040 
00041 /* --------------------------------------------------------------------------------------------- *
00042  * OCI_ConnectionAllocate
00043  * --------------------------------------------------------------------------------------------- */
00044 
00045 OCI_Connection * OCI_ConnectionAllocate
00046 (
00047     OCI_Pool    *pool,
00048     const mtext *db,
00049     const mtext *user,
00050     const mtext *pwd,
00051     unsigned int mode
00052 )
00053 {
00054     OCI_Connection *con = NULL;
00055     OCI_List *list      = NULL;
00056     OCI_Item *item      = NULL;
00057     boolean res         = TRUE;
00058 
00059     /* create connection object */
00060 
00061     if (pool != NULL)
00062     {
00063         list = pool->cons;
00064     }
00065     else
00066     {
00067         list = OCILib.cons;
00068     }
00069 
00070     item = OCI_ListAppend(list, sizeof(*con));
00071 
00072     if (item != NULL)
00073     {
00074         con = (OCI_Connection *) item->data;
00075 
00076         con->alloc_handles = ((con->mode & OCI_SESSION_XA) == 0);
00077 
00078         /* create internal lists */
00079 
00080         con->stmts = OCI_ListCreate(OCI_IPC_STATEMENT);
00081 
00082         if (res == TRUE)
00083         {
00084             con->tinfs = OCI_ListCreate(OCI_IPC_TYPE_INFO);
00085             res        = (con->tinfs != NULL);
00086         }
00087 
00088         if (res == TRUE)
00089         {
00090             con->trsns = OCI_ListCreate(OCI_IPC_TRANSACTION);
00091             res        = (con->trsns != NULL);
00092         }
00093 
00094         /* set attributes */
00095 
00096         if (res == TRUE)
00097         {
00098             con->mode     = mode;
00099             con->pool     = pool;
00100             con->sess_tag = NULL;
00101 
00102             if (con->pool != NULL)
00103             {
00104                 con->db   = (mtext *) db;
00105                 con->user = (mtext *) user;
00106                 con->pwd  = (mtext *) pwd;
00107 
00108             #if OCI_VERSION_COMPILE >= OCI_9_2
00109 
00110                 if (con->pool->htype == OCI_HTYPE_SPOOL)
00111                 {
00112                     con->alloc_handles = FALSE;
00113                 }
00114 
00115             #endif
00116 
00117             }
00118             else
00119             {
00120                 con->db   = mtsdup(db   != NULL ? db   : MT(""));
00121                 con->user = mtsdup(user != NULL ? user : MT(""));
00122                 con->pwd  = mtsdup(pwd  != NULL ? pwd  : MT(""));
00123             }
00124 
00125         #if OCI_VERSION_COMPILE >= OCI_10_1
00126 
00127             if (con->mode & OCI_SESSION_XA)
00128             {
00129                 char dbname[OCI_SIZE_BUFFER+1];
00130 
00131                 memset(dbname, 0, sizeof(dbname));
00132 
00133                 if (con->db != NULL && con->db[0] != 0)
00134                 {
00135 
00136             #if defined(OCI_CHARSET_WIDE)
00137 
00138                     wcstombs(dbname, con->db, sizeof(dbname));
00139 
00140             #else
00141 
00142                     strncat(dbname, con->db, sizeof(dbname) - strlen(dbname));
00143 
00144             #endif
00145 
00146                 }
00147 
00148                 con->env = xaoEnv((OraText *) (dbname[0] ? dbname : NULL ));
00149             }
00150             else
00151 
00152         #endif
00153 
00154             {
00155                 con->env = OCILib.env;
00156             }
00157 
00158             res = (con->env != NULL);
00159         }
00160 
00161         /*  allocate error handle */
00162 
00163         if (res == TRUE)
00164         {
00165             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) con->env,
00166                                                   (dvoid **) (void *) &con->err,
00167                                                   (ub4) OCI_HTYPE_ERROR,
00168                                                   (size_t) 0, (dvoid **) NULL));
00169         }
00170     }
00171     else
00172     {
00173         res = FALSE;
00174     }
00175 
00176     /* update internal status */
00177 
00178     if (res == TRUE)
00179     {
00180         con->cstate = OCI_CONN_ALLOCATED;
00181     }
00182     else
00183     {
00184         OCI_ConnectionFree(con);
00185         con = NULL;
00186     }
00187 
00188     return con;
00189 }
00190 
00191 /* --------------------------------------------------------------------------------------------- *
00192  * OCI_ConnectionDeallocate
00193  * --------------------------------------------------------------------------------------------- */
00194 
00195 boolean OCI_ConnectionDeallocate
00196 (
00197     OCI_Connection *con
00198 )
00199 {
00200     OCI_CHECK(con == NULL, FALSE);
00201     OCI_CHECK(con->cstate != OCI_CONN_ALLOCATED, FALSE);
00202 
00203     /* close error handle */
00204 
00205     if (con->err != NULL)
00206     {
00207         OCI_HandleFree((dvoid *) con->err, (ub4) OCI_HTYPE_ERROR);
00208     }
00209 
00210     /* close server handle (if it had been allocated) in case of login error */
00211 
00212     if ((con->svr != NULL) && (con->alloc_handles == TRUE))
00213     {
00214         OCI_HandleFree((dvoid *) con->svr, (ub4) OCI_HTYPE_SERVER);
00215     }
00216 
00217     con->cxt = NULL;
00218     con->ses = NULL;
00219     con->svr = NULL;
00220     con->err = NULL;
00221 
00222     return TRUE;
00223 }
00224 
00225 /* --------------------------------------------------------------------------------------------- *
00226  * OCI_ConnectionAttach
00227  * --------------------------------------------------------------------------------------------- */
00228 
00229 boolean OCI_ConnectionAttach
00230 (
00231     OCI_Connection *con
00232 )
00233 {
00234     boolean res = TRUE;
00235 
00236     OCI_CHECK(con == NULL, FALSE);
00237     OCI_CHECK(con->cstate != OCI_CONN_ALLOCATED, FALSE);
00238 
00239     /* allocate server handle for non session pooled connection */
00240 
00241     if (con->alloc_handles == TRUE)
00242     {
00243         ub4 cmode   = OCI_DEFAULT;
00244         void *ostr  = NULL;
00245         int osize   = -1;
00246         
00247         res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) con->env,
00248                                               (dvoid **) (void *) &con->svr,
00249                                               (ub4) OCI_HTYPE_SERVER,
00250                                               (size_t) 0, (dvoid **) NULL));
00251 
00252         /* attach server handle to service name */
00253 
00254     #if OCI_VERSION_COMPILE >= OCI_9_0
00255 
00256         if (OCILib.version_runtime >= OCI_9_0 && con->pool != NULL)
00257         {
00258             ostr  = OCI_GetInputMetaString(con->pool->name, &osize);
00259             cmode = OCI_CPOOL;
00260         }
00261         else
00262 
00263     #endif
00264 
00265         {
00266             ostr = OCI_GetInputMetaString(con->db, &osize);
00267         }
00268 
00269         OCI_CALL2
00270         (
00271             res, con,
00272 
00273             OCIServerAttach(con->svr, con->err,(OraText *) ostr, (sb4) osize, cmode)
00274         )
00275 
00276         OCI_ReleaseMetaString(ostr);
00277     }
00278 
00279     /* handle errors */
00280 
00281     if (res == TRUE)
00282     {
00283         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00284         {
00285             con->pool->nb_opened++;
00286         }
00287 
00288         con->cstate = OCI_CONN_ATTACHED;
00289     }
00290 
00291     return res;
00292 }
00293 
00294 /* --------------------------------------------------------------------------------------------- *
00295  * OCI_ConnectionDetach
00296  * --------------------------------------------------------------------------------------------- */
00297 
00298 boolean OCI_ConnectionDetach
00299 (
00300     OCI_Connection *con
00301 )
00302 {
00303     boolean res = TRUE;
00304 
00305     OCI_CHECK(con == NULL, FALSE);
00306     OCI_CHECK(con->cstate != OCI_CONN_ATTACHED, FALSE);
00307 
00308     if ((con->alloc_handles == TRUE) && (con->svr != NULL))
00309     {
00310         /* detach from the oracle server */
00311 
00312         OCI_CALL2
00313         (
00314             res, con,
00315 
00316             OCIServerDetach(con->svr, con->err, (ub4) OCI_DEFAULT)
00317         )
00318 
00319         /* close server handle */
00320 
00321         OCI_HandleFree((dvoid *) con->svr, (ub4) OCI_HTYPE_SERVER);
00322 
00323         con->svr = NULL;
00324     }
00325 
00326     /* update internal status */
00327 
00328     if (res == TRUE)
00329     {
00330         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00331         {
00332             con->pool->nb_opened--;
00333         }
00334 
00335         con->cstate = OCI_CONN_ALLOCATED;
00336     }
00337 
00338     return res;
00339 }
00340 
00341 /* --------------------------------------------------------------------------------------------- *
00342  * OCI_ConnectionLogon
00343  * --------------------------------------------------------------------------------------------- */
00344 
00345 boolean OCI_ConnectionLogon
00346 (
00347     OCI_Connection *con,
00348     const mtext    *new_pwd,
00349     const mtext    *tag
00350 )
00351 {
00352     void *ostr  = NULL;
00353     int osize   = -1;
00354     boolean res = TRUE;
00355 
00356     OCI_CHECK(con == NULL, FALSE);
00357 
00358 #if OCI_VERSION_COMPILE < OCI_9_2
00359 
00360     OCI_NOT_USED(tag)
00361 
00362 #endif
00363 
00364     /* 1 - XA connection */
00365 
00366 #if OCI_VERSION_COMPILE >= OCI_10_1
00367 
00368     if (con->mode & OCI_SESSION_XA)
00369     {
00370         char dbname[OCI_SIZE_BUFFER+1];
00371 
00372         memset(dbname, 0, sizeof(dbname));
00373 
00374         if (con->db != NULL && con->db[0] != 0)
00375         {
00376 
00377         #if defined(OCI_CHARSET_WIDE)
00378 
00379             wcstombs(dbname, con->db, sizeof(dbname));
00380 
00381         #else
00382 
00383             strncat(dbname, con->db, sizeof(dbname) - strlen(dbname));
00384 
00385         #endif
00386 
00387         }
00388 
00389         con->cxt = xaoSvcCtx((OraText *) (dbname[0] ? dbname : NULL ));
00390 
00391         res = (con->cxt != NULL);
00392 
00393         if (res == TRUE)
00394         {
00395             OCI_CALL2
00396             (
00397                 res, con,
00398 
00399                 OCIAttrGet((dvoid **) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00400                            (dvoid *) &con->svr, (ub4 *) NULL,
00401                            (ub4) OCI_ATTR_SERVER, con->err)
00402 
00403             )
00404 
00405             OCI_CALL2
00406             (
00407                 res, con,
00408 
00409                 OCIAttrGet((dvoid **) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00410                            (dvoid *) &con->ses, (ub4 *) NULL,
00411                            (ub4) OCI_ATTR_SESSION, con->err)
00412 
00413             )
00414 
00415             OCI_CALL2
00416             (
00417                 res, con,
00418 
00419                 OCIAttrGet((dvoid **) con->ses, (ub4) OCI_HTYPE_SESSION,
00420                            (dvoid *) &con->user, (ub4 *) NULL,
00421                            (ub4) OCI_ATTR_USERNAME, con->err)
00422 
00423             )
00424         }
00425     }
00426 
00427 #endif
00428 
00429     /* 2 - regular connection and connection from connection pool */
00430 
00431     if (con->alloc_handles == TRUE)
00432     {
00433         /* allocate session handle */
00434 
00435         if (res == TRUE)
00436         {
00437             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) con->env,
00438                                                   (dvoid **) (void *) &con->ses,
00439                                                   (ub4) OCI_HTYPE_SESSION,
00440                                                   (size_t) 0, (dvoid **) NULL));
00441         }
00442 
00443         /* allocate context handle */
00444 
00445         if (res == TRUE)
00446         {
00447             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) con->env,
00448                                                   (dvoid **) (void *) &con->cxt,
00449                                                   (ub4) OCI_HTYPE_SVCCTX,
00450                                                   (size_t) 0, (dvoid **) NULL));
00451         }
00452 
00453         /* set context server attribute */
00454 
00455         OCI_CALL2
00456         (
00457             res, con,
00458 
00459             OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00460                        (dvoid *) con->svr, (ub4) sizeof (con->svr),
00461                        (ub4) OCI_ATTR_SERVER, con->err)
00462         )
00463 
00464         /* modifiy user password if needed */
00465 
00466         if (new_pwd && new_pwd[0])
00467         {
00468             int   osize1 = -1;
00469             int   osize2 = -1;
00470             int   osize3 = -1;
00471             void *ostr1  = NULL;
00472             void *ostr2  = NULL;
00473             void *ostr3  = NULL;
00474 
00475             ostr1 = OCI_GetInputMetaString(con->user, &osize1);
00476             ostr2 = OCI_GetInputMetaString(con->pwd,  &osize2);
00477             ostr3 = OCI_GetInputMetaString(new_pwd,   &osize3);
00478 
00479             OCI_CALL2
00480             (
00481                 res, con,
00482 
00483                 OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00484                            (dvoid *) con->ses, (ub4) sizeof(con->ses),
00485                            (ub4) OCI_ATTR_SESSION, con->err)
00486             )
00487 
00488             OCI_CALL2
00489             (
00490                 res, con,
00491 
00492                 OCIPasswordChange(con->cxt, con->err,
00493                                   (OraText *) ostr1, (ub4) osize1,
00494                                   (OraText *) ostr2, (ub4) osize2,
00495                                   (OraText *) ostr3, (ub4) osize3,
00496                                   OCI_AUTH)
00497             )
00498 
00499             OCI_ReleaseMetaString(ostr1);
00500             OCI_ReleaseMetaString(ostr2);
00501             OCI_ReleaseMetaString(ostr3);
00502 
00503 
00504             if (res == TRUE)
00505             {
00506                 OCI_FREE(con->pwd);
00507 
00508                 con->pwd = mtsdup(new_pwd);
00509             }
00510         }
00511         else
00512         {
00513             /* set session login attribute */
00514 
00515             if ((res == TRUE) && (con->user != NULL) && (con->user[0] != 0))
00516             {
00517                 osize = -1;
00518                 ostr  = OCI_GetInputMetaString(con->user, &osize);
00519 
00520                 OCI_CALL2
00521                 (
00522                     res, con,
00523 
00524                     OCIAttrSet((dvoid *) con->ses,(ub4)  OCI_HTYPE_SESSION, (dvoid *) ostr,
00525                                (ub4) osize, (ub4) OCI_ATTR_USERNAME, con->err)
00526                 )
00527 
00528                 OCI_ReleaseMetaString(ostr);
00529             }
00530 
00531             /* set session password attribute */
00532 
00533             if ((res == TRUE) && (con->pwd != NULL) && (con->pwd[0] != 0))
00534             {
00535                 osize = -1;
00536                 ostr  = OCI_GetInputMetaString(con->pwd, &osize);
00537 
00538                 OCI_CALL2
00539                 (
00540                     res, con,
00541 
00542                     OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION, (dvoid *) ostr,
00543                                (ub4) osize, (ub4) OCI_ATTR_PASSWORD, con->err)
00544                 )
00545 
00546                 OCI_ReleaseMetaString(ostr);
00547             }
00548 
00549 
00550             /* set OCILIB's driver layer name attribute */
00551 
00552         #if OCI_VERSION_COMPILE >= OCI_11_1
00553 
00554             if ((res == TRUE) && (OCILib.version_runtime >= OCI_11_1))
00555             {
00556                 osize = -1;
00557                 ostr  = OCI_GetInputMetaString(OCILIB_DRIVER_NAME, &osize);
00558 
00559                 OCI_CALL2
00560                 (
00561                     res, con,
00562 
00563                     OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION, (dvoid *) ostr,
00564                                 (ub4) osize, (ub4) OCI_ATTR_DRIVER_NAME, con->err)
00565                 )
00566 
00567                 OCI_ReleaseMetaString(ostr);
00568             }
00569 
00570         #endif
00571 
00572             /* start session */
00573 
00574             if (res == TRUE)
00575             {
00576                 ub4 credt = OCI_CRED_RDBMS;
00577                 ub4 mode  = con->mode;
00578 
00579                 if  (((con->user == NULL) || (con->user[0] == 0)) &&
00580                      ((con->pwd  == NULL) || (con->pwd[0]  == 0)))
00581                 {
00582                     credt = OCI_CRED_EXT;
00583                 }
00584 
00585             #if OCI_VERSION_COMPILE >= OCI_9_2
00586        
00587                 /* activate statement cache is the OCI version supports it */
00588 
00589                 if (OCILib.version_runtime >= OCI_9_2)
00590                 {
00591                     mode |= OCI_STMT_CACHE;
00592                 }
00593 
00594             #endif
00595 
00596                 /* start session */
00597 
00598                 OCI_CALL2
00599                 (
00600                     res, con,
00601 
00602                     OCISessionBegin(con->cxt, con->err, con->ses, credt, mode)
00603                 )
00604 
00605                 if (res == TRUE)
00606                 {
00607                     /* This call has moved after OCISessionBegin() call to
00608                        enable connection pooling (an error ORA-24324 was thrown if
00609                        the session handle was set to the service context handle
00610                        before OCISessionBegin()
00611 
00612                        note  : from v3.7.0, OCISessionBegin() is not used anymore
00613                                for OCI managed pools
00614                                From v3.9.4, OCISessionBegin() is not used anymore 
00615                                only for session pools
00616                        */
00617 
00618                     OCI_CALL2
00619                     (
00620                         res, con,
00621 
00622                         OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00623                                    (dvoid *) con->ses, (ub4) sizeof(con->ses),
00624                                    (ub4) OCI_ATTR_SESSION, con->err)
00625                     )
00626                 }
00627                 else
00628                 {
00629                     /* could not start session, must free the session and context handles */
00630 
00631                     OCI_HandleFree((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION);
00632                     OCI_HandleFree((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX);
00633 
00634                     con->ses = NULL;
00635                     con->cxt = NULL;
00636                 }
00637 
00638                 if (res == TRUE)
00639                 {                    
00640                     if (!(con->mode & OCI_PRELIM_AUTH))
00641                     {
00642                         /* create default transaction object */
00643 
00644                        OCI_Transaction *trs = OCI_TransactionCreate(con, 1, OCI_TRANS_READWRITE, NULL);
00645 
00646                        if (trs != NULL)
00647                        {
00648                            if (OCI_SetTransaction(con, trs))
00649                            {
00650                                 /* start transaction */
00651 
00652                                 res = OCI_TransactionStart(trs);
00653                            }
00654                        }
00655                     }
00656                 }
00657             }
00658         }
00659     }
00660 
00661 #if OCI_VERSION_COMPILE >= OCI_9_2
00662 
00663    /* 3 - connection from session pool */
00664 
00665     else 
00666     {
00667         if (OCILib.version_runtime >= OCI_9_0)
00668         {
00669             ub4 mode       = OCI_DEFAULT;
00670             boolean found  = FALSE;
00671             void *ostr_tag = NULL;
00672             int osize_tag  = 0;
00673 
00674             OraText *ostr_ret = NULL;
00675             ub4 osize_ret     = 0;
00676 
00677             osize = -1;
00678             ostr  = OCI_GetInputMetaString(con->pool->name, &osize);
00679 
00680             mode = OCI_SESSGET_SPOOL;
00681 
00682             if (tag != NULL && tag[0] != 0)
00683             {
00684                 osize_tag = -1;
00685                 ostr_tag  = OCI_GetInputMetaString(tag, &osize_tag);
00686             }
00687 
00688             OCI_CALL2
00689             (
00690                 res, con,
00691 
00692                 OCISessionGet(con->env, con->err, &con->cxt, NULL,
00693                               (OraText  *) ostr, (ub4) osize, (OraText *) ostr_tag, osize_tag,
00694                               (OraText **) &ostr_ret, &osize_ret, &found, mode)
00695             )
00696 
00697             OCI_CALL2
00698             (
00699                 res, con,
00700 
00701                 OCIAttrGet((dvoid **) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00702                             (dvoid *) &con->svr, (ub4 *) NULL,
00703                             (ub4) OCI_ATTR_SERVER, con->err)
00704 
00705             )
00706 
00707             OCI_CALL2
00708             (
00709                 res, con,
00710 
00711                 OCIAttrGet((dvoid **) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00712                             (dvoid *) &con->ses, (ub4 *) NULL,
00713                             (ub4) OCI_ATTR_SESSION, con->err)
00714 
00715             )
00716 
00717             if (res == TRUE)
00718             {
00719                 if (found == TRUE)
00720                 {
00721                     OCI_SetSessionTag(con, tag);
00722                 }
00723             }
00724         }
00725     }
00726 
00727 #endif
00728 
00729     /* check for success */
00730 
00731     if (res == TRUE)
00732     {
00733         /* get server version */
00734 
00735         OCI_GetVersionServer(con);
00736 
00737         /* update internal status */
00738 
00739         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00740         {
00741             con->pool->nb_busy++;
00742         }
00743 
00744         con->cstate = OCI_CONN_LOGGED;
00745     }
00746 
00747     return res;
00748 }
00749 
00750 /* --------------------------------------------------------------------------------------------- *
00751  * OCI_ConnectionLogOff
00752  * --------------------------------------------------------------------------------------------- */
00753 
00754 boolean OCI_ConnectionLogOff
00755 (
00756     OCI_Connection *con
00757 )
00758 {
00759     boolean res = TRUE;
00760 
00761     OCI_CHECK(con == NULL, FALSE);
00762     OCI_CHECK(con->cstate != OCI_CONN_LOGGED, FALSE);
00763 
00764     /* close opened files */
00765 
00766     if (con->nb_files > 0)
00767     {
00768         OCILobFileCloseAll(con->cxt, con->err);
00769     }
00770 
00771     /* deassociate connection from existing subscriptions */
00772 
00773     OCI_SubscriptionDetachConnection(con);
00774 
00775     /* free all statements */
00776 
00777     OCI_ListForEach(con->stmts, (POCI_LIST_FOR_EACH) OCI_StatementClose);
00778     OCI_ListClear(con->stmts);
00779 
00780     /* free all type info objects */
00781 
00782     OCI_ListForEach(con->tinfs, (POCI_LIST_FOR_EACH) OCI_TypeInfoClose);
00783     OCI_ListClear(con->tinfs);
00784 
00785     /* free all transactions */
00786 
00787     OCI_ListForEach(con->trsns, (POCI_LIST_FOR_EACH) OCI_TransactionClose);
00788     OCI_ListClear(con->trsns);
00789 
00790     /* close session */
00791 
00792     if (con->alloc_handles == TRUE)
00793     {
00794         /* close any server files not explicitly closed - no check of return code */
00795 
00796         if  ((con->cxt != NULL) && (con->err != NULL) && (con->ses != NULL))
00797         {
00798             OCI_CALL2
00799             (
00800                 res, con,
00801 
00802                 OCISessionEnd(con->cxt, con->err, con->ses, (ub4) OCI_DEFAULT)
00803             )
00804 
00805             /* close session handle */
00806 
00807             if (con->ses != NULL)
00808             {
00809                 OCI_HandleFree((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION);
00810 
00811                 con->ses = NULL;
00812             }
00813 
00814             /* close context handle */
00815 
00816             if (con->cxt != NULL)
00817             {
00818                 OCI_HandleFree((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX);
00819 
00820                 con->cxt = NULL;
00821             }
00822         }
00823     }
00824     else
00825     {
00826         /* No explicit transaction object => commit if needed otherwise rollback changes */
00827 
00828         if (con->autocom == TRUE)
00829         {
00830              OCI_Commit(con);
00831         }
00832         else
00833         {
00834              OCI_Rollback(con);
00835         }
00836 
00837     #if OCI_VERSION_COMPILE >= OCI_9_2
00838 
00839         if (OCILib.version_runtime >= OCI_9_0)
00840         {
00841             void *ostr = NULL;
00842             int osize  = 0;
00843             ub4 mode   = OCI_DEFAULT;
00844 
00845             /* Clear session tag if connection was retrieved from session pool */
00846 
00847             if ((con->pool != NULL) && (con->sess_tag != NULL) && (con->pool->htype == (ub4) OCI_HTYPE_SPOOL))
00848             {
00849                 osize = -1;
00850                 ostr  = OCI_GetInputMetaString(con->sess_tag, &osize);
00851                 mode  = OCI_SESSRLS_RETAG;
00852             }
00853 
00854             OCI_CALL2
00855             (
00856                 res, con,
00857 
00858                 OCISessionRelease(con->cxt, con->err, (OraText*) ostr, (ub4) osize, mode)
00859             )
00860 
00861             con->cxt = NULL;
00862             con->ses = NULL;
00863             con->svr = NULL;
00864         }
00865 
00866         #endif
00867     }
00868 
00869     /* update internal status */
00870 
00871     if (res == TRUE)
00872     {
00873         con->cstate = OCI_CONN_ATTACHED;
00874 
00875         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00876         {
00877             con->pool->nb_busy--;
00878         }
00879     }
00880 
00881     return res;
00882 }
00883 
00884 /* --------------------------------------------------------------------------------------------- *
00885  * OCI_ConnectionClose
00886  * --------------------------------------------------------------------------------------------- */
00887 
00888 boolean OCI_ConnectionClose
00889 (
00890     OCI_Connection *con
00891 )
00892 {
00893     OCI_CHECK(con == NULL, FALSE);
00894 
00895     /* clear server output resources */
00896 
00897     OCI_ServerDisableOutput(con);
00898 
00899     /* lofoff and detatch form server */
00900 
00901     OCI_ConnectionLogOff(con);
00902     OCI_ConnectionDetach(con);
00903     OCI_ConnectionDeallocate(con);
00904 
00905     /* free internal lists */
00906 
00907     OCI_ListFree(con->stmts);
00908     OCI_ListFree(con->trsns);
00909     OCI_ListFree(con->tinfs);
00910 
00911     /* free strings */
00912 
00913     OCI_FREE(con->fmt_date);
00914     OCI_FREE(con->fmt_num);
00915     OCI_FREE(con->ver_str);
00916     OCI_FREE(con->sess_tag);
00917     OCI_FREE(con->db_name);
00918     OCI_FREE(con->inst_name);
00919     OCI_FREE(con->service_name);
00920     OCI_FREE(con->server_name);
00921     OCI_FREE(con->db_name);
00922     OCI_FREE(con->domain_name);
00923 
00924     if (con->pool == NULL)
00925     {
00926         OCI_FREE(con->db);
00927         OCI_FREE(con->user);
00928         OCI_FREE(con->pwd);
00929     }
00930 
00931     if (con->inst_startup != NULL)
00932     {
00933         OCI_TimestampFree(con->inst_startup);
00934     }
00935 
00936     con->stmts = NULL;
00937     con->trsns = NULL;
00938     con->tinfs = NULL;
00939 
00940     return TRUE;
00941 }
00942 
00943 /* ********************************************************************************************* *
00944  *                             PUBLIC FUNCTIONS
00945  * ********************************************************************************************* */
00946 
00947 /* --------------------------------------------------------------------------------------------- *
00948  * OCI_ConnectionCreate
00949  * --------------------------------------------------------------------------------------------- */
00950 
00951 OCI_Connection * OCI_API OCI_ConnectionCreate
00952 (
00953     const mtext *db,
00954     const mtext *user,
00955     const mtext *pwd,
00956     unsigned int mode
00957 )
00958 {
00959     OCI_Connection * con;
00960 
00961     /* let's be sure OCI_Initialize() has been called */
00962 
00963     OCI_CHECK_INITIALIZED(NULL);
00964 
00965     /* check for XA connections support */
00966 
00967     OCI_CHECK_XA_ENABLED(mode, NULL);
00968 
00969     /* create connection */
00970 
00971     con = OCI_ConnectionAllocate(NULL, db, user, pwd, mode);
00972 
00973     if (con != NULL)
00974     {
00975         if (OCI_ConnectionAttach(con) == FALSE || OCI_ConnectionLogon(con, NULL, NULL) == FALSE)
00976         {
00977             OCI_ConnectionFree(con);
00978             con = NULL;
00979         }
00980     }
00981 
00982     OCI_RESULT(con != NULL);
00983 
00984     return con;
00985 }
00986 
00987 /* --------------------------------------------------------------------------------------------- *
00988  * OCI_ConnectionFree
00989  * --------------------------------------------------------------------------------------------- */
00990 
00991 boolean OCI_API OCI_ConnectionFree
00992 (
00993     OCI_Connection *con
00994 )
00995 {
00996     boolean res    = TRUE;
00997     OCI_Error *err = NULL;
00998 
00999     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01000 
01001     /* clear connection reference from current error object */
01002 
01003     err = OCI_ErrorGet(FALSE, FALSE);
01004 
01005     if (err != NULL && err->con == con)
01006     {
01007         err->con = NULL;
01008     }
01009 
01010     OCI_FREE(con->sess_tag);
01011 
01012     if (con->pool != NULL)
01013     {
01014         res = OCI_ConnectionLogOff(con);
01015 
01016         if (OCILib.version_runtime >= OCI_9_0)
01017         {
01018             OCI_ConnectionDetach(con);
01019         }
01020     }
01021     else
01022     {
01023         res = OCI_ConnectionClose(con);
01024         OCI_ListRemove(OCILib.cons, con);
01025         OCI_FREE(con);
01026     }
01027 
01028     OCI_RESULT(res);
01029 
01030     return res;
01031 }
01032 
01033 /* --------------------------------------------------------------------------------------------- *
01034  * OCI_Commit
01035  * --------------------------------------------------------------------------------------------- */
01036 
01037 boolean OCI_API OCI_Commit
01038 (
01039     OCI_Connection *con
01040 )
01041 {
01042     boolean res = TRUE;
01043 
01044     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01045 
01046     OCI_CALL2
01047     (
01048         res, con,
01049 
01050         OCITransCommit(con->cxt, con->err, (ub4) OCI_DEFAULT)
01051     )
01052 
01053     OCI_RESULT(res);
01054 
01055     return res;
01056 }
01057 
01058 /* --------------------------------------------------------------------------------------------- *
01059  * OCI_Rollback
01060  * --------------------------------------------------------------------------------------------- */
01061 
01062 boolean OCI_API OCI_Rollback
01063 (
01064     OCI_Connection *con
01065 )
01066 {
01067     boolean res = TRUE;
01068 
01069     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01070 
01071     OCI_CALL2
01072     (
01073         res, con,
01074 
01075         OCITransRollback(con->cxt, con->err, (ub4) OCI_DEFAULT)
01076     )
01077 
01078     OCI_RESULT(res);
01079 
01080     return res;
01081 }
01082 
01083 /* --------------------------------------------------------------------------------------------- *
01084  * OCI_SetAutoCommit
01085  * --------------------------------------------------------------------------------------------- */
01086 
01087 boolean OCI_API OCI_SetAutoCommit
01088 (
01089     OCI_Connection *con,
01090     boolean         enable
01091 )
01092 {
01093     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01094 
01095     OCI_RESULT(TRUE);
01096 
01097     con->autocom = enable;
01098 
01099     return TRUE;
01100 }
01101 
01102 /* --------------------------------------------------------------------------------------------- *
01103  * OCI_GetAutoCommit
01104  * --------------------------------------------------------------------------------------------- */
01105 
01106 boolean OCI_API OCI_GetAutoCommit
01107 (
01108     OCI_Connection *con
01109 )
01110 {
01111     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01112 
01113     OCI_RESULT(TRUE);
01114 
01115     return con->autocom;
01116 }
01117 
01118 /* --------------------------------------------------------------------------------------------- *
01119  * OCI_IsConnected
01120  * --------------------------------------------------------------------------------------------- */
01121 
01122 boolean OCI_API OCI_IsConnected
01123 (
01124     OCI_Connection *con
01125 )
01126 {
01127     boolean res = TRUE;
01128     ub4 status  = 0;
01129     ub4 size    = (ub4) sizeof(status);
01130 
01131     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01132 
01133     OCI_CALL2
01134     (
01135         res, con,
01136 
01137         OCIAttrGet((dvoid **) con->svr, (ub4) OCI_HTYPE_SERVER, (dvoid *) &status,
01138                    (ub4 *) &size, (ub4) OCI_ATTR_SERVER_STATUS, con->err)
01139     )
01140 
01141     OCI_RESULT(res);
01142 
01143     return (status == OCI_SERVER_NORMAL);
01144 }
01145 
01146 /* --------------------------------------------------------------------------------------------- *
01147  * OCI_GetUserData
01148  * --------------------------------------------------------------------------------------------- */
01149 
01150 void * OCI_API OCI_GetUserData
01151 (
01152     OCI_Connection *con
01153 )
01154 {
01155     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01156 
01157     OCI_RESULT(TRUE);
01158 
01159     return con->usrdata;
01160 }
01161 
01162 /* --------------------------------------------------------------------------------------------- *
01163  * OCI_SetSetData
01164  * --------------------------------------------------------------------------------------------- */
01165 
01166 boolean OCI_API OCI_SetUserData
01167 (
01168     OCI_Connection *con,
01169     void           *data
01170 )
01171 {
01172     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01173 
01174     OCI_RESULT(TRUE);
01175 
01176     con->usrdata = data;
01177 
01178     return TRUE;
01179 }
01180 
01181 /* --------------------------------------------------------------------------------------------- *
01182  * OCI_SetSessionTag
01183  * --------------------------------------------------------------------------------------------- */
01184 
01185 boolean OCI_API OCI_SetSessionTag
01186 (
01187     OCI_Connection *con,
01188     const mtext    *tag
01189 )
01190 {
01191     boolean res = TRUE;
01192 
01193     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01194 
01195     OCI_RESULT(TRUE);
01196 
01197     OCI_FREE(con->sess_tag);
01198 
01199 #if OCI_VERSION_COMPILE >= OCI_9_2
01200 
01201     if ((tag              != NULL                 ) &&
01202         (con->pool        != NULL                 ) &&
01203         (con->pool->htype == (ub4) OCI_HTYPE_SPOOL))
01204     {
01205         con->sess_tag = mtsdup(tag);
01206 
01207         res = (con->sess_tag != NULL);
01208     }
01209 
01210 #else
01211 
01212     OCI_NOT_USED(tag)
01213 
01214 #endif
01215 
01216     OCI_RESULT(res);
01217 
01218     return res;
01219 }
01220 
01221 /* --------------------------------------------------------------------------------------------- *
01222  * OCI_GetSessionTag
01223  * --------------------------------------------------------------------------------------------- */
01224 
01225 const mtext * OCI_API OCI_GetSessionTag
01226 (
01227     OCI_Connection *con
01228 )
01229 {
01230     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01231 
01232     OCI_RESULT(TRUE);
01233 
01234     return con->sess_tag;
01235 }
01236 
01237 /* --------------------------------------------------------------------------------------------- *
01238  * OCI_GetDatabase
01239  * --------------------------------------------------------------------------------------------- */
01240 
01241 const mtext * OCI_API OCI_GetDatabase
01242 (
01243     OCI_Connection *con
01244 )
01245 {
01246     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01247 
01248     OCI_RESULT(TRUE);
01249 
01250     return (const mtext *) con->db;
01251 }
01252 
01253 /* --------------------------------------------------------------------------------------------- *
01254  * OCI_GetUserName
01255  * --------------------------------------------------------------------------------------------- */
01256 
01257 const mtext * OCI_API OCI_GetUserName
01258 (
01259     OCI_Connection *con
01260 )
01261 {
01262     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01263 
01264     OCI_RESULT(TRUE);
01265 
01266     return (const mtext *) con->user;
01267 }
01268 
01269 /* --------------------------------------------------------------------------------------------- *
01270  * OCI_GetPassword
01271  * --------------------------------------------------------------------------------------------- */
01272 
01273 const mtext * OCI_API OCI_GetPassword
01274 (
01275     OCI_Connection *con
01276 )
01277 {
01278     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01279 
01280     OCI_RESULT(TRUE);
01281 
01282     return (const mtext *) con->pwd;
01283 }
01284 
01285 /* --------------------------------------------------------------------------------------------- *
01286  * OCI_SetPassword
01287  * --------------------------------------------------------------------------------------------- */
01288 
01289 boolean OCI_API OCI_SetPassword
01290 (
01291     OCI_Connection *con,
01292     const mtext    *password
01293 )
01294 {
01295     boolean res = TRUE;
01296 
01297     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01298     OCI_CHECK_PTR(OCI_IPC_STRING, password, FALSE);
01299 
01300     if (con->cstate != OCI_CONN_LOGGED)
01301     {
01302         OCI_ConnectionLogon(con, password, NULL);
01303     }
01304     else
01305     {
01306         int   osize1 = -1;
01307         int   osize2 = -1;
01308         int   osize3 = -1;
01309         void *ostr1  = NULL;
01310         void *ostr2  = NULL;
01311         void *ostr3  = NULL;
01312 
01313         ostr1 = OCI_GetInputMetaString(con->user,  &osize1);
01314         ostr2 = OCI_GetInputMetaString(con->pwd,   &osize2);
01315         ostr3 = OCI_GetInputMetaString(password,   &osize3);
01316 
01317         OCI_CALL2
01318         (
01319             res, con,
01320 
01321             OCIPasswordChange(con->cxt, con->err,
01322                               (OraText *) ostr1, (ub4) osize1,
01323                               (OraText *) ostr2, (ub4) osize2,
01324                               (OraText *) ostr3, (ub4) osize3,
01325                               OCI_DEFAULT)
01326         )
01327 
01328         OCI_ReleaseMetaString(ostr1);
01329         OCI_ReleaseMetaString(ostr2);
01330         OCI_ReleaseMetaString(ostr3);
01331     }
01332 
01333     OCI_RESULT(res);
01334 
01335     return res;
01336 }
01337 
01338 /* --------------------------------------------------------------------------------------------- *
01339  * OCI_SetUserPassword
01340  * --------------------------------------------------------------------------------------------- */
01341 
01342 boolean OCI_API OCI_SetUserPassword
01343 (
01344     const mtext *db,
01345     const mtext *user,
01346     const mtext *pwd,
01347     const mtext *new_pwd
01348 )
01349 {
01350     OCI_Connection * con = NULL;
01351     boolean res = FALSE;
01352 
01353     /* let's be sure OCI_Initialize() has been called */
01354 
01355     OCI_CHECK_INITIALIZED(FALSE);
01356 
01357     con = OCI_ConnectionAllocate(NULL, db, user, pwd, OCI_AUTH);
01358 
01359     if (con != NULL)
01360     {
01361         if (OCI_ConnectionAttach(con) == FALSE || OCI_ConnectionLogon(con, new_pwd, NULL) == FALSE)
01362         {
01363             OCI_ConnectionFree(con);
01364             con = NULL;
01365         }
01366     }
01367 
01368     if (con != NULL)
01369     {
01370         res = TRUE;
01371         OCI_ConnectionFree(con);
01372     }
01373     else
01374     {
01375         res = FALSE;
01376     }
01377 
01378     OCI_RESULT(res);
01379 
01380     return res;
01381 }
01382 
01383 /* --------------------------------------------------------------------------------------------- *
01384  * OCI_GetSessionMode
01385  * --------------------------------------------------------------------------------------------- */
01386 
01387 unsigned int OCI_API OCI_GetSessionMode
01388 (
01389     OCI_Connection *con
01390 )
01391 {
01392     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
01393 
01394     OCI_RESULT(TRUE);
01395 
01396     return con->mode;
01397 }
01398 
01399 /* --------------------------------------------------------------------------------------------- *
01400  * OCI_GetVersionServer
01401  * --------------------------------------------------------------------------------------------- */
01402 
01403 const mtext * OCI_API OCI_GetVersionServer
01404 (
01405     OCI_Connection *con
01406 )
01407 {
01408     boolean res = TRUE;
01409 
01410     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01411 
01412     /* no version available in prelim mode */
01413 
01414     if ((con->ver_str == NULL) && (!(con->mode & OCI_PRELIM_AUTH)))
01415     {
01416         res = FALSE;
01417 
01418         con->ver_str = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
01419                                               (size_t) (OCI_SIZE_BUFFER + 1), FALSE);
01420 
01421         if (con->ver_str != NULL)
01422         {
01423             int osize  = OCI_SIZE_BUFFER * (int) sizeof(mtext);
01424             void *ostr = NULL;
01425 
01426             con->ver_str[0] = 0;
01427 
01428             res = TRUE;
01429 
01430             ostr = OCI_GetInputMetaString(con->ver_str, &osize);
01431 
01432             OCI_CALL2
01433             (
01434                 res, con,
01435 
01436                 OCIServerVersion((dvoid *) con->cxt, con->err, (OraText *) ostr,
01437                                  (ub4) osize, (ub1) OCI_HTYPE_SVCCTX)
01438             )
01439 
01440             OCI_GetOutputMetaString(ostr, con->ver_str, &osize);
01441 
01442             OCI_ReleaseMetaString(ostr);
01443 
01444             if (res == TRUE)
01445             {
01446                 mtext *p = NULL;
01447                 
01448                 int ver_maj, ver_min, ver_rev;
01449 
01450                 ver_maj = ver_min = ver_rev = 0;
01451 
01452                 con->ver_str[osize / (int) sizeof(mtext)] = 0;
01453 
01454                 /* parse server version string to find the version information
01455                  **/
01456 
01457                 for (p = con->ver_str; (p != NULL) && (*p != 0); p++)
01458                 {
01459                     if (mtisdigit((unsigned char) *p) &&
01460                         (*(p + (size_t) 1) != 0) &&
01461                         (*(p + (size_t) 1) == MT('.') || (*(p + (size_t) 2) == MT('.') )))
01462                     {
01463                         if (OCI_NB_ARG_VERSION == mtsscanf(p, MT("%d.%d.%d"),
01464                                                            (int *) &ver_maj,
01465                                                            (int *) &ver_min,
01466                                                            (int *) &ver_rev))
01467                         {
01468                             con->ver_num = ver_maj*100 + ver_min*10 + ver_rev;
01469                         }
01470 
01471                         break;
01472                     }
01473                 }
01474             }
01475             else
01476             {
01477                 OCI_FREE(con->ver_str);
01478             }
01479         }
01480     }
01481 
01482     OCI_RESULT(res);
01483 
01484     return con->ver_str;
01485 }
01486 
01487 /* --------------------------------------------------------------------------------------------- *
01488  * OCI_GetServerMajorVersion
01489  * --------------------------------------------------------------------------------------------- */
01490 
01491 unsigned int OCI_API OCI_GetServerMajorVersion
01492 (
01493     OCI_Connection *con
01494 )
01495 {
01496     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
01497 
01498     if (con->ver_num == OCI_UNKNOWN)
01499     {
01500         OCI_GetVersionServer(con);
01501     }
01502 
01503     OCI_RESULT(con->ver_num != OCI_UNKNOWN);
01504 
01505     return (unsigned int) OCI_VER_MAJ(con->ver_num);
01506 }
01507 
01508 /* --------------------------------------------------------------------------------------------- *
01509  * OCI_GetServerMinorVersion
01510  * --------------------------------------------------------------------------------------------- */
01511 
01512 unsigned int OCI_API OCI_GetServerMinorVersion
01513 (
01514     OCI_Connection *con
01515 )
01516 {
01517     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
01518 
01519     if (con->ver_num == OCI_UNKNOWN)
01520     {
01521         OCI_GetVersionServer(con);
01522     }
01523 
01524     OCI_RESULT(con->ver_num != OCI_UNKNOWN);
01525 
01526     return OCI_VER_MIN(con->ver_num);
01527 }
01528 
01529 /* --------------------------------------------------------------------------------------------- *
01530  * OCI_GetServerRevisionVersion
01531  * --------------------------------------------------------------------------------------------- */
01532 
01533 unsigned int OCI_API OCI_GetServerRevisionVersion
01534 (
01535     OCI_Connection *con
01536 )
01537 {
01538     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
01539 
01540     if (con->ver_num == OCI_UNKNOWN)
01541     {
01542         OCI_GetVersionServer(con);
01543     }
01544 
01545     OCI_RESULT(con->ver_num != OCI_UNKNOWN);
01546 
01547     return (unsigned int) OCI_VER_REV(con->ver_num);
01548 }
01549 
01550 /* --------------------------------------------------------------------------------------------- *
01551  * OCI_GetTransaction
01552  * --------------------------------------------------------------------------------------------- */
01553 
01554 OCI_Transaction * OCI_API OCI_GetTransaction
01555 (
01556     OCI_Connection *con
01557 )
01558 {
01559     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01560 
01561     OCI_RESULT(TRUE);
01562 
01563     return con->trs;
01564 }
01565 
01566 /* --------------------------------------------------------------------------------------------- *
01567  * OCI_SetTransaction
01568  * --------------------------------------------------------------------------------------------- */
01569 
01570 boolean OCI_API OCI_SetTransaction
01571 (
01572     OCI_Connection  *con,
01573     OCI_Transaction *trans
01574 )
01575 {
01576     boolean res = TRUE;
01577 
01578     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01579     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
01580 
01581     if (con->trs != NULL)
01582     {
01583         res = OCI_TransactionStop(con->trs);
01584     }
01585 
01586     if (res == TRUE)
01587     {
01588         con->trs = trans;
01589 
01590         /* set context transaction attribute */
01591 
01592         OCI_CALL2
01593         (
01594             res, con,
01595 
01596             OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
01597                        (dvoid *) con->trs->htr, (ub4) sizeof(con->trs->htr),
01598                        (ub4) OCI_ATTR_TRANS, con->err)
01599         )
01600     }
01601 
01602     OCI_RESULT(res);
01603 
01604     return res;
01605 }
01606 
01607 /* --------------------------------------------------------------------------------------------- *
01608  * OCI_GetVersionConnection
01609  * --------------------------------------------------------------------------------------------- */
01610 
01611 unsigned int OCI_API OCI_GetVersionConnection
01612 (
01613     OCI_Connection *con
01614 )
01615 {
01616     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
01617 
01618     OCI_RESULT(TRUE);
01619 
01620     /* return the minimum supported version */
01621 
01622     return (OCILib.version_runtime > con->ver_num) ? con->ver_num : OCILib.version_runtime;
01623 }
01624 
01625 /* --------------------------------------------------------------------------------------------- *
01626  * OCI_SetDefaultFormatDate
01627  * --------------------------------------------------------------------------------------------- */
01628 
01629 boolean OCI_API OCI_SetDefaultFormatDate
01630 (
01631     OCI_Connection *con,
01632     const mtext    *format
01633 )
01634 {
01635     boolean res = TRUE;
01636 
01637     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01638 
01639     OCI_FREE(con->fmt_date);
01640 
01641     con->fmt_date = mtsdup(format ? format : OCI_STRING_FORMAT_DATE);
01642 
01643     res = (con->fmt_date != NULL);
01644 
01645     OCI_RESULT(res);
01646 
01647     return res;
01648 }
01649 
01650 /* --------------------------------------------------------------------------------------------- *
01651  * OCI_GetDefaultFormatDate
01652  * --------------------------------------------------------------------------------------------- */
01653 
01654 const mtext * OCI_API OCI_GetDefaultFormatDate
01655 (
01656     OCI_Connection *con
01657 )
01658 {
01659     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01660 
01661     OCI_RESULT(TRUE);
01662 
01663     if (con->fmt_date == NULL)
01664     {
01665         OCI_SetDefaultFormatDate(con, NULL);
01666     }
01667 
01668     return (con->fmt_date);
01669 }
01670 
01671 /* --------------------------------------------------------------------------------------------- *
01672  * OCI_SetDefaultFormatNumeric
01673  * --------------------------------------------------------------------------------------------- */
01674 
01675 boolean OCI_API OCI_SetDefaultFormatNumeric
01676 (
01677     OCI_Connection *con,
01678     const mtext    *format
01679 )
01680 {
01681     boolean res = TRUE;
01682 
01683     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01684 
01685     OCI_FREE(con->fmt_num);
01686 
01687     con->fmt_num = mtsdup(format ? format : OCI_STRING_FORMAT_NUM);
01688 
01689     res = (con->fmt_num != NULL);
01690 
01691     OCI_RESULT(res);
01692 
01693     return res;
01694 }
01695 
01696 /* --------------------------------------------------------------------------------------------- *
01697  * OCI_GetDefaultFormatNumeric
01698  * --------------------------------------------------------------------------------------------- */
01699 
01700 const mtext * OCI_API OCI_GetDefaultFormatNumeric
01701 (
01702     OCI_Connection *con
01703 )
01704 {
01705     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01706 
01707     OCI_RESULT(TRUE);
01708 
01709     if (con->fmt_num == NULL)
01710     {
01711         OCI_SetDefaultFormatNumeric(con, NULL);
01712     }
01713 
01714     return (con->fmt_num);
01715 }
01716 
01717 /* --------------------------------------------------------------------------------------------- *
01718  * OCI_Break
01719  * --------------------------------------------------------------------------------------------- */
01720 
01721 boolean OCI_API OCI_Break
01722 (
01723     OCI_Connection *con
01724 )
01725 {
01726     boolean res = TRUE;
01727 
01728     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01729 
01730     OCI_CALL2
01731     (
01732         res, con,
01733 
01734         OCIBreak((dvoid *) con->cxt, con->err)
01735     )
01736 
01737     OCI_RESULT(res);
01738 
01739     return res;
01740 }
01741 
01742 /* --------------------------------------------------------------------------------------------- *
01743  * OCI_ServerEnableOutput
01744  * --------------------------------------------------------------------------------------------- */
01745 
01746 boolean OCI_API OCI_ServerEnableOutput
01747 (
01748     OCI_Connection *con,
01749     unsigned int    bufsize,
01750     unsigned int    arrsize,
01751     unsigned int    lnsize
01752 )
01753 {
01754     boolean res = TRUE;
01755 
01756     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01757 
01758     /* initialize the output buffer on server side */
01759 
01760     if (con->svopt == NULL)
01761     {
01762         con->svopt = (OCI_ServerOutput *) OCI_MemAlloc(OCI_IPC_SERVER_OUPUT, sizeof(*con->svopt),
01763                                                        (size_t) 1, TRUE);
01764 
01765         res = (con->svopt != NULL);
01766     }
01767 
01768     /* allocation internal buffer if needed */
01769 
01770     if ((res == TRUE) && (con->svopt->arrbuf == NULL))
01771     {
01772         unsigned int charsize = sizeof(dtext);
01773 
01774         /* check params ranges ( Oracle 10g increased the size of output line */
01775 
01776         if (con->ver_num >= OCI_10_2)
01777         {
01778             if (lnsize < OCI_OUPUT_LSIZE)
01779             {
01780                 lnsize = OCI_OUPUT_LSIZE;
01781             }
01782             else if (lnsize > OCI_OUPUT_LSIZE_10G)
01783             {
01784                 lnsize = OCI_OUPUT_LSIZE_10G;
01785             }
01786         }
01787         else
01788         {
01789             if (lnsize > OCI_OUPUT_LSIZE)
01790             {
01791                 lnsize = OCI_OUPUT_LSIZE;
01792             }
01793         }
01794 
01795         con->svopt->arrsize = arrsize;
01796         con->svopt->lnsize  = lnsize;
01797 
01798         /* allocate internal string (line) array */
01799 
01800         con->svopt->arrbuf = (ub1 *) OCI_MemAlloc(OCI_IPC_STRING,
01801                                                   ((size_t)(con->svopt->lnsize + 1)) * charsize,
01802                                                   (size_t) con->svopt->arrsize, TRUE);
01803 
01804         res = (con->svopt->arrbuf != NULL);
01805     }
01806 
01807     if (res == TRUE)
01808     {
01809         if (con->svopt->stmt == NULL)
01810         {
01811             con->svopt->stmt = OCI_StatementCreate(con);
01812         }
01813 
01814         if (con->svopt->stmt != NULL)
01815         {
01816             /* enable server ouput */
01817 
01818             res = OCI_Prepare(con->svopt->stmt, MT("BEGIN DBMS_OUTPUT.ENABLE(:n); END;"));
01819 
01820             res = res && OCI_BindUnsignedInt(con->svopt->stmt, MT(":n"), &bufsize);
01821 
01822             if (bufsize == 0)
01823             {
01824                 res = OCI_BindSetNull(OCI_GetBind(con->svopt->stmt, 1));
01825             }
01826 
01827             res = res && OCI_Execute(con->svopt->stmt);
01828 
01829             /* prepare the retreival statement call */
01830 
01831             con->svopt->cursize = con->svopt->arrsize;
01832 
01833             res = res && OCI_Prepare(con->svopt->stmt, MT("BEGIN DBMS_OUTPUT.GET_LINES(:s, :i); END;"));
01834 
01835             res = res && OCI_BindArrayOfStrings(con->svopt->stmt,  MT(":s"),
01836                                                 (dtext *) con->svopt->arrbuf,
01837                                                 con->svopt->lnsize,
01838                                                 con->svopt->arrsize);
01839 
01840             res = res && OCI_BindUnsignedInt(con->svopt->stmt, MT(":i"), &con->svopt->cursize);
01841         }
01842     }
01843 
01844     if (res == FALSE)
01845     {
01846         OCI_ServerDisableOutput(con);
01847     }
01848 
01849     OCI_RESULT(res);
01850 
01851     return res;
01852 }
01853 
01854 /* --------------------------------------------------------------------------------------------- *
01855  * OCI_ServerDisableOutput
01856  * --------------------------------------------------------------------------------------------- */
01857 
01858 boolean OCI_API OCI_ServerDisableOutput
01859 (
01860     OCI_Connection *con
01861 )
01862 {
01863     boolean res = TRUE;
01864 
01865     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01866 
01867     if (con->svopt != NULL)
01868     {
01869         res = res && OCI_ExecuteStmt(con->svopt->stmt, MT("BEGIN DBMS_OUTPUT.DISABLE(); END;"));
01870 
01871         res = res && OCI_StatementFree(con->svopt->stmt);
01872 
01873         OCI_FREE(con->svopt->arrbuf);
01874         OCI_FREE(con->svopt);
01875     }
01876 
01877     OCI_RESULT(res);
01878 
01879     return res;
01880 }
01881 
01882 /* --------------------------------------------------------------------------------------------- *
01883  * OCI_ServerGetOutput
01884  * --------------------------------------------------------------------------------------------- */
01885 
01886 const dtext * OCI_API OCI_ServerGetOutput
01887 (
01888     OCI_Connection *con
01889 )
01890 {
01891     boolean res = TRUE;
01892     dtext *str  = NULL;
01893 
01894     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01895     OCI_CHECK(con->svopt == NULL, FALSE);
01896 
01897     if (con->svopt->curpos == 0 || con->svopt->curpos >= con->svopt->cursize)
01898     {
01899         con->svopt->cursize = con->svopt->arrsize;
01900         res                 = OCI_Execute(con->svopt->stmt);
01901         con->svopt->curpos  = 0;
01902     }
01903 
01904     if ((res == TRUE) && (con->svopt->cursize > 0))
01905     {
01906         unsigned int charsize = sizeof(dtext);
01907 
01908         str = (dtext*) (con->svopt->arrbuf + (size_t) (((con->svopt->lnsize + 1) * charsize) * con->svopt->curpos++));
01909     }
01910 
01911     OCI_RESULT(res);
01912 
01913     return (const dtext *) str;
01914 }
01915 
01916 /* --------------------------------------------------------------------------------------------- *
01917  * OCI_SetTrace
01918  * --------------------------------------------------------------------------------------------- */
01919 
01920 boolean OCI_API OCI_SetTrace
01921 (
01922     OCI_Connection *con,
01923     unsigned int    trace,
01924     const mtext    *value
01925 )
01926 {
01927     boolean res = TRUE;
01928     mtext *str  = NULL;
01929 
01930 #if OCI_VERSION_COMPILE >= OCI_10_1
01931 
01932     ub4 attrib = 0;
01933 
01934 #endif
01935 
01936     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01937 
01938     /* allocate trace info structure only if trace functions are used */
01939 
01940     if (con->trace == NULL)
01941     {
01942         con->trace = (OCI_TraceInfo *) OCI_MemAlloc(OCI_IPC_TRACE_INFO, sizeof(*con->trace),
01943                                                     (size_t) 1, TRUE);
01944         res = (con->trace != NULL);
01945     }
01946 
01947     /* set trace properties */
01948 
01949     if (con->trace != NULL)
01950     {
01951         switch (trace)
01952         {
01953             case OCI_TRC_IDENTITY:
01954             {
01955 
01956             #if OCI_VERSION_COMPILE >= OCI_10_1
01957 
01958                 attrib = OCI_ATTR_CLIENT_IDENTIFIER;
01959 
01960             #endif
01961 
01962                 con->trace->identifier[0] = 0;
01963 
01964                 mtsncat(con->trace->identifier, value, OCI_SIZE_TRACE_ID);
01965 
01966                 str = con->trace->identifier;
01967 
01968                 break;
01969             }
01970             case OCI_TRC_MODULE:
01971             {
01972 
01973             #if OCI_VERSION_COMPILE >= OCI_10_1
01974 
01975                 attrib = OCI_ATTR_MODULE;
01976 
01977             #endif
01978 
01979                 con->trace->module[0] = 0;
01980 
01981                 mtsncat(con->trace->module, value, OCI_SIZE_TRACE_MODULE);
01982 
01983                 str = con->trace->module;
01984 
01985                 break;
01986             }
01987             case OCI_TRC_ACTION:
01988             {
01989 
01990             #if OCI_VERSION_COMPILE >= OCI_10_1
01991 
01992                 attrib = OCI_ATTR_ACTION;
01993 
01994             #endif
01995 
01996                 con->trace->action[0] = 0;
01997 
01998                 mtsncat(con->trace->action, value, OCI_SIZE_TRACE_ACTION);
01999 
02000                 str = con->trace->action;
02001 
02002                 break;
02003             }
02004             case OCI_TRC_DETAIL:
02005             {
02006 
02007             #if OCI_VERSION_COMPILE >= OCI_10_1
02008 
02009                 attrib = OCI_ATTR_CLIENT_INFO;
02010 
02011             #endif
02012 
02013                 con->trace->info[0] = 0;
02014 
02015                 mtsncat(con->trace->info, value,  OCI_SIZE_TRACE_INF0);
02016 
02017                 str = con->trace->info;
02018 
02019                 break;
02020             }
02021             default:
02022             {
02023                 res = FALSE;
02024 
02025                 break;
02026             }
02027         }
02028     }
02029 
02030 #if OCI_VERSION_COMPILE >= OCI_10_1
02031 
02032     /* On success, we give the value to Oracle to record it in system session view */
02033 
02034     if (res == TRUE)
02035     {
02036         void *ostr = NULL;
02037         int osize  = -1;
02038 
02039         ostr = OCI_GetInputMetaString(str, &osize);
02040 
02041         if (str == NULL)
02042         {
02043             osize = 0;
02044         }
02045 
02046         OCI_CALL2
02047         (
02048             res, con,
02049 
02050             OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION,
02051                        (dvoid *) ostr, (ub4) osize, attrib, con->err)
02052         )
02053 
02054         OCI_ReleaseMetaString(ostr);
02055     }
02056 
02057 #endif
02058 
02059     OCI_RESULT(res);
02060 
02061     return res;
02062 }
02063 
02064 /* --------------------------------------------------------------------------------------------- *
02065  * OCI_TraceGet
02066  * --------------------------------------------------------------------------------------------- */
02067 
02068 const mtext * OCI_API OCI_GetTrace
02069 (
02070     OCI_Connection *con,
02071     unsigned int    trace
02072 )
02073 {
02074     const mtext *str = NULL;
02075     boolean res      = TRUE;
02076 
02077     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
02078 
02079     if (con->trace != NULL)
02080     {
02081         switch (trace)
02082         {
02083             case OCI_TRC_IDENTITY:
02084             {
02085                 str = con->trace->identifier;
02086                 break;
02087             }
02088             case OCI_TRC_MODULE:
02089             {
02090                 str = con->trace->module;
02091                 break;
02092             }
02093             case OCI_TRC_ACTION:
02094             {
02095                 str = con->trace->action;
02096                 break;
02097             }
02098             case OCI_TRC_DETAIL:
02099             {
02100                 str = con->trace->info;
02101                 break;
02102             }
02103             default:
02104             {
02105                 res = FALSE;
02106                 break;
02107             }
02108         }
02109     }
02110 
02111     OCI_RESULT(res);
02112 
02113     return str;
02114 }
02115 
02116 /* --------------------------------------------------------------------------------------------- *
02117  * OCI_Ping
02118  * --------------------------------------------------------------------------------------------- */
02119 
02120 boolean OCI_API OCI_Ping
02121 (
02122     OCI_Connection *con
02123 )
02124 {
02125     boolean res = TRUE;
02126     boolean ret = FALSE;
02127 
02128     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02129 
02130 #if OCI_VERSION_COMPILE >= OCI_10_2
02131 
02132     if (OCILib.version_runtime >= OCI_10_2)
02133     {
02134         OCI_CALL2
02135         (
02136             res, con,
02137 
02138             OCIPing(con->cxt, con->err, (ub4) OCI_DEFAULT)
02139 
02140         )
02141 
02142         ret = res;
02143     }
02144 
02145 #endif
02146 
02147     OCI_RESULT(res);
02148 
02149     return ret;
02150 }
02151 
02152 /* --------------------------------------------------------------------------------------------- *
02153  * OCI_GetDBName
02154  * --------------------------------------------------------------------------------------------- */
02155 
02156 const mtext * OCI_API OCI_GetDBName
02157 (
02158     OCI_Connection *con
02159 )
02160 {
02161     boolean res = TRUE;
02162 
02163     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
02164 
02165 #if OCI_VERSION_COMPILE >= OCI_10_2
02166 
02167     if (con->db_name == NULL)
02168     {
02169         res = OCI_StringGetFromAttrHandle(con, con->svr, OCI_HTYPE_SERVER, 
02170                                           OCI_ATTR_DBNAME, &con->db_name);
02171     }
02172 
02173 #endif
02174 
02175     OCI_RESULT(res);
02176 
02177     return con->db_name;
02178 } 
02179 
02180 /* --------------------------------------------------------------------------------------------- *
02181  * OCI_GetInstanceName
02182  * --------------------------------------------------------------------------------------------- */
02183 
02184 const mtext * OCI_API OCI_GetInstanceName
02185 (
02186     OCI_Connection *con
02187 )
02188 {
02189     boolean res = TRUE;
02190 
02191     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
02192 
02193 #if OCI_VERSION_COMPILE >= OCI_10_2
02194 
02195     if (con->inst_name == NULL)
02196     {
02197         res = OCI_StringGetFromAttrHandle(con, con->svr, OCI_HTYPE_SERVER, 
02198                                           OCI_ATTR_INSTNAME, &con->inst_name);
02199     }
02200 
02201 #endif
02202 
02203     OCI_RESULT(res);
02204 
02205     return con->inst_name;
02206 } 
02207 
02208 /* --------------------------------------------------------------------------------------------- *
02209  * OCI_GetServiceName
02210  * --------------------------------------------------------------------------------------------- */
02211 
02212 const mtext * OCI_API OCI_GetServiceName
02213 (
02214     OCI_Connection *con
02215 )
02216 {
02217     boolean res = TRUE;
02218 
02219     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
02220 
02221 #if OCI_VERSION_COMPILE >= OCI_10_2
02222 
02223     if (con->service_name == NULL)
02224     {
02225         res = OCI_StringGetFromAttrHandle(con, con->svr, OCI_HTYPE_SERVER, 
02226                                           OCI_ATTR_SERVICENAME, &con->service_name);
02227     }
02228 
02229 #endif
02230 
02231     OCI_RESULT(res);
02232 
02233     return con->service_name;
02234 } 
02235 
02236 /* --------------------------------------------------------------------------------------------- *
02237  * OCI_GetServerName
02238  * --------------------------------------------------------------------------------------------- */
02239 
02240 const mtext * OCI_API OCI_GetServerName
02241 (
02242     OCI_Connection *con
02243 )
02244 {
02245     boolean res = TRUE;
02246 
02247     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
02248 
02249 #if OCI_VERSION_COMPILE >= OCI_10_2
02250 
02251     if (con->server_name == NULL)
02252     {
02253         res = OCI_StringGetFromAttrHandle(con, con->svr, OCI_HTYPE_SERVER, 
02254                                           OCI_ATTR_HOSTNAME, &con->server_name);
02255     }
02256 
02257 #endif
02258 
02259     OCI_RESULT(res);
02260 
02261     return con->server_name;
02262 } 
02263 
02264 /* --------------------------------------------------------------------------------------------- *
02265  * OCI_GetDomainName
02266  * --------------------------------------------------------------------------------------------- */
02267 
02268 const mtext * OCI_API OCI_GetDomainName
02269 (
02270     OCI_Connection *con
02271 )
02272 {
02273     boolean res = TRUE;
02274 
02275     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
02276 
02277 #if OCI_VERSION_COMPILE >= OCI_10_2
02278 
02279     if (con->domain_name == NULL)
02280     {
02281         res = OCI_StringGetFromAttrHandle(con, con->svr, OCI_HTYPE_SERVER, 
02282                                           OCI_ATTR_DBDOMAIN, &con->domain_name);
02283     }
02284 
02285 #endif
02286 
02287     OCI_RESULT(res);
02288 
02289     return con->domain_name;
02290 } 
02291 
02292 /* --------------------------------------------------------------------------------------------- *
02293  * OCI_GetInstanceStartTime
02294  * --------------------------------------------------------------------------------------------- */
02295 
02296 OCI_Timestamp * OCI_API OCI_GetInstanceStartTime
02297 (
02298     OCI_Connection *con
02299 )
02300 {
02301     boolean res = TRUE;
02302 
02303     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
02304 
02305 #if OCI_VERSION_COMPILE >= OCI_10_2
02306 
02307     if (con->inst_startup == NULL)
02308     {
02309         OCIDateTime *handle = NULL;
02310 
02311         OCI_CALL2
02312         (
02313             res, con,
02314 
02315             OCIAttrGet((dvoid **) con->svr, (ub4) OCI_HTYPE_SERVER, (dvoid *) &handle,
02316                        (ub4 *) NULL,  (ub4) OCI_ATTR_INSTSTARTTIME, con->err)
02317 
02318         )
02319 
02320         if (res == TRUE)
02321         {
02322             res = (OCI_TimestampInit(con, &con->inst_startup, handle, OCI_TIMESTAMP) != NULL);
02323         }
02324     }
02325 
02326 #endif
02327 
02328     OCI_RESULT(res);
02329 
02330     return con->inst_startup;
02331 } 
02332 
02333 /* --------------------------------------------------------------------------------------------- *
02334  * OCI_IsTAFCapable
02335  * --------------------------------------------------------------------------------------------- */
02336 
02337 boolean OCI_API OCI_IsTAFCapable
02338 (
02339     OCI_Connection *con
02340 )
02341 {
02342     boolean res = TRUE;
02343     boolean ret = FALSE;
02344 
02345     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02346     
02347 #if OCI_VERSION_COMPILE >= OCI_10_2
02348 
02349     if (OCILib.version_runtime >= OCI_10_2)
02350     {
02351         OCI_CALL2
02352         (
02353             res, con,
02354 
02355             OCIAttrGet((dvoid **) con->svr, (ub4) OCI_HTYPE_SERVER, (dvoid *) &ret,
02356                        (ub4 *) NULL,  (ub4) OCI_ATTR_TAF_ENABLED, con->err)
02357 
02358         )
02359     }
02360 
02361 #endif
02362 
02363     OCI_RESULT(res);
02364 
02365     return ret;
02366 }
02367 
02368 /* --------------------------------------------------------------------------------------------- *
02369  * OCI_SetTAFHandler
02370  * --------------------------------------------------------------------------------------------- */
02371 
02372 boolean OCI_API OCI_SetTAFHandler
02373 (
02374     OCI_Connection  *con,
02375     POCI_TAF_HANDLER handler
02376 )
02377 {
02378     boolean res = TRUE;
02379     boolean ret = OCI_IsTAFCapable(con);
02380     
02381 #if OCI_VERSION_COMPILE >= OCI_10_2
02382 
02383     if (OCILib.version_runtime >= OCI_10_2)
02384     {
02385         if (ret == TRUE)
02386         {
02387             OCIFocbkStruct fo_struct;
02388         
02389             memset(&fo_struct, 0, sizeof(fo_struct));
02390 
02391             con->taf_handler = handler;
02392 
02393             if (con->taf_handler != NULL)
02394             {
02395                 fo_struct.callback_function = (OCICallbackFailover) OCI_ProcFailOver;
02396                 fo_struct.fo_ctx            = (dvoid *) con;
02397             }
02398 
02399             OCI_CALL2
02400             (
02401                 res, con,
02402 
02403                 OCIAttrSet((dvoid *) con->svr, (ub4) OCI_HTYPE_SERVER, (dvoid *) &fo_struct, (ub4) 0,
02404                            (ub4) OCI_ATTR_FOCBK, con->err)
02405             )
02406         }
02407     }
02408     
02409 #endif
02410     
02411     OCI_RESULT(res);
02412 
02413     return (ret);
02414 }
02415 
02416 /* --------------------------------------------------------------------------------------------- *
02417  * OCI_GetStatementCacheSize
02418  * --------------------------------------------------------------------------------------------- */
02419 
02420 unsigned int OCI_API OCI_GetStatementCacheSize
02421 (
02422     OCI_Connection  *con
02423 )
02424 {
02425     boolean res        = TRUE;
02426     ub4     cache_size = 0;
02427 
02428     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, 0);
02429     
02430 #if OCI_VERSION_COMPILE >= OCI_9_2
02431 
02432     if (OCILib.version_runtime >= OCI_9_2)
02433     {
02434 
02435         OCI_CALL2
02436         (
02437             res, con,
02438 
02439             OCIAttrGet((dvoid **) con->cxt, (ub4) OCI_HTYPE_SVCCTX, (dvoid *) &cache_size,
02440                         (ub4 *) NULL,  (ub4) OCI_ATTR_STMTCACHESIZE, con->err)
02441         )
02442     }
02443 
02444 #endif
02445 
02446     OCI_RESULT(res);
02447 
02448     return cache_size;
02449 }
02450 
02451 /* --------------------------------------------------------------------------------------------- *
02452  * OCI_SetStatementCacheSize
02453  * --------------------------------------------------------------------------------------------- */
02454 
02455 boolean OCI_API OCI_SetStatementCacheSize
02456 (
02457     OCI_Connection  *con,
02458     unsigned int     value
02459 )
02460 {
02461     boolean res        = TRUE;
02462     ub4     cache_size = value;
02463 
02464     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02465     
02466 #if OCI_VERSION_COMPILE >= OCI_9_2
02467 
02468     if (OCILib.version_runtime >= OCI_9_2)
02469     {
02470         OCI_CALL2
02471         (
02472             res, con,
02473 
02474             OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
02475                         (dvoid *) &cache_size, (ub4) sizeof (cache_size),
02476                         (ub4) OCI_ATTR_STMTCACHESIZE, con->err)
02477         )
02478     }
02479 
02480 #else
02481 
02482     OCI_NOT_USED(cache_size);
02483 
02484 #endif
02485 
02486     OCI_RESULT(res);
02487 
02488     return res;
02489 }
02490 
02491 /* --------------------------------------------------------------------------------------------- *
02492  * OCI_GetDefaultLobPrefetchSize
02493  * --------------------------------------------------------------------------------------------- */
02494 
02495 OCI_EXPORT unsigned int OCI_API OCI_GetDefaultLobPrefetchSize
02496 (
02497     OCI_Connection *con
02498 )
02499 {
02500     boolean res           = TRUE;
02501     ub4     prefetch_size = 0;
02502 
02503     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, 0);
02504     
02505 #if OCI_VERSION_COMPILE >= OCI_11_1
02506 
02507     if (con->ver_num >= OCI_11_1)
02508     {
02509 
02510         OCI_CALL2
02511         (
02512             res, con,
02513 
02514             OCIAttrGet((dvoid **) con->ses, (ub4) OCI_HTYPE_SESSION, (dvoid *) &prefetch_size,
02515                         (ub4 *) NULL,  (ub4) OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE, con->err)
02516         )
02517     }
02518 
02519 #endif
02520 
02521     OCI_RESULT(res);
02522 
02523     return prefetch_size;
02524 }
02525 
02526 /* --------------------------------------------------------------------------------------------- *
02527  * OCI_SetDefaultLobPrefetchSize
02528  * --------------------------------------------------------------------------------------------- */
02529 
02530 OCI_EXPORT boolean OCI_API OCI_SetDefaultLobPrefetchSize
02531 (
02532     OCI_Connection *con,
02533     unsigned int     value
02534 )
02535 {
02536     boolean res           = TRUE;
02537     ub4     prefetch_size = value;
02538 
02539     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
02540     
02541 #if OCI_VERSION_COMPILE >= OCI_11_1
02542 
02543     if (con->ver_num >= OCI_11_1)
02544     {
02545         OCI_CALL2
02546         (
02547             res, con,
02548 
02549             OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION,
02550                         (dvoid *) &prefetch_size, (ub4) sizeof (prefetch_size),
02551                         (ub4) OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE, con->err)
02552         )
02553     }
02554 
02555 #else
02556 
02557     OCI_NOT_USED(prefetch_size);
02558 
02559 #endif
02560 
02561     OCI_RESULT(res);
02562 
02563     return res;
02564 }
02565