C:/Users/vincent/Data/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    +----------------------------------------------------------------------+
00009    |                      Website : http://www.ocilib.net                 |
00010    +----------------------------------------------------------------------+
00011    |               Copyright (c) 2007-2009 Vincent ROGIER                 |
00012    +----------------------------------------------------------------------+
00013    | This library is free software; you can redistribute it and/or        |
00014    | modify it under the terms of the GNU Lesser General Public           |
00015    | License as published by the Free Software Foundation; either         |
00016    | version 2 of the License, or (at your option) any later version.     |
00017    |                                                                      |
00018    | This library is distributed in the hope that it will be useful,      |
00019    | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
00020    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
00021    | Lesser General Public License for more details.                      |
00022    |                                                                      |
00023    | You should have received a copy of the GNU Lesser General Public     |
00024    | License along with this library; if not, write to the Free           |
00025    | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   |
00026    +----------------------------------------------------------------------+
00027    |          Author: Vincent ROGIER <vince.rogier@gmail.com>             |
00028    +----------------------------------------------------------------------+
00029 */
00030 
00031 /* ------------------------------------------------------------------------ *
00032  * $Id: connection.c, v 3.4.0 2009-07-30 17:40 Vince $
00033  * ------------------------------------------------------------------------ */
00034 
00035 #include "ocilib_internal.h"
00036 
00037 
00038 /* ************************************************************************ *
00039  *                             PRIVATE FUNCTIONS
00040  * ************************************************************************ */
00041 
00042 /* ------------------------------------------------------------------------ *
00043  * OCI_ConnectionAllocate
00044  * ------------------------------------------------------------------------ */
00045 
00046 OCI_Connection * OCI_ConnectionAllocate(OCI_ConnPool *pool, const mtext *db,
00047                                         const mtext *user,  const mtext *pwd,
00048                                         unsigned int mode)
00049 {
00050     OCI_Connection *con = NULL;
00051     OCI_List *list      = NULL;
00052     OCI_Item *item      = NULL;
00053     boolean res         = TRUE;
00054 
00055     /* create connection object */
00056 
00057     if (pool != NULL)
00058         list  = pool->cons;
00059     else
00060         list  = OCILib.cons;
00061 
00062     item = OCI_ListAppend(list, sizeof(*con));
00063 
00064     if (item != NULL)
00065     {
00066         con = (OCI_Connection *) item->data;
00067 
00068         /* create internal lists */
00069 
00070         con->stmts = OCI_ListCreate(OCI_IPC_STATEMENT);
00071 
00072         if (res == TRUE)
00073         {
00074             con->tinfs = OCI_ListCreate(OCI_IPC_TYPE_INFO);
00075             res = (con->tinfs != NULL);
00076         }
00077 
00078         if (res == TRUE)
00079         {
00080             con->trsns = OCI_ListCreate(OCI_IPC_TRANSACTION);
00081             res = (con->trsns != NULL);
00082         }
00083 
00084         /* set attributes */
00085 
00086         if (res == TRUE)
00087         {
00088             con->mode = mode;
00089             con->pool = pool;
00090 
00091             if (con->pool != NULL)
00092             {
00093                 con->db     = (mtext *) db;
00094                 con->user   = (mtext *) user;
00095                 con->pwd    = (mtext *) pwd;
00096             }
00097             else
00098             {
00099                 con->db   = mtsdup(db   != NULL ? db   : MT(""));
00100                 con->user = mtsdup(user != NULL ? user : MT(""));
00101                 con->pwd  = mtsdup(pwd  != NULL ? pwd  : MT(""));
00102             }
00103         }
00104 
00105         /*  allocate error handle */
00106 
00107         if (res == TRUE)
00108             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
00109                                                   (dvoid **) (void *) &con->err,
00110                                                   (ub4) OCI_HTYPE_ERROR,
00111                                                   (size_t) 0, (dvoid **) NULL));
00112 
00113         /* allocate server handle */
00114 
00115         if (res == TRUE)
00116             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
00117                                                   (dvoid **) (void *) &con->svr,
00118                                                   (ub4) OCI_HTYPE_SERVER,
00119                                                   (size_t) 0, (dvoid **) NULL));
00120 
00121         /* allocate context handle */
00122 
00123         if (res == TRUE)
00124             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
00125                                                   (dvoid **) (void *) &con->cxt,
00126                                                   (ub4) OCI_HTYPE_SVCCTX,
00127                                                   (size_t) 0, (dvoid **) NULL));
00128 
00129         /* allocate session handle */
00130 
00131         if (res == TRUE)
00132             res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
00133                                                   (dvoid **) (void *) &con->ses,
00134                                                   (ub4) OCI_HTYPE_SESSION,
00135                                                   (size_t) 0, (dvoid **) NULL));
00136     }
00137     else
00138         res = FALSE;
00139 
00140    /* update internal status */
00141 
00142     if (res == TRUE)
00143     {
00144         con->cstate = OCI_CONN_ALLOCATED;
00145     }
00146     else
00147     {
00148         OCI_ConnectionFree(con);
00149         con = NULL;
00150     }
00151 
00152     return con;
00153 }
00154 
00155 /* ------------------------------------------------------------------------ *
00156  * OCI_ConnectionDeallocate
00157  * ------------------------------------------------------------------------ */
00158 
00159 boolean OCI_ConnectionDeallocate(OCI_Connection *con)
00160 {
00161     OCI_CHECK(con == NULL, FALSE);
00162     OCI_CHECK(con->cstate != OCI_CONN_ALLOCATED, FALSE);
00163 
00164     /* close context handle */
00165 
00166     if (con->cxt != NULL)
00167        OCI_HandleFree((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX);
00168 
00169     /* close session handle */
00170 
00171     if (con->ses != NULL)
00172         OCI_HandleFree((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION);
00173 
00174     /* close server handle */
00175     if (con->svr != NULL)
00176         OCI_HandleFree((dvoid *) con->svr, (ub4) OCI_HTYPE_SERVER);
00177 
00178      /* close error handle */
00179 
00180     if (con->err != NULL)
00181         OCI_HandleFree((dvoid *) con->err, (ub4) OCI_HTYPE_ERROR);
00182 
00183     con->cxt = NULL;
00184     con->ses = NULL;
00185     con->svr = NULL;
00186     con->err = NULL;
00187 
00188     return TRUE;
00189 }
00190 
00191 /* ------------------------------------------------------------------------ *
00192  * OCI_ConnectionAttach
00193  * ------------------------------------------------------------------------ */
00194 
00195 boolean OCI_ConnectionAttach(OCI_Connection *con)
00196 {
00197     void *ostr  = NULL;
00198     int osize   = -1;
00199     boolean res = TRUE;
00200     ub4 cmode   = OCI_DEFAULT;
00201 
00202     OCI_CHECK(con == NULL, FALSE);
00203     OCI_CHECK(con->cstate != OCI_CONN_ALLOCATED, FALSE);
00204 
00205     /* attach server handle to service name */
00206 
00207 #if OCI_VERSION_COMPILE >= OCI_9_0
00208 
00209     if (OCILib.version_runtime >= OCI_9_0 && con->pool != NULL)
00210     {
00211         ostr  = OCI_GetInputMetaString(con->pool->name, &osize);
00212         cmode = OCI_CPOOL;
00213     }
00214     else
00215 
00216 #endif
00217 
00218     {
00219         ostr  = OCI_GetInputMetaString(con->db, &osize);
00220     }
00221 
00222     OCI_CALL2
00223     (
00224         res, con,
00225 
00226         OCIServerAttach(con->svr, con->err,(OraText *) ostr, (sb4) osize, cmode)
00227     )
00228 
00229     OCI_ReleaseMetaString(ostr);
00230 
00231     /* handle errors */
00232 
00233     if (res == TRUE)
00234     {
00235         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00236             con->pool->nb_opened++;
00237 
00238         con->cstate = OCI_CONN_ATTACHED;
00239     }
00240 
00241     return res;
00242 }
00243 
00244 /* ------------------------------------------------------------------------ *
00245  * OCI_ConnectionDetach
00246  * ------------------------------------------------------------------------ */
00247 
00248 boolean OCI_ConnectionDetach(OCI_Connection *con)
00249 {
00250     boolean res = TRUE;
00251 
00252     OCI_CHECK(con == NULL, FALSE);
00253     OCI_CHECK(con->cstate != OCI_CONN_ATTACHED, FALSE);
00254 
00255     /* detach from the oracle server */
00256 
00257     OCI_CALL2
00258     (
00259         res, con,
00260 
00261         OCIServerDetach(con->svr, con->err, (ub4) OCI_DEFAULT)
00262     )
00263 
00264    /* update internal status */
00265 
00266     if (res == TRUE)
00267     {
00268         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00269             con->pool->nb_opened--;
00270 
00271         con->cstate = OCI_CONN_ALLOCATED;
00272     }
00273 
00274     return res;
00275 }
00276 
00277 /* ------------------------------------------------------------------------ *
00278  * OCI_ConnectionLogon
00279  * ------------------------------------------------------------------------ */
00280 
00281 boolean OCI_ConnectionLogon(OCI_Connection *con)
00282 {
00283     void *ostr  = NULL;
00284     int osize   = -1;
00285     boolean res = TRUE;
00286 
00287     OCI_CHECK(con == NULL, FALSE);
00288 
00289     /* set context server attribute */
00290 
00291     OCI_CALL2
00292     (
00293         res, con,
00294 
00295         OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00296                    (dvoid *) con->svr, (ub4) sizeof (con->svr),
00297                    (ub4) OCI_ATTR_SERVER, con->err)
00298     )
00299 
00300     /* set session login attribute */
00301 
00302     if ((res == TRUE) && (con->user != NULL) && (con->user[0] != 0))
00303     {
00304         osize = -1;
00305         ostr  = OCI_GetInputMetaString(con->user, &osize);
00306 
00307         OCI_CALL2
00308         (
00309             res, con,
00310 
00311             OCIAttrSet((dvoid *) con->ses,(ub4)  OCI_HTYPE_SESSION,
00312                        (dvoid *) ostr, (ub4) osize,
00313                        (ub4) OCI_ATTR_USERNAME, con->err)
00314         )
00315 
00316         OCI_ReleaseMetaString(ostr);
00317     }
00318 
00319     /* set session password attribute */
00320 
00321     if ((res == TRUE) && (con->pwd != NULL) && (con->pwd[0] != 0))
00322     {
00323         osize = -1;
00324         ostr  = OCI_GetInputMetaString(con->pwd, &osize);
00325 
00326         OCI_CALL2
00327         (
00328             res, con,
00329 
00330             OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION,
00331                        (dvoid *) ostr, (ub4) osize,
00332                        (ub4) OCI_ATTR_PASSWORD, con->err)
00333         )
00334 
00335         OCI_ReleaseMetaString(ostr);
00336     }
00337 
00338     /* start session */
00339 
00340     if (res == TRUE)
00341     {
00342         ub4 credt = OCI_CRED_RDBMS;
00343 
00344         if  (((con->user == NULL) || (con->user[0] == 0)) &&
00345              ((con->pwd  == NULL) || (con->pwd[0]  == 0)))
00346         {
00347             credt = OCI_CRED_EXT;
00348         }
00349 
00350         OCI_CALL2
00351         (
00352             res, con,
00353 
00354             OCISessionBegin(con->cxt, con->err, con->ses, credt, con->mode)
00355         )
00356 
00357        /* This call has moved after OCISessionBegin() call to enable connection
00358           pooling (an error ORA-24324 was thrown is the session handle was set to
00359           the service context handle before OCISessionBegin() */
00360 
00361         OCI_CALL2
00362         (
00363             res, con,
00364 
00365             OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX,
00366                        (dvoid *) con->ses, (ub4) sizeof(con->ses),
00367                        (ub4) OCI_ATTR_SESSION, con->err))
00368 
00369     }
00370 
00371     /* check for success */
00372 
00373     if (res == TRUE)
00374     {
00375         /* get server version */
00376 
00377         OCI_GetVersionServer(con);
00378 
00379         if (!(con->mode & OCI_PRELIM_AUTH))
00380         {
00381             /* create default transaction object */
00382     
00383             con->trs  = OCI_TransactionCreate(con, 1, OCI_TRANS_READWRITE, NULL);
00384 
00385             /* start transaction */
00386 
00387             res = OCI_TransactionStart(con->trs);
00388         }
00389     }
00390 
00391     /* set OCILIB's driver layer name attribute */
00392 
00393 #if OCI_VERSION_COMPILE >= OCI_11_1
00394 
00395     if ((res == TRUE) && (OCILib.version_runtime >= OCI_11_1) && (con->ver_num >= OCI_11_1))
00396     {
00397         osize = -1;
00398         ostr  = OCI_GetInputMetaString(OCILIB_DRIVER_NAME, &osize);
00399 
00400         OCI_CALL2
00401         (
00402             res, con,
00403 
00404             OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION,
00405                        (dvoid *) ostr, (ub4) osize,
00406                        (ub4) OCI_ATTR_DRIVER_NAME, con->err)
00407         )
00408 
00409         OCI_ReleaseMetaString(ostr);
00410     }
00411 
00412 #endif
00413 
00414 
00415    /* update internal status */
00416 
00417     if (res == TRUE)
00418     {
00419         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00420             con->pool->nb_busy++;
00421 
00422         con->cstate = OCI_CONN_LOGGED;
00423     }
00424 
00425     return res;
00426 }
00427 
00428 /* ------------------------------------------------------------------------ *
00429  * OCI_ConnectionLogOff
00430  * ------------------------------------------------------------------------ */
00431 
00432 boolean OCI_ConnectionLogOff(OCI_Connection *con)
00433 {
00434     boolean res = TRUE;
00435 
00436     OCI_CHECK(con == NULL, FALSE);
00437     OCI_CHECK(con->cstate != OCI_CONN_LOGGED, FALSE);
00438 
00439     /* free all statements */
00440 
00441     OCI_ListForEach(con->stmts, (boolean (*)(void *)) OCI_StatementClose);
00442     OCI_ListClear(con->stmts);
00443 
00444     /* cleanup the cache */
00445 
00446     OCI_CALL2
00447     (
00448         res, con,
00449 
00450         OCICacheFree(OCILib.env, con->err, con->cxt)
00451     )
00452 
00453     /* free all transactions */
00454 
00455     OCI_ListForEach(con->trsns, (boolean (*)(void *)) OCI_TransactionClose);
00456     OCI_ListClear(con->trsns);
00457 
00458     /* free all type info objects */
00459 
00460     OCI_ListForEach(con->tinfs, (boolean (*)(void *)) OCI_TypeInfoClose);
00461     OCI_ListClear(con->tinfs);
00462 
00463    /* close any server files not explicitly closed - no check of return code */
00464 
00465     if (con->nb_files > 0)
00466     {
00467         OCILobFileCloseAll(con->cxt, con->err);
00468     }
00469 
00470     /* close session */
00471 
00472     if ((con->cxt != NULL) && (con->err != NULL) && (con->ses != NULL))
00473     {
00474          OCI_CALL2
00475          (
00476             res, con,
00477 
00478             OCISessionEnd(con->cxt, con->err, con->ses, (ub4) OCI_DEFAULT)
00479          )
00480     }
00481 
00482     /* update internal status */
00483 
00484     if (res == TRUE)
00485     {
00486         con->cstate = OCI_CONN_ATTACHED;
00487 
00488         if (OCILib.version_runtime < OCI_9_0 && con->pool != NULL)
00489             con->pool->nb_busy--;
00490     }
00491 
00492     return res;
00493 }
00494 
00495 /* ------------------------------------------------------------------------ *
00496  * OCI_ConnectionClose
00497  * ------------------------------------------------------------------------ */
00498 
00499 boolean OCI_ConnectionClose(OCI_Connection *con)
00500 {
00501     OCI_CHECK(con == NULL, FALSE);
00502 
00503     /* clear server output resources */
00504 
00505     OCI_ServerDisableOutput(con);
00506 
00507     /* lofoff and detatch form server */
00508 
00509     OCI_ConnectionLogOff(con);
00510     OCI_ConnectionDetach(con);
00511     OCI_ConnectionDeallocate(con);
00512 
00513     /* free internal lists */
00514 
00515     OCI_ListFree(con->stmts);
00516     OCI_ListFree(con->trsns);
00517     OCI_ListFree(con->tinfs);
00518 
00519     if (con->pool == NULL)
00520     {
00521         /* free strings */
00522 
00523         OCI_FREE(con->db);
00524         OCI_FREE(con->user);
00525         OCI_FREE(con->pwd);
00526     }
00527 
00528 
00529     OCI_FREE(con->fmt_date);
00530     OCI_FREE(con->fmt_num);
00531     OCI_FREE(con->ver_str);
00532 
00533     con->stmts = NULL;
00534     con->trsns = NULL;
00535     con->tinfs = NULL;
00536 
00537     return TRUE;
00538 }
00539 
00540 /* ************************************************************************ *
00541  *                             PUBLIC FUNCTIONS
00542  * ************************************************************************ */
00543 
00544 /* ------------------------------------------------------------------------ *
00545  * OCI_ConnectionCreate
00546  * ------------------------------------------------------------------------ */
00547 
00548 OCI_Connection * OCI_API OCI_ConnectionCreate(const mtext *db,
00549                                               const mtext *user,
00550                                               const mtext *pwd,
00551                                               unsigned int mode)
00552 {
00553     OCI_Connection * con;
00554 
00555     /* let's be sure OCI_Initialize() has been called */
00556 
00557     OCI_CHECK_INITIALIZED(NULL);
00558 
00559     con = OCI_ConnectionAllocate(NULL, db, user, pwd, mode);
00560 
00561     if (con != NULL)
00562     {
00563         if (OCI_ConnectionAttach(con) == FALSE ||
00564             OCI_ConnectionLogon(con)  == FALSE)
00565         {
00566             OCI_ConnectionFree(con);
00567             con = NULL;
00568         }
00569     }
00570 
00571     OCI_RESULT(con != NULL);
00572 
00573     return con;
00574 }
00575 
00576 /* ------------------------------------------------------------------------ *
00577  * OCI_ConnectionFree
00578  * ------------------------------------------------------------------------ */
00579 
00580 boolean OCI_API OCI_ConnectionFree(OCI_Connection *con)
00581 {
00582     boolean res    = TRUE;
00583     OCI_Error *err = NULL;
00584 
00585     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00586 
00587     /* clear connection reference from current error object */
00588 
00589     err = OCI_ErrorGet(FALSE);
00590 
00591     if (err != NULL && err->con == con)
00592         err->con = NULL;
00593 
00594     if (con->pool != NULL)
00595     {
00596         res = OCI_ConnectionLogOff(con);
00597 
00598         if (OCILib.version_runtime >= OCI_9_0)
00599             OCI_ConnectionDetach(con);
00600     }
00601     else
00602     {
00603         res = OCI_ConnectionClose(con);
00604         OCI_ListRemove(OCILib.cons, con);
00605         OCI_FREE(con);
00606     }
00607 
00608     OCI_RESULT(res);
00609 
00610     return res;
00611 }
00612 
00613 /* ------------------------------------------------------------------------ *
00614  * OCI_Commit
00615  * ------------------------------------------------------------------------ */
00616 
00617 boolean OCI_API OCI_Commit(OCI_Connection *con)
00618 {
00619     boolean res = TRUE;
00620 
00621     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00622 
00623     OCI_CALL2
00624     (
00625         res, con,
00626 
00627         OCITransCommit(con->cxt, con->err, (ub4) OCI_DEFAULT)
00628     )
00629 
00630     OCI_RESULT(res);
00631 
00632     return res;
00633 }
00634 
00635 /* ------------------------------------------------------------------------ *
00636  * OCI_Rollback
00637  * ------------------------------------------------------------------------ */
00638 
00639 boolean OCI_API OCI_Rollback(OCI_Connection *con)
00640 {
00641     boolean res = TRUE;
00642 
00643     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00644 
00645     OCI_CALL2
00646     (
00647         res, con,
00648 
00649         OCITransRollback(con->cxt, con->err, (ub4) OCI_DEFAULT)
00650     )
00651 
00652     OCI_RESULT(res);
00653 
00654     return res;
00655 }
00656 
00657 /* ------------------------------------------------------------------------ *
00658  * OCI_SetAutoCommit
00659  * ------------------------------------------------------------------------ */
00660 
00661 boolean OCI_API OCI_SetAutoCommit(OCI_Connection *con, boolean enable)
00662 {
00663     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00664 
00665     OCI_RESULT(TRUE);
00666 
00667     con->autocom = enable;
00668 
00669     return TRUE;
00670 }
00671 
00672 /* ------------------------------------------------------------------------ *
00673  * OCI_GetAutoCommit
00674  * ------------------------------------------------------------------------ */
00675 
00676 boolean OCI_API OCI_GetAutoCommit(OCI_Connection *con)
00677 {
00678     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00679 
00680     OCI_RESULT(TRUE);
00681 
00682     return con->autocom;
00683 }
00684 
00685 /* ------------------------------------------------------------------------ *
00686  * OCI_IsConnected
00687  * ------------------------------------------------------------------------ */
00688 
00689 boolean OCI_API OCI_IsConnected(OCI_Connection *con)
00690 {
00691     boolean res = TRUE;
00692     ub4 status  = 0;
00693 
00694     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00695 
00696     OCI_CALL2
00697     (
00698         res, con,
00699 
00700         OCIAttrGet((dvoid **) con->svr, (ub4) OCI_HTYPE_SERVER,
00701                    (dvoid *) &status, (ub4 *) NULL,
00702                    (ub4) OCI_ATTR_SERVER_STATUS, con->err)
00703 
00704     )
00705 
00706     OCI_RESULT(res);
00707 
00708     return (status == OCI_SERVER_NORMAL);
00709 }
00710 
00711 /* ------------------------------------------------------------------------ *
00712  * OCI_GetUserData
00713  * ------------------------------------------------------------------------ */
00714 
00715 void * OCI_API OCI_GetUserData(OCI_Connection *con)
00716 {
00717     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00718 
00719     OCI_RESULT(TRUE);
00720 
00721     return con->usrdata;
00722 }
00723 
00724 /* ------------------------------------------------------------------------ *
00725  * OCI_SetSetData
00726  * ------------------------------------------------------------------------ */
00727 
00728 boolean OCI_API OCI_SetUserData(OCI_Connection *con, void * data)
00729 {
00730     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00731 
00732     OCI_RESULT(TRUE);
00733 
00734     con->usrdata = data;
00735 
00736     return TRUE;
00737 }
00738 
00739 /* ------------------------------------------------------------------------ *
00740  * OCI_GetDatabase
00741  * ------------------------------------------------------------------------ */
00742 
00743 const mtext * OCI_API OCI_GetDatabase(OCI_Connection *con)
00744 {
00745     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00746 
00747     OCI_RESULT(TRUE);
00748 
00749     return (const mtext *) con->db;
00750 }
00751 
00752 /* ------------------------------------------------------------------------ *
00753  * OCI_GetUserName
00754  * ------------------------------------------------------------------------ */
00755 
00756 const mtext * OCI_API OCI_GetUserName(OCI_Connection *con)
00757 {
00758     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00759 
00760     OCI_RESULT(TRUE);
00761 
00762     return (const mtext *) con->user;
00763 }
00764 
00765 /* ------------------------------------------------------------------------ *
00766  * OCI_GetPassword
00767  * ------------------------------------------------------------------------ */
00768 
00769 const mtext * OCI_API OCI_GetPassword(OCI_Connection *con)
00770 {
00771     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00772 
00773     OCI_RESULT(TRUE);
00774 
00775     return (const mtext *) con->pwd;
00776 }
00777 
00778 /* ------------------------------------------------------------------------ *
00779  * OCI_SetPassword
00780  * ------------------------------------------------------------------------ */
00781 
00782 boolean OCI_API OCI_SetPassword(OCI_Connection *con, const mtext *password)
00783 {
00784     boolean res = TRUE;
00785 
00786     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00787     OCI_CHECK_PTR(OCI_IPC_STRING, password, FALSE);
00788 
00789     OCI_CALL2
00790     (
00791         res, con,
00792 
00793         OCIPasswordChange(con->cxt, con->err,
00794                           (OraText *) con->user, (ub4) mtextsize(con->user),
00795                           (OraText *) con->pwd,  (ub4) mtextsize(con->pwd),
00796                           (OraText *) password,  (ub4) mtextsize(password),
00797                           (ub4) OCI_DEFAULT)
00798     )
00799 
00800     OCI_RESULT(res);
00801 
00802     return res;
00803 }
00804 
00805 /* ------------------------------------------------------------------------ *
00806  * OCI_GetSessionMode
00807  * ------------------------------------------------------------------------ */
00808 
00809 unsigned int OCI_API OCI_GetSessionMode(OCI_Connection *con)
00810 {
00811     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
00812 
00813     OCI_RESULT(TRUE);
00814 
00815     return con->mode;
00816 }
00817 
00818 /* ------------------------------------------------------------------------ *
00819  * OCI_GetVersionServer
00820  * ------------------------------------------------------------------------ */
00821 
00822 const mtext * OCI_API OCI_GetVersionServer(OCI_Connection *con)
00823 {
00824     boolean res = TRUE;
00825 
00826     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00827 
00828     /* no version available in prelim mode */
00829 
00830     if ((con->ver_str == NULL) && (!(con->mode & OCI_PRELIM_AUTH)))
00831     {
00832         res = FALSE;
00833 
00834         con->ver_str = (mtext *) OCI_MemAlloc(OCI_IPC_STRING, sizeof(mtext),
00835                                               OCI_SIZE_BUFFER + 1, FALSE);
00836 
00837         if (con->ver_str != NULL)
00838         {
00839             int osize  = OCI_SIZE_BUFFER * sizeof(mtext);
00840             void *ostr = NULL;
00841             mtext *p   = NULL;
00842 
00843             con->ver_str[0] = 0;
00844 
00845             res  = TRUE;
00846 
00847             ostr = OCI_GetInputMetaString(con->ver_str, &osize);
00848 
00849             OCI_CALL2
00850             (
00851                 res, con,
00852 
00853                 OCIServerVersion((dvoid *) con->cxt, con->err,
00854                                  (OraText *) ostr, (ub4) osize,
00855                                  (ub1) OCI_HTYPE_SVCCTX)
00856             )
00857 
00858             OCI_GetOutputMetaString(ostr, con->ver_str, &osize);
00859 
00860             OCI_ReleaseMetaString(ostr);
00861 
00862             if (res == TRUE)
00863             {
00864                 int ver_maj, ver_min, ver_rev;
00865 
00866                 ver_maj = ver_min = ver_rev = 0;
00867 
00868                 con->ver_str[osize / sizeof(mtext)] = 0;
00869 
00870                 /* parse server version string to find the version information */
00871 
00872                 for (p = con->ver_str; (p != NULL) && (*p != 0); p++)
00873                 {
00874                     if (mtisdigit(*p) &&
00875                         (*(p+1) != 0) &&
00876                         (*(p+1) == MT('.') || (*(p+2) == MT('.') )))
00877                     {
00878                         if (OCI_NB_ARG_VERSION == mtsscanf(p, MT("%d.%d.%d"),
00879                                                            (int *) &ver_maj,
00880                                                            (int *) &ver_min,
00881                                                            (int *) &ver_rev))
00882                         {
00883                             con->ver_num = ver_maj*100 + ver_min*10 + ver_rev;
00884                         }
00885 
00886                         break;
00887                     }
00888                 }
00889             }
00890             else
00891                 OCI_FREE(con->ver_str);
00892         }
00893     }
00894 
00895     OCI_RESULT(res);
00896 
00897     return con->ver_str;
00898 }
00899 
00900 /* ------------------------------------------------------------------------ *
00901  * OCI_GetServerMajorVersion
00902  * ------------------------------------------------------------------------ */
00903 
00904 unsigned int OCI_API OCI_GetServerMajorVersion(OCI_Connection *con)
00905 {
00906     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
00907 
00908     if (con->ver_num == OCI_UNKNOWN)
00909         OCI_GetVersionServer(con);
00910 
00911     OCI_RESULT(con->ver_num != OCI_UNKNOWN);
00912 
00913     return (unsigned int) OCI_VER_MAJ(con->ver_num);
00914 }
00915 
00916 /* ------------------------------------------------------------------------ *
00917  * OCI_GetServerMinorVersion
00918  * ------------------------------------------------------------------------ */
00919 
00920 unsigned int OCI_API OCI_GetServerMinorVersion(OCI_Connection *con)
00921 {
00922     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
00923 
00924     if (con->ver_num == OCI_UNKNOWN)
00925         OCI_GetVersionServer(con);
00926 
00927     OCI_RESULT(con->ver_num != OCI_UNKNOWN);
00928 
00929     return OCI_VER_MIN(con->ver_num);
00930 }
00931 
00932 /* ------------------------------------------------------------------------ *
00933  * OCI_GetServerRevisionVersion
00934  * ------------------------------------------------------------------------ */
00935 
00936 unsigned int OCI_API OCI_GetServerRevisionVersion(OCI_Connection *con)
00937 {
00938     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
00939 
00940     if (con->ver_num == OCI_UNKNOWN)
00941         OCI_GetVersionServer(con);
00942 
00943     OCI_RESULT(con->ver_num != OCI_UNKNOWN);
00944 
00945     return (unsigned int) OCI_VER_MAJ(con->ver_num);
00946 }
00947 
00948 /* ------------------------------------------------------------------------ *
00949  * OCI_GetTransaction
00950  * ------------------------------------------------------------------------ */
00951 
00952 OCI_Transaction * OCI_API OCI_GetTransaction(OCI_Connection *con)
00953 {
00954     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
00955 
00956     OCI_RESULT(TRUE);
00957 
00958     return con->trs;
00959 }
00960 
00961 /* ------------------------------------------------------------------------ *
00962  * OCI_SetTransaction
00963  * ------------------------------------------------------------------------ */
00964 
00965 boolean OCI_API OCI_SetTransaction(OCI_Connection *con, OCI_Transaction *trans)
00966 {
00967     boolean res = TRUE;
00968 
00969     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
00970     OCI_CHECK_PTR(OCI_IPC_TRANSACTION, trans, FALSE);
00971 
00972     res = OCI_TransactionStop(con->trs);
00973 
00974     if (res == TRUE)
00975         con->trs = trans;
00976 
00977     OCI_RESULT(res);
00978 
00979     return res;
00980 }
00981 
00982 /* ------------------------------------------------------------------------ *
00983  * OCI_GetVersionConnection
00984  * ------------------------------------------------------------------------ */
00985 
00986  unsigned int OCI_API OCI_GetVersionConnection(OCI_Connection *con)
00987 {
00988     int v1, v2;
00989 
00990     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, OCI_UNKNOWN);
00991 
00992     v1 = OCI_GetOCIRuntimeVersion();
00993     v2 = OCI_GetServerMajorVersion(con);
00994 
00995     OCI_RESULT(TRUE);
00996 
00997     /* return the minimum supported version */
00998 
00999     return (OCILib.version_runtime > con->ver_num) ? con->ver_num : OCILib.version_runtime;
01000 }
01001 
01002 
01003 /* ------------------------------------------------------------------------ *
01004  * OCI_SetDefaultFormatDate
01005  * ------------------------------------------------------------------------ */
01006 
01007 boolean OCI_API OCI_SetDefaultFormatDate(OCI_Connection *con, const mtext *format)
01008 {
01009     boolean res = TRUE;
01010 
01011     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01012 
01013     OCI_FREE(con->fmt_date);
01014 
01015     con->fmt_date = mtsdup(format ? format : OCI_STRING_FORMAT_DATE);
01016 
01017     res = (con->fmt_date != NULL);
01018 
01019     OCI_RESULT(res);
01020 
01021     return res;
01022 }
01023 
01024 /* ------------------------------------------------------------------------ *
01025  * OCI_GetDefaultFormatDate
01026  * ------------------------------------------------------------------------ */
01027 
01028 const mtext * OCI_API OCI_GetDefaultFormatDate(OCI_Connection *con)
01029 {
01030     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01031 
01032     OCI_RESULT(TRUE);
01033 
01034     if (con->fmt_date == NULL)
01035         OCI_SetDefaultFormatDate(con, NULL);
01036 
01037     return (con->fmt_date);
01038 }
01039 
01040 /* ------------------------------------------------------------------------ *
01041  * OCI_SetDefaultFormatNumeric
01042  * ------------------------------------------------------------------------ */
01043 
01044 boolean OCI_API OCI_SetDefaultFormatNumeric(OCI_Connection *con, const mtext *format)
01045 {
01046     boolean res = TRUE;
01047 
01048     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01049 
01050     OCI_FREE(con->fmt_num);
01051 
01052     con->fmt_num = mtsdup(format ? format : OCI_STRING_FORMAT_NUM);
01053 
01054     res = (con->fmt_num != NULL);
01055 
01056     OCI_RESULT(res);
01057 
01058     return res;
01059 }
01060 
01061 /* ------------------------------------------------------------------------ *
01062  * OCI_GetDefaultFormatNumeric
01063  * ------------------------------------------------------------------------ */
01064 
01065 const mtext * OCI_API OCI_GetDefaultFormatNumeric(OCI_Connection *con)
01066 {
01067     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01068 
01069     OCI_RESULT(TRUE);
01070 
01071     if (con->fmt_num == NULL)
01072         OCI_SetDefaultFormatNumeric(con, NULL);
01073 
01074     return (con->fmt_num);
01075 }
01076 
01077 /* ------------------------------------------------------------------------ *
01078  * OCI_Break
01079  * ------------------------------------------------------------------------ */
01080 
01081 boolean OCI_API OCI_Break(OCI_Connection *con)
01082 {
01083     boolean res = TRUE;
01084 
01085     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01086 
01087     OCI_CALL2
01088     (
01089         res, con,
01090 
01091         OCIBreak((dvoid *) con->cxt, con->err)
01092     )
01093 
01094     OCI_RESULT(res);
01095 
01096     return res;
01097 }
01098 
01099 /* ------------------------------------------------------------------------ *
01100  * OCI_ServerEnableOutput
01101  * ------------------------------------------------------------------------ */
01102 
01103 boolean OCI_API OCI_ServerEnableOutput(OCI_Connection *con,
01104                                        unsigned int bufsize,
01105                                        unsigned int arrsize,
01106                                        unsigned int lnsize)
01107 {
01108     boolean res = TRUE;
01109 
01110     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01111 
01112     /* initialize the output buffer on server side */
01113 
01114     if (con->svopt == NULL)
01115     {
01116         con->svopt  = (OCI_ServerOutput *) OCI_MemAlloc(OCI_IPC_SERVER_OUPUT,
01117                                                         sizeof(*con->svopt),
01118                                                         1, TRUE);
01119 
01120         res = (con->svopt != NULL);
01121     }
01122 
01123     /* allocation internal buffer if needed */
01124 
01125     if ((res == TRUE) && (con->svopt->arrbuf == NULL))
01126     {
01127         /* check params ranges ( Oracle 10g increased the size of output line */
01128 
01129         if (con->ver_num >= OCI_10_2)
01130         {
01131             if (lnsize < OCI_OUPUT_LSIZE)
01132                 lnsize = OCI_OUPUT_LSIZE;
01133             else if (lnsize > OCI_OUPUT_LSIZE_10G)
01134                 lnsize = OCI_OUPUT_LSIZE_10G;
01135         }
01136         else
01137         {
01138             if (lnsize > OCI_OUPUT_LSIZE)
01139                 lnsize = OCI_OUPUT_LSIZE;
01140         }
01141 
01142         con->svopt->arrsize = arrsize;
01143         con->svopt->lnsize  = lnsize;
01144 
01145         /* allocate internal string (line) array */
01146 
01147         con->svopt->arrbuf = (ub1 *) OCI_MemAlloc(OCI_IPC_STRING,
01148                                                   (con->svopt->lnsize + 1) * sizeof(dtext),
01149                                                   con->svopt->arrsize, TRUE
01150                                                   );
01151 
01152         res = (con->svopt->arrbuf != NULL);
01153     }
01154 
01155     if (res == TRUE)
01156     {
01157         if (con->svopt->stmt == NULL)
01158             con->svopt->stmt = OCI_StatementCreate(con);
01159 
01160         if (con->svopt->stmt != NULL)
01161         {
01162             /* enable server ouput */
01163 
01164             res = OCI_Prepare(con->svopt->stmt,
01165                               MT("BEGIN DBMS_OUTPUT.ENABLE(:n); END;"));
01166 
01167             res = res && OCI_BindUnsignedInt(con->svopt->stmt, MT(":n"), &bufsize);
01168 
01169             if (bufsize == 0)
01170                 res = OCI_SetNull(con->svopt->stmt, 1);
01171 
01172             res = res && OCI_Execute(con->svopt->stmt);
01173 
01174             /* prepare the retreival statement call */
01175 
01176             con->svopt->cursize = con->svopt->arrsize;
01177 
01178             res = res && OCI_Prepare(con->svopt->stmt,
01179                                      MT("BEGIN DBMS_OUTPUT.GET_LINES(:s, :i); END;"));
01180 
01181             res = res && OCI_BindArrayOfStrings(con->svopt->stmt,
01182                                                 MT(":s"),
01183                                                 (dtext *) con->svopt->arrbuf,
01184                                                 con->svopt->lnsize,
01185                                                 con->svopt->arrsize);
01186 
01187             res = res && OCI_BindUnsignedInt(con->svopt->stmt,
01188                                              MT(":i"),
01189                                              &con->svopt->cursize);
01190         }
01191     }
01192 
01193     if (res == FALSE)
01194         OCI_ServerDisableOutput(con);
01195 
01196     OCI_RESULT(res);
01197 
01198     return res;
01199 }
01200 
01201 /* ------------------------------------------------------------------------ *
01202  * OCI_ServerDisableOutput
01203  * ------------------------------------------------------------------------ */
01204 
01205 boolean OCI_API OCI_ServerDisableOutput(OCI_Connection *con)
01206 {
01207     boolean res = TRUE;
01208 
01209     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01210 
01211     if (con->svopt != NULL)
01212     {
01213         res = res && OCI_ExecuteStmt(con->svopt->stmt,
01214                               MT("BEGIN DBMS_OUTPUT.DISABLE(); END;"));
01215 
01216         res = res && OCI_StatementFree(con->svopt->stmt);
01217 
01218         OCI_FREE(con->svopt->arrbuf);
01219         OCI_FREE(con->svopt);
01220     }
01221 
01222     OCI_RESULT(res);
01223 
01224     return res;
01225 }
01226 
01227 /* ------------------------------------------------------------------------ *
01228  * OCI_ServerGetOutput
01229  * ------------------------------------------------------------------------ */
01230 
01231 const dtext * OCI_API OCI_ServerGetOutput(OCI_Connection *con)
01232 {
01233     boolean res = TRUE;
01234     dtext *str  = NULL;
01235 
01236     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01237     OCI_CHECK(con->svopt == NULL, FALSE);
01238 
01239     if (con->svopt->curpos == 0 || con->svopt->curpos >= con->svopt->cursize)
01240         res = OCI_Execute(con->svopt->stmt);
01241 
01242     if (con->svopt->cursize > 0)
01243         str = (dtext*) (con->svopt->arrbuf +
01244                         (((con->svopt->lnsize + 1) * sizeof(dtext)) * con->svopt->curpos++));
01245 
01246     OCI_RESULT(res);
01247 
01248     return (const dtext *) str;
01249 }
01250 
01251 
01252 
01253 /* ------------------------------------------------------------------------ *
01254  * OCI_SetTrace
01255  * ------------------------------------------------------------------------ */
01256 
01257 boolean OCI_API OCI_SetTrace(OCI_Connection *con, unsigned int trace,
01258                              const mtext *value)
01259 {
01260     boolean res = TRUE;
01261     mtext *str  = NULL;
01262 
01263 #if OCI_VERSION_COMPILE >= OCI_10_1
01264     ub4 attrib  = 0;
01265 #endif
01266 
01267     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01268 
01269     /* allocate trace info structure only if trace functions are used */
01270 
01271     if (con->trace == NULL)
01272     {
01273         con->trace = (OCI_TraceInfo *) OCI_MemAlloc(OCI_IPC_TRACE_INFO,
01274                                                     sizeof(*con->trace),
01275                                                     1, TRUE);
01276         res = (con->trace != NULL);
01277     }
01278 
01279     /* set trace properties */
01280 
01281     if (con->trace != NULL)
01282     {
01283         switch (trace)
01284         {
01285             case OCI_TRC_IDENTITY:
01286 
01287 #if OCI_VERSION_COMPILE >= OCI_10_1
01288 
01289                 attrib = OCI_ATTR_CLIENT_IDENTIFIER;
01290 
01291 #endif
01292                 con->trace->identifier[0] = 0;
01293 
01294                 mtsncat(con->trace->identifier, value,
01295                         msizeof(con->trace->identifier));
01296 
01297                 str = con->trace->identifier;
01298 
01299                 break;
01300 
01301             case OCI_TRC_MODULE:
01302 
01303  #if OCI_VERSION_COMPILE >= OCI_10_1
01304 
01305                 attrib = OCI_ATTR_MODULE;
01306 
01307 #endif
01308                 con->trace->module[0] = 0;
01309 
01310                 mtsncat(con->trace->module, value, msizeof(con->trace->module));
01311 
01312                 str = con->trace->module;
01313 
01314                 break;
01315 
01316             case OCI_TRC_ACTION:
01317 
01318 #if OCI_VERSION_COMPILE >= OCI_10_1
01319 
01320                 attrib = OCI_ATTR_ACTION;
01321 
01322 #endif
01323                 con->trace->action[0] = 0;
01324 
01325                 mtsncat(con->trace->action, value, msizeof(con->trace->action));
01326 
01327                 str = con->trace->action;
01328 
01329                 break;
01330 
01331             case OCI_TRC_DETAIL:
01332 
01333 #if OCI_VERSION_COMPILE >= OCI_10_1
01334 
01335                 attrib = OCI_ATTR_CLIENT_INFO;
01336 
01337 #endif
01338                 con->trace->info[0] = 0;
01339 
01340                 mtsncat(con->trace->info, value,  msizeof(con->trace->info));
01341 
01342                 str = con->trace->info;
01343 
01344                 break;
01345 
01346             default:
01347 
01348                 res = FALSE;
01349         }
01350     }
01351 
01352 #if OCI_VERSION_COMPILE >= OCI_10_1
01353 
01354     /* On success, we give the value to Oracle to record it in system session view */
01355 
01356     if (res == TRUE)
01357     {
01358         void *ostr  = NULL;
01359         int osize   = -1;
01360 
01361         ostr  = OCI_GetInputMetaString(str, &osize);
01362 
01363         if (str == NULL)
01364             osize = 0;
01365 
01366         OCI_CALL2
01367         (
01368             res, con,
01369 
01370             OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION,
01371                        (dvoid *) ostr, (ub4) osize, attrib, con->err)
01372         )
01373 
01374         OCI_ReleaseMetaString(ostr);
01375     }
01376 
01377 #endif
01378 
01379     OCI_RESULT(res);
01380 
01381     return res;
01382 }
01383 
01384 /* ------------------------------------------------------------------------ *
01385  * OCI_TraceGet
01386  * ------------------------------------------------------------------------ */
01387 
01388 const mtext * OCI_API OCI_GetTrace(OCI_Connection *con, unsigned int trace)
01389 {
01390     const mtext *str = NULL;
01391     boolean res = TRUE;
01392 
01393     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, NULL);
01394 
01395     if (con->trace != NULL)
01396     {
01397         switch (trace)
01398         {
01399             case OCI_TRC_IDENTITY:
01400 
01401                 str = con->trace->identifier;
01402                 break;
01403 
01404             case OCI_TRC_MODULE:
01405 
01406                 str = con->trace->module;
01407                 break;
01408 
01409             case OCI_TRC_ACTION:
01410 
01411                 str = con->trace->action;
01412                 break;
01413 
01414             case OCI_TRC_DETAIL:
01415 
01416                 str = con->trace->info;
01417                 break;
01418 
01419             default:
01420 
01421                 res = FALSE;
01422         }
01423     }
01424 
01425     OCI_RESULT(res);
01426 
01427     return str;
01428 }
01429 
01430 /* ------------------------------------------------------------------------ *
01431  * OCI_Ping
01432  * ------------------------------------------------------------------------ */
01433 
01434 boolean OCI_API OCI_Ping(OCI_Connection *con)
01435 {
01436     boolean res = TRUE;
01437     boolean ret = FALSE;
01438 
01439     OCI_CHECK_PTR(OCI_IPC_CONNECTION, con, FALSE);
01440 
01441 #if OCI_VERSION_COMPILE >= OCI_10_2
01442 
01443     if (OCILib.version_runtime >= OCI_10_2)
01444     {
01445         OCI_CALL2
01446         (
01447             res, con,
01448 
01449             OCIPing(con->cxt, con->err, (ub4) OCI_DEFAULT)
01450 
01451         )
01452 
01453         ret = res;
01454     }
01455 
01456 #endif
01457 
01458     OCI_RESULT(res);
01459 
01460     return ret;
01461 }

Generated on Thu Jul 30 17:41:52 2009 for OCILIB (C Driver for Oracle) by  doxygen 1.5.4