📄 connection.c
字号:
/*
+----------------------------------------------------------------------+
| |
| 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 + -