//-----------------------------------------------------------------------------
// Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
//
// Portions Copyright 2007-2015, Anthony Tuininga. All rights reserved.
//
// Portions Copyright 2001-2007, Computronix (Canada) Ltd., Edmonton, Alberta,
// Canada. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// cxoSessionPool.c
// Handles session pooling.
//-----------------------------------------------------------------------------
#include "cxoModule.h"
//-----------------------------------------------------------------------------
// functions for the Python type "SessionPool"
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_new(PyTypeObject*, PyObject*, PyObject*);
static int cxoSessionPool_init(cxoSessionPool*, PyObject*, PyObject*);
static void cxoSessionPool_free(cxoSessionPool*);
static PyObject *cxoSessionPool_acquire(cxoSessionPool*, PyObject*, PyObject*);
static PyObject *cxoSessionPool_close(cxoSessionPool*, PyObject*, PyObject*);
static PyObject *cxoSessionPool_drop(cxoSessionPool*, PyObject*);
static PyObject *cxoSessionPool_release(cxoSessionPool*, PyObject*, PyObject*);
static PyObject *cxoSessionPool_getBusyCount(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getGetMode(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getMaxLifetimeSession(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getOpenCount(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getStmtCacheSize(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getTimeout(cxoSessionPool*, void*);
static PyObject *cxoSessionPool_getWaitTimeout(cxoSessionPool*, void*);
static int cxoSessionPool_setGetMode(cxoSessionPool*, PyObject*, void*);
static int cxoSessionPool_setMaxLifetimeSession(cxoSessionPool*, PyObject*,
void*);
static int cxoSessionPool_setStmtCacheSize(cxoSessionPool*, PyObject*, void*);
static int cxoSessionPool_setTimeout(cxoSessionPool*, PyObject*, void*);
static int cxoSessionPool_setWaitTimeout(cxoSessionPool*, PyObject*, void*);
//-----------------------------------------------------------------------------
// declaration of methods for Python type "SessionPool"
//-----------------------------------------------------------------------------
static PyMethodDef cxoSessionPoolMethods[] = {
{ "acquire", (PyCFunction) cxoSessionPool_acquire,
METH_VARARGS | METH_KEYWORDS },
{ "close", (PyCFunction) cxoSessionPool_close,
METH_VARARGS | METH_KEYWORDS },
{ "drop", (PyCFunction) cxoSessionPool_drop, METH_VARARGS },
{ "release", (PyCFunction) cxoSessionPool_release,
METH_VARARGS | METH_KEYWORDS },
{ NULL }
};
//-----------------------------------------------------------------------------
// declaration of members for Python type "SessionPool"
//-----------------------------------------------------------------------------
static PyMemberDef cxoSessionPoolMembers[] = {
{ "username", T_OBJECT, offsetof(cxoSessionPool, username), READONLY },
{ "dsn", T_OBJECT, offsetof(cxoSessionPool, dsn), READONLY },
{ "tnsentry", T_OBJECT, offsetof(cxoSessionPool, dsn), READONLY },
{ "name", T_OBJECT, offsetof(cxoSessionPool, name), READONLY },
{ "max", T_INT, offsetof(cxoSessionPool, maxSessions), READONLY },
{ "min", T_INT, offsetof(cxoSessionPool, minSessions), READONLY },
{ "increment", T_INT, offsetof(cxoSessionPool, sessionIncrement),
READONLY },
{ "homogeneous", T_INT, offsetof(cxoSessionPool, homogeneous), READONLY },
{ NULL }
};
//-----------------------------------------------------------------------------
// declaration of calculated members for Python type "SessionPool"
//-----------------------------------------------------------------------------
static PyGetSetDef cxoSessionPoolCalcMembers[] = {
{ "opened", (getter) cxoSessionPool_getOpenCount, 0, 0, 0 },
{ "busy", (getter) cxoSessionPool_getBusyCount, 0, 0, 0 },
{ "timeout", (getter) cxoSessionPool_getTimeout,
(setter) cxoSessionPool_setTimeout, 0, 0 },
{ "getmode", (getter) cxoSessionPool_getGetMode,
(setter) cxoSessionPool_setGetMode, 0, 0 },
{ "max_lifetime_session", (getter) cxoSessionPool_getMaxLifetimeSession,
(setter) cxoSessionPool_setMaxLifetimeSession, 0, 0 },
{ "stmtcachesize", (getter) cxoSessionPool_getStmtCacheSize,
(setter) cxoSessionPool_setStmtCacheSize, 0, 0 },
{ "wait_timeout", (getter) cxoSessionPool_getWaitTimeout,
(setter) cxoSessionPool_setWaitTimeout, 0, 0 },
{ NULL }
};
//-----------------------------------------------------------------------------
// declaration of Python type "SessionPool"
//-----------------------------------------------------------------------------
PyTypeObject cxoPyTypeSessionPool = {
PyVarObject_HEAD_INIT(NULL, 0)
"cx_Oracle.SessionPool", // tp_name
sizeof(cxoSessionPool), // tp_basicsize
0, // tp_itemsize
(destructor) cxoSessionPool_free, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
// tp_flags
0, // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
cxoSessionPoolMethods, // tp_methods
cxoSessionPoolMembers, // tp_members
cxoSessionPoolCalcMembers, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
(initproc) cxoSessionPool_init, // tp_init
0, // tp_alloc
(newfunc) cxoSessionPool_new, // tp_new
0, // tp_free
0, // tp_is_gc
0 // tp_bases
};
//-----------------------------------------------------------------------------
// cxoSessionPool_new()
// Create a new session pool object.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_new(PyTypeObject *type, PyObject *args,
PyObject *keywordArgs)
{
return type->tp_alloc(type, 0);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_init()
// Initialize the session pool object.
//-----------------------------------------------------------------------------
static int cxoSessionPool_init(cxoSessionPool *pool, PyObject *args,
PyObject *keywordArgs)
{
cxoBuffer userNameBuffer, passwordBuffer, dsnBuffer, editionBuffer;
PyObject *threadedObj, *eventsObj, *homogeneousObj, *passwordObj;
PyObject *usernameObj, *dsnObj, *sessionCallbackObj;
uint32_t minSessions, maxSessions, sessionIncrement;
PyObject *externalAuthObj, *editionObj;
dpiCommonCreateParams dpiCommonParams;
dpiPoolCreateParams dpiCreateParams;
cxoBuffer sessionCallbackBuffer;
PyTypeObject *connectionType;
const char *encoding;
int status, temp;
// define keyword arguments
static char *keywordList[] = { "user", "password", "dsn", "min", "max",
"increment", "connectiontype", "threaded", "getmode", "events",
"homogeneous", "externalauth", "encoding", "nencoding", "edition",
"timeout", "waitTimeout", "maxLifetimeSession", "sessionCallback",
NULL };
// parse arguments and keywords
usernameObj = passwordObj = dsnObj = editionObj = Py_None;
externalAuthObj = sessionCallbackObj = NULL;
threadedObj = eventsObj = homogeneousObj = passwordObj = NULL;
connectionType = &cxoPyTypeConnection;
minSessions = 1;
maxSessions = 2;
sessionIncrement = 1;
if (cxoUtils_initializeDPI() < 0)
return -1;
if (dpiContext_initCommonCreateParams(cxoDpiContext, &dpiCommonParams) < 0)
return cxoError_raiseAndReturnInt();
dpiCommonParams.driverName = CXO_DRIVER_NAME;
dpiCommonParams.driverNameLength =
(uint32_t) strlen(dpiCommonParams.driverName);
if (dpiContext_initPoolCreateParams(cxoDpiContext, &dpiCreateParams) < 0)
return cxoError_raiseAndReturnInt();
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|OOOiiiOObOOOssOiiiO",
keywordList, &usernameObj, &passwordObj, &dsnObj, &minSessions,
&maxSessions, &sessionIncrement, &connectionType, &threadedObj,
&dpiCreateParams.getMode, &eventsObj, &homogeneousObj,
&externalAuthObj, &dpiCommonParams.encoding,
&dpiCommonParams.nencoding, &editionObj, &dpiCreateParams.timeout,
&dpiCreateParams.waitTimeout, &dpiCreateParams.maxLifetimeSession,
&sessionCallbackObj))
return -1;
if (!PyType_Check(connectionType)) {
cxoError_raiseFromString(cxoProgrammingErrorException,
"connectiontype must be a type");
return -1;
}
if (!PyType_IsSubtype(connectionType, &cxoPyTypeConnection)) {
cxoError_raiseFromString(cxoProgrammingErrorException,
"connectiontype must be a subclass of Connection");
return -1;
}
if (cxoUtils_getBooleanValue(threadedObj, 0, &temp) < 0)
return -1;
if (temp)
dpiCommonParams.createMode |= DPI_MODE_CREATE_THREADED;
if (cxoUtils_getBooleanValue(eventsObj, 0, &temp) < 0)
return -1;
if (temp)
dpiCommonParams.createMode |= DPI_MODE_CREATE_EVENTS;
if (cxoUtils_getBooleanValue(externalAuthObj, 0,
&dpiCreateParams.externalAuth) < 0)
return -1;
if (cxoUtils_getBooleanValue(homogeneousObj, 1,
&dpiCreateParams.homogeneous) < 0)
return -1;
// initialize the object's members
Py_INCREF(connectionType);
pool->connectionType = connectionType;
Py_INCREF(dsnObj);
pool->dsn = dsnObj;
Py_INCREF(usernameObj);
pool->username = usernameObj;
pool->minSessions = minSessions;
pool->maxSessions = maxSessions;
pool->sessionIncrement = sessionIncrement;
pool->homogeneous = dpiCreateParams.homogeneous;
pool->externalAuth = dpiCreateParams.externalAuth;
Py_XINCREF(sessionCallbackObj);
pool->sessionCallback = sessionCallbackObj;
// populate parameters
encoding = cxoUtils_getAdjustedEncoding(dpiCommonParams.encoding);
cxoBuffer_init(&userNameBuffer);
cxoBuffer_init(&passwordBuffer);
cxoBuffer_init(&dsnBuffer);
cxoBuffer_init(&editionBuffer);
cxoBuffer_init(&sessionCallbackBuffer);
if (sessionCallbackObj && !PyCallable_Check(sessionCallbackObj) &&
cxoBuffer_fromObject(&sessionCallbackBuffer, sessionCallbackObj,
encoding) < 0)
return -1;
if (cxoBuffer_fromObject(&userNameBuffer, usernameObj, encoding) < 0 ||
cxoBuffer_fromObject(&passwordBuffer, passwordObj, encoding) < 0 ||
cxoBuffer_fromObject(&dsnBuffer, dsnObj, encoding) < 0 ||
cxoBuffer_fromObject(&editionBuffer, editionObj, encoding) < 0) {
cxoBuffer_clear(&userNameBuffer);
cxoBuffer_clear(&passwordBuffer);
cxoBuffer_clear(&dsnBuffer);
cxoBuffer_clear(&sessionCallbackBuffer);
return -1;
}
dpiCreateParams.minSessions = minSessions;
dpiCreateParams.maxSessions = maxSessions;
dpiCreateParams.sessionIncrement = sessionIncrement;
dpiCreateParams.plsqlFixupCallback = sessionCallbackBuffer.ptr;
dpiCreateParams.plsqlFixupCallbackLength = sessionCallbackBuffer.size;
dpiCommonParams.edition = editionBuffer.ptr;
dpiCommonParams.editionLength = editionBuffer.size;
// create pool
Py_BEGIN_ALLOW_THREADS
status = dpiPool_create(cxoDpiContext, userNameBuffer.ptr,
userNameBuffer.size, passwordBuffer.ptr, passwordBuffer.size,
dsnBuffer.ptr, dsnBuffer.size, &dpiCommonParams, &dpiCreateParams,
&pool->handle);
Py_END_ALLOW_THREADS
cxoBuffer_clear(&userNameBuffer);
cxoBuffer_clear(&passwordBuffer);
cxoBuffer_clear(&dsnBuffer);
cxoBuffer_clear(&editionBuffer);
if (status < 0)
return cxoError_raiseAndReturnInt();
// get encodings and name
if (dpiPool_getEncodingInfo(pool->handle, &pool->encodingInfo) < 0)
return cxoError_raiseAndReturnInt();
pool->encodingInfo.encoding =
cxoUtils_getAdjustedEncoding(pool->encodingInfo.encoding);
pool->encodingInfo.nencoding =
cxoUtils_getAdjustedEncoding(pool->encodingInfo.nencoding);
pool->name = cxoPyString_fromEncodedString(dpiCreateParams.outPoolName,
dpiCreateParams.outPoolNameLength, pool->encodingInfo.encoding,
NULL);
if (!pool->name)
return -1;
return 0;
}
//-----------------------------------------------------------------------------
// cxoSessionPool_free()
// Deallocate the session pool.
//-----------------------------------------------------------------------------
static void cxoSessionPool_free(cxoSessionPool *pool)
{
if (pool->handle) {
dpiPool_release(pool->handle);
pool->handle = NULL;
}
Py_CLEAR(pool->username);
Py_CLEAR(pool->dsn);
Py_CLEAR(pool->name);
Py_CLEAR(pool->sessionCallback);
Py_TYPE(pool)->tp_free((PyObject*) pool);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_acquire()
// Create a new connection within the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_acquire(cxoSessionPool *pool, PyObject *args,
PyObject *keywordArgs)
{
static char *keywordList[] = { "user", "password", "cclass", "purity",
"tag", "matchanytag", "shardingkey", "supershardingkey", NULL };
PyObject *createKeywordArgs, *result, *cclassObj, *purityObj, *tagObj;
PyObject *shardingKeyObj, *superShardingKeyObj;
unsigned usernameLength, passwordLength;
char *username, *password;
PyObject *matchAnyTagObj;
// parse arguments
username = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|s#s#OOOOOO",
keywordList, &username, &usernameLength, &password,
&passwordLength, &cclassObj, &purityObj, &tagObj, &matchAnyTagObj,
&shardingKeyObj, &superShardingKeyObj))
return NULL;
if (pool->homogeneous && username)
return cxoError_raiseFromString(cxoProgrammingErrorException,
"pool is homogeneous. Proxy authentication is not possible.");
// create arguments
if (keywordArgs)
createKeywordArgs = PyDict_Copy(keywordArgs);
else createKeywordArgs = PyDict_New();
if (!createKeywordArgs)
return NULL;
if (PyDict_SetItemString(createKeywordArgs, "pool",
(PyObject*) pool) < 0) {
Py_DECREF(createKeywordArgs);
return NULL;
}
// create the connection object
result = PyObject_Call( (PyObject*) pool->connectionType, args,
createKeywordArgs);
Py_DECREF(createKeywordArgs);
return result;
}
//-----------------------------------------------------------------------------
// cxoSessionPool_close()
// Close the session pool and make it unusable.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_close(cxoSessionPool *pool, PyObject *args,
PyObject *keywordArgs)
{
static char *keywordList[] = { "force", NULL };
PyObject *forceObj;
uint32_t closeMode;
int temp, status;
// parse arguments
forceObj = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|O", keywordList,
&forceObj))
return NULL;
if (cxoUtils_getBooleanValue(forceObj, 0, &temp) < 0)
return NULL;
closeMode = (temp) ? DPI_MODE_POOL_CLOSE_FORCE :
DPI_MODE_POOL_CLOSE_DEFAULT;
// close pool
Py_BEGIN_ALLOW_THREADS
status = dpiPool_close(pool->handle, closeMode);
Py_END_ALLOW_THREADS
if (status < 0)
return cxoError_raiseAndReturnNull();
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoSessionPool_drop()
// Release a connection back to the session pool, dropping it so that a new
// connection will be created if needed.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_drop(cxoSessionPool *pool, PyObject *args)
{
cxoConnection *connection;
int status;
// connection is expected
if (!PyArg_ParseTuple(args, "O!", &cxoPyTypeConnection, &connection))
return NULL;
// release the connection
Py_BEGIN_ALLOW_THREADS
status = dpiConn_close(connection->handle, DPI_MODE_CONN_CLOSE_DROP, NULL,
0);
Py_END_ALLOW_THREADS
if (status < 0)
return cxoError_raiseAndReturnNull();
// mark connection as closed
Py_CLEAR(connection->sessionPool);
dpiConn_release(connection->handle);
connection->handle = NULL;
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoSessionPool_release()
// Release a connection back to the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_release(cxoSessionPool *pool, PyObject *args,
PyObject *keywordArgs)
{
static char *keywordList[] = { "connection", "tag", NULL };
cxoConnection *conn;
cxoBuffer tagBuffer;
PyObject *tagObj;
uint32_t mode;
int status;
// parse arguments
tagObj = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "O!|O",
keywordList, &cxoPyTypeConnection, &conn, &tagObj))
return NULL;
if (!tagObj)
tagObj = conn->tag;
if (cxoBuffer_fromObject(&tagBuffer, tagObj,
pool->encodingInfo.encoding) < 0)
return NULL;
mode = DPI_MODE_CONN_CLOSE_DEFAULT;
if (tagObj && tagObj != Py_None)
mode |= DPI_MODE_CONN_CLOSE_RETAG;
Py_BEGIN_ALLOW_THREADS
status = dpiConn_close(conn->handle, mode, (char*) tagBuffer.ptr,
tagBuffer.size);
Py_END_ALLOW_THREADS
cxoBuffer_clear(&tagBuffer);
if (status < 0)
return cxoError_raiseAndReturnNull();
// mark connection as closed
Py_CLEAR(conn->sessionPool);
dpiConn_release(conn->handle);
conn->handle = NULL;
Py_RETURN_NONE;
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getAttribute()
// Return the value for the attribute.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getAttribute(cxoSessionPool *pool,
int (*func)(dpiPool *pool, uint32_t *value))
{
uint32_t value;
if ((*func)(pool->handle, &value) < 0)
return cxoError_raiseAndReturnNull();
#if PY_MAJOR_VERSION >= 3
return PyLong_FromUnsignedLong(value);
#else
return PyInt_FromLong(value);
#endif
}
//-----------------------------------------------------------------------------
// cxoSessionPool_setAttribute()
// Set the value of the OCI attribute.
//-----------------------------------------------------------------------------
static int cxoSessionPool_setAttribute(cxoSessionPool *pool, PyObject *value,
int (*func)(dpiPool *pool, uint32_t value))
{
uint32_t cValue;
if (!PyInt_Check(value)) {
PyErr_SetString(PyExc_TypeError, "value must be an integer");
return -1;
}
#if PY_MAJOR_VERSION >= 3
cValue = PyLong_AsUnsignedLong(value);
#else
cValue = PyInt_AsLong(value);
#endif
if (PyErr_Occurred())
return -1;
if ((*func)(pool->handle, cValue) < 0)
return cxoError_raiseAndReturnInt();
return 0;
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getBusyCount()
// Return the number of busy connections in the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getBusyCount(cxoSessionPool *pool,
void *unused)
{
return cxoSessionPool_getAttribute(pool, dpiPool_getBusyCount);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getGetMode()
// Return the "get" mode for connections in the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getGetMode(cxoSessionPool *pool, void *unused)
{
dpiPoolGetMode value;
if (dpiPool_getGetMode(pool->handle, &value) < 0)
return cxoError_raiseAndReturnNull();
return PyInt_FromLong(value);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getMaxLifetimeSession()
// Return the maximum lifetime session of connections in the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getMaxLifetimeSession(cxoSessionPool *pool,
void *unused)
{
return cxoSessionPool_getAttribute(pool, dpiPool_getMaxLifetimeSession);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getOpenCount()
// Return the number of open connections in the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getOpenCount(cxoSessionPool *pool, void *unused)
{
return cxoSessionPool_getAttribute(pool, dpiPool_getOpenCount);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getStmtCacheSize()
// Return the size of the statement cache to use in connections that are
// acquired from the pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getStmtCacheSize(cxoSessionPool *pool,
void *unused)
{
return cxoSessionPool_getAttribute(pool, dpiPool_getStmtCacheSize);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getTimeout()
// Return the timeout for connections in the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getTimeout(cxoSessionPool *pool, void *unused)
{
return cxoSessionPool_getAttribute(pool, dpiPool_getTimeout);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_getWaitTimeout()
// Return the wait timeout for connections in the session pool.
//-----------------------------------------------------------------------------
static PyObject *cxoSessionPool_getWaitTimeout(cxoSessionPool *pool,
void *unused)
{
return cxoSessionPool_getAttribute(pool, dpiPool_getWaitTimeout);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_setGetMode()
// Set the "get" mode for connections in the session pool.
//-----------------------------------------------------------------------------
static int cxoSessionPool_setGetMode(cxoSessionPool *pool, PyObject *value,
void *unused)
{
dpiPoolGetMode cValue;
cValue = PyInt_AsLong(value);
if (PyErr_Occurred())
return -1;
if (dpiPool_setGetMode(pool->handle, cValue) < 0)
return cxoError_raiseAndReturnInt();
return 0;
}
//-----------------------------------------------------------------------------
// cxoSessionPool_setMaxLifetimeSession()
// Set the maximum lifetime for connections in the session pool.
//-----------------------------------------------------------------------------
static int cxoSessionPool_setMaxLifetimeSession(cxoSessionPool *pool,
PyObject *value, void *unused)
{
return cxoSessionPool_setAttribute(pool, value,
dpiPool_setMaxLifetimeSession);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_setStmtCacheSize()
// Set the default size of the statement cache used for connections that are
// acquired from the pool.
//-----------------------------------------------------------------------------
static int cxoSessionPool_setStmtCacheSize(cxoSessionPool *pool,
PyObject *value, void *unused)
{
return cxoSessionPool_setAttribute(pool, value, dpiPool_setStmtCacheSize);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_setTimeout()
// Set the timeout for connections in the session pool.
//-----------------------------------------------------------------------------
static int cxoSessionPool_setTimeout(cxoSessionPool *pool, PyObject *value,
void *unused)
{
return cxoSessionPool_setAttribute(pool, value, dpiPool_setTimeout);
}
//-----------------------------------------------------------------------------
// cxoSessionPool_setWaitTimeout()
// Set the wait timeout for connections in the session pool.
//-----------------------------------------------------------------------------
static int cxoSessionPool_setWaitTimeout(cxoSessionPool *pool, PyObject *value,
void *unused)
{
return cxoSessionPool_setAttribute(pool, value, dpiPool_setWaitTimeout);
}