⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connection.c

📁 oci的源码,可以在任何平台上编译,相当方便实用
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
   +----------------------------------------------------------------------+   
   |                                                                      |
   |                     OCILIB - C Driver for Oracle                     |
   |                                                                      |
   |                      (C Wrapper for Oracle OCI)                      |
   |                                                                      |
   +----------------------------------------------------------------------+
   |                      Website : http://ocilib.net                     |
   +----------------------------------------------------------------------+
   |               Copyright (c) 2007-2009 Vincent ROGIER                 |
   +----------------------------------------------------------------------+
   | This library is free software; you can redistribute it and/or        |
   | modify it under the terms of the GNU Library General Public          |
   | License as published by the Free Software Foundation; either         |
   | version 2 of the License, or (at your option) any later version.     |
   |                                                                      |
   | This library is distributed in the hope that it will be useful,      |
   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
   | Library General Public License for more details.                     |
   |                                                                      |
   | You should have received a copy of the GNU Library General Public    |
   | License along with this library; if not, write to the Free           |
   | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   |
   +----------------------------------------------------------------------+
   |          Author: Vincent ROGIER <vince.rogier@gmail.com>             |
   +----------------------------------------------------------------------+ 
*/

/* ------------------------------------------------------------------------ *
 * $Id: connection.c, v 3.2.0 2009/04/20 00:00 Vince $
 * ------------------------------------------------------------------------ */

#include "ocilib_internal.h"


/* ************************************************************************ *
 *                             PRIVATE FUNCTIONS
 * ************************************************************************ */

/* ------------------------------------------------------------------------ *
 * OCI_ConnectionAllocate
 * ------------------------------------------------------------------------ */

OCI_Connection * OCI_ConnectionAllocate(OCI_ConnPool *pool, const mtext *db, 
                                        const mtext *user,  const mtext *pwd, 
                                        unsigned int mode)
{
    OCI_Connection *con = NULL;
    OCI_List *list      = NULL;
    OCI_Item *item      = NULL;
    boolean res         = TRUE;

    /* create connection object */

    if (pool != NULL)
        list  = pool->cons;
    else
        list  = OCILib.cons;

    item = OCI_ListAppend(list, sizeof(*con));
 
    if (item != NULL)
    {
        con = (OCI_Connection *) item->data;

        /* create internal lists */

        con->stmts = OCI_ListCreate(OCI_IPC_STATEMENT);    
        
        if (res == TRUE)
        {
            con->tinfs = OCI_ListCreate(OCI_IPC_TYPE_INFO);    
            res = (con->tinfs != NULL);
        }

        if (res == TRUE)
        {
            con->trsns = OCI_ListCreate(OCI_IPC_TRANSACTION);
            res = (con->trsns != NULL);
        }
 
        /* set attributes */

        if (res == TRUE)
        {
            con->mode = mode;
            con->pool = pool;

            if (con->pool != NULL)
            {
                con->db     = (mtext *) db;
                con->user   = (mtext *) user;
                con->pwd    = (mtext *) pwd;
            }
            else
            {
                con->db   = mtsdup(db   != NULL ? db   : MT(""));
                con->user = mtsdup(user != NULL ? user : MT(""));
                con->pwd  = mtsdup(pwd  != NULL ? pwd  : MT(""));
            }
        }

        /*  allocate error handle */
          
        if (res == TRUE)
            res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env, 
                                                  (dvoid **) (void *) &con->err,
                                                  (ub4) OCI_HTYPE_ERROR, 
                                                  (size_t) 0, (dvoid **) NULL));

        /* allocate server handle */
        
        if (res == TRUE)
            res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env, 
                                                  (dvoid **) (void *) &con->svr,
                                                  (ub4) OCI_HTYPE_SERVER,
                                                  (size_t) 0, (dvoid **) NULL));

        /* allocate context handle */
        
        if (res == TRUE)
            res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env, 
                                                  (dvoid **) (void *) &con->cxt,
                                                  (ub4) OCI_HTYPE_SVCCTX, 
                                                  (size_t) 0, (dvoid **) NULL));

        /* allocate session handle */
        
        if (res == TRUE)
            res = (OCI_SUCCESS == OCI_HandleAlloc((dvoid *) OCILib.env,
                                                  (dvoid **) (void *) &con->ses,
                                                  (ub4) OCI_HTYPE_SESSION,
                                                  (size_t) 0, (dvoid **) NULL));
    }
    else
        res = FALSE;

   /* update internal status */
    
    if (res == TRUE)
    {
        con->cstate = OCI_CONN_ALLOCATED;
    }
    else
    {
        OCI_ConnectionFree(con);
        con = NULL;
    }

    return con;
}

/* ------------------------------------------------------------------------ *
 * OCI_ConnectionDeallocate
 * ------------------------------------------------------------------------ */

boolean OCI_ConnectionDeallocate(OCI_Connection *con)
{
    OCI_CHECK(con == NULL, FALSE);
    OCI_CHECK(con->cstate != OCI_CONN_ALLOCATED, FALSE);

    /* close context handle */
    
    if (con->cxt != NULL)
       OCI_HandleFree((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX);

    /* close session handle */
    
    if (con->ses != NULL)
        OCI_HandleFree((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION);

    /* close server handle */
    if (con->svr != NULL)
        OCI_HandleFree((dvoid *) con->svr, (ub4) OCI_HTYPE_SERVER);

     /* close error handle */
    
    if (con->err != NULL)
        OCI_HandleFree((dvoid *) con->err, (ub4) OCI_HTYPE_ERROR);

    con->cxt = NULL;
    con->ses = NULL;
    con->svr = NULL;
    con->err = NULL;

    return TRUE;
}

/* ------------------------------------------------------------------------ *
 * OCI_ConnectionAttach
 * ------------------------------------------------------------------------ */

boolean OCI_ConnectionAttach(OCI_Connection *con)
{
    void *ostr  = NULL;
    int osize   = -1;
    boolean res = TRUE;
    ub4 cmode   = OCI_DEFAULT;

    OCI_CHECK(con == NULL, FALSE);
    OCI_CHECK(con->cstate != OCI_CONN_ALLOCATED, FALSE);

    /* attach server handle to service name */

#if OCI_VERSION_COMPILE >= OCI_9

    if (OCILib.ver_runtime >= OCI_9 && con->pool != NULL)
    {
        ostr  = OCI_GetInputMetaString(con->pool->name, &osize);
        cmode = OCI_CPOOL;
    }
    else

#endif

    {
        ostr  = OCI_GetInputMetaString(con->db, &osize);
    }

    OCI_CALL2
    (
        res, con, 
        
        OCIServerAttach(con->svr, con->err,(OraText *) ostr, (sb4) osize, cmode)
    )
    
    OCI_ReleaseMetaString(ostr);

    /* handle errors */
    
    if (res == TRUE)
    {
        if (OCILib.ver_runtime < OCI_9 && con->pool != NULL)
            con->pool->nb_opened++;

        con->cstate = OCI_CONN_ATTACHED;
    }

    return res;
}

/* ------------------------------------------------------------------------ *
 * OCI_ConnectionDetach
 * ------------------------------------------------------------------------ */

boolean OCI_ConnectionDetach(OCI_Connection *con)
{
    boolean res = TRUE;

    OCI_CHECK(con == NULL, FALSE);
    OCI_CHECK(con->cstate != OCI_CONN_ATTACHED, FALSE);

    /* detach from the oracle server */
    
    OCI_CALL2
    (
        res, con, 
        
        OCIServerDetach(con->svr, con->err, (ub4) OCI_DEFAULT)
    )
 
   /* update internal status */

    if (res == TRUE)
    {
        if (OCILib.ver_runtime < OCI_9 && con->pool != NULL)
            con->pool->nb_opened--;

        con->cstate = OCI_CONN_ALLOCATED;
    }

    return res;
}

/* ------------------------------------------------------------------------ *
 * OCI_ConnectionLogon
 * ------------------------------------------------------------------------ */

boolean OCI_ConnectionLogon(OCI_Connection *con)
{
    void *ostr  = NULL;
    int osize   = -1;
    boolean res = TRUE;
    
    OCI_CHECK(con == NULL, FALSE);

    /* set context server attribute */
    
    OCI_CALL2
    (
        res, con, 
        
        OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX, 
                   (dvoid *) con->svr, (ub4) sizeof (con->svr), 
                   (ub4) OCI_ATTR_SERVER, con->err)
    )

    /* set session login attribute */

    if ((res == TRUE) && (con->user != NULL) && (con->user[0] != 0))
    {
        osize = -1;
        ostr  = OCI_GetInputMetaString(con->user, &osize);

        OCI_CALL2
        (
            res, con,
            
            OCIAttrSet((dvoid *) con->ses,(ub4)  OCI_HTYPE_SESSION, 
                       (dvoid *) ostr, (ub4) osize, 
                       (ub4) OCI_ATTR_USERNAME, con->err)
        )

        OCI_ReleaseMetaString(ostr);
    }

    /* set session password attribute */

    if ((res == TRUE) && (con->pwd != NULL) && (con->pwd[0] != 0))
    {
        osize = -1;
        ostr  = OCI_GetInputMetaString(con->pwd, &osize);

        OCI_CALL2
        (
            res, con,
            
            OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION, 
                       (dvoid *) ostr, (ub4) osize, 
                       (ub4) OCI_ATTR_PASSWORD, con->err)
        )

        OCI_ReleaseMetaString(ostr);
    }

    /* start session */
    
    if (res == TRUE)
    {
        ub4 credt = OCI_CRED_RDBMS;

        if  (((con->user == NULL) || (con->user[0] == 0)) &&
             ((con->pwd  == NULL) || (con->pwd[0]  == 0)))
        {
            credt = OCI_CRED_EXT;
        }

        OCI_CALL2
        (
            res, con,
            
            OCISessionBegin(con->cxt, con->err, con->ses, credt, con->mode)
        )
 
       /* This call has moved after OCISessionBegin() call to enable connection
          pooling (an error ORA-24324 was thrown is the session handle was set to
          the service context handle before OCISessionBegin() */
    
        OCI_CALL2
        (
            res, con,
            
            OCIAttrSet((dvoid *) con->cxt, (ub4) OCI_HTYPE_SVCCTX, 
                       (dvoid *) con->ses, (ub4) sizeof(con->ses), 
                       (ub4) OCI_ATTR_SESSION, con->err))

    }
    
    /* check for success */

    if (res == TRUE)
    {
        /* get server version */

        OCI_GetVersionServer(con);

        /* create default transaction object */

        con->trs  = OCI_TransactionCreate(con, 1, OCI_TRANS_READWRITE, NULL);

        /* start transaction */
        
        res = OCI_TransactionStart(con->trs);
    }


    /* set OCILIB's driver layer name attribute */

#if OCI_VERSION_COMPILE >= OCI_11

    if ((res == TRUE) && (OCILib.ver_runtime >= OCI_11) && (con->ver_maj >= OCI_11))
    {
        osize = -1;
        ostr  = OCI_GetInputMetaString(OCILIB_DRIVER_NAME, &osize);

        OCI_CALL2
        (
            res, con,
            
            OCIAttrSet((dvoid *) con->ses, (ub4) OCI_HTYPE_SESSION, 
                       (dvoid *) ostr, (ub4) osize, 
                       (ub4) OCI_ATTR_DRIVER_NAME, con->err)
        )

        OCI_ReleaseMetaString(ostr);
    }

#endif


   /* update internal status */
    
    if (res == TRUE)
    {
        if (OCILib.ver_runtime < OCI_9 && con->pool != NULL)
            con->pool->nb_busy++;

        con->cstate = OCI_CONN_LOGGED;
    }

    return res;
}

/* ------------------------------------------------------------------------ *
 * OCI_ConnectionLogOff
 * ------------------------------------------------------------------------ */

boolean OCI_ConnectionLogOff(OCI_Connection *con)
{
    boolean res = TRUE;

    OCI_CHECK(con == NULL, FALSE);
    OCI_CHECK(con->cstate != OCI_CONN_LOGGED, FALSE);

    /* free all statements */
    
    OCI_ListForEach(con->stmts, (boolean (*)(void *)) OCI_StatementClose);
    OCI_ListClear(con->stmts);

    /* cleanup the cache */

    OCI_CALL2
    (
        res, con, 

        OCICacheFree(OCILib.env, con->err, con->cxt)
    )

    /* free all transactions */
    
    OCI_ListForEach(con->trsns, (boolean (*)(void *)) OCI_TransactionClose);
    OCI_ListClear(con->trsns);

    /* free all type info objects */
    
    OCI_ListForEach(con->tinfs, (boolean (*)(void *)) OCI_TypeInfoClose);
    OCI_ListClear(con->tinfs);

   /* close any server files not explicitly closed - no check of return code */
   
    if (con->nb_files > 0)
    {
        OCILobFileCloseAll(con->cxt, con->err);
    }

    /* close session */
   
    if ((con->cxt != NULL) && (con->err != NULL) && (con->ses != NULL))
    {
         OCI_CALL2
         (
            res, con, 
            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -