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