1620 lines
63 KiB
C
1620 lines
63 KiB
C
//-----------------------------------------------------------------------------
|
|
// Copyright 2016-2018, 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.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection.c
|
|
// Definition of the Python type Connection.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "cxoModule.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// functions for the Python type "Connection"
|
|
//-----------------------------------------------------------------------------
|
|
static void cxoConnection_free(cxoConnection*);
|
|
static PyObject *cxoConnection_new(PyTypeObject*, PyObject*, PyObject*);
|
|
static int cxoConnection_init(cxoConnection*, PyObject*, PyObject*);
|
|
static PyObject *cxoConnection_repr(cxoConnection*);
|
|
static PyObject *cxoConnection_close(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_commit(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_begin(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_prepare(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_rollback(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_newCursor(cxoConnection*, PyObject*, PyObject*);
|
|
static PyObject *cxoConnection_cancel(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_getVersion(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getEncoding(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getNationalEncoding(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getMaxBytesPerCharacter(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_contextManagerEnter(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_contextManagerExit(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_changePassword(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_getType(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_createLob(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_getStmtCacheSize(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_newEnqueueOptions(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_newDequeueOptions(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_newMessageProperties(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_dequeue(cxoConnection*, PyObject*, PyObject*);
|
|
static PyObject *cxoConnection_enqueue(cxoConnection*, PyObject*, PyObject*);
|
|
static PyObject *cxoConnection_ping(cxoConnection*, PyObject*);
|
|
static PyObject *cxoConnection_shutdown(cxoConnection*, PyObject*, PyObject*);
|
|
static PyObject *cxoConnection_startup(cxoConnection*, PyObject*, PyObject*);
|
|
static PyObject *cxoConnection_subscribe(cxoConnection*, PyObject*, PyObject*);
|
|
static PyObject *cxoConnection_getLTXID(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getHandle(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getCurrentSchema(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getEdition(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getExternalName(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getInternalName(cxoConnection*, void*);
|
|
static PyObject *cxoConnection_getException(cxoConnection*, void*);
|
|
static int cxoConnection_setStmtCacheSize(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setAction(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setClientIdentifier(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setClientInfo(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setCurrentSchema(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setDbOp(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setExternalName(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setInternalName(cxoConnection*, PyObject*, void*);
|
|
static int cxoConnection_setModule(cxoConnection*, PyObject*, void*);
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// declaration of methods for Python type "Connection"
|
|
//-----------------------------------------------------------------------------
|
|
static PyMethodDef cxoConnectionMethods[] = {
|
|
{ "cursor", (PyCFunction) cxoConnection_newCursor,
|
|
METH_VARARGS | METH_KEYWORDS },
|
|
{ "commit", (PyCFunction) cxoConnection_commit, METH_NOARGS },
|
|
{ "rollback", (PyCFunction) cxoConnection_rollback, METH_NOARGS },
|
|
{ "begin", (PyCFunction) cxoConnection_begin, METH_VARARGS },
|
|
{ "prepare", (PyCFunction) cxoConnection_prepare, METH_NOARGS },
|
|
{ "close", (PyCFunction) cxoConnection_close, METH_NOARGS },
|
|
{ "cancel", (PyCFunction) cxoConnection_cancel, METH_NOARGS },
|
|
{ "__enter__", (PyCFunction) cxoConnection_contextManagerEnter,
|
|
METH_NOARGS },
|
|
{ "__exit__", (PyCFunction) cxoConnection_contextManagerExit,
|
|
METH_VARARGS },
|
|
{ "ping", (PyCFunction) cxoConnection_ping, METH_NOARGS },
|
|
{ "shutdown", (PyCFunction) cxoConnection_shutdown,
|
|
METH_VARARGS | METH_KEYWORDS},
|
|
{ "startup", (PyCFunction) cxoConnection_startup,
|
|
METH_VARARGS | METH_KEYWORDS},
|
|
{ "subscribe", (PyCFunction) cxoConnection_subscribe,
|
|
METH_VARARGS | METH_KEYWORDS},
|
|
{ "changepassword", (PyCFunction) cxoConnection_changePassword,
|
|
METH_VARARGS },
|
|
{ "gettype", (PyCFunction) cxoConnection_getType, METH_O },
|
|
{ "deqoptions", (PyCFunction) cxoConnection_newDequeueOptions,
|
|
METH_NOARGS },
|
|
{ "enqoptions", (PyCFunction) cxoConnection_newEnqueueOptions,
|
|
METH_NOARGS },
|
|
{ "msgproperties", (PyCFunction) cxoConnection_newMessageProperties,
|
|
METH_NOARGS },
|
|
{ "deq", (PyCFunction) cxoConnection_dequeue,
|
|
METH_VARARGS | METH_KEYWORDS },
|
|
{ "enq", (PyCFunction) cxoConnection_enqueue,
|
|
METH_VARARGS | METH_KEYWORDS },
|
|
{ "createlob", (PyCFunction) cxoConnection_createLob, METH_O },
|
|
{ NULL }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// declaration of members for Python type "Connection"
|
|
//-----------------------------------------------------------------------------
|
|
static PyMemberDef cxoConnectionMembers[] = {
|
|
{ "username", T_OBJECT, offsetof(cxoConnection, username), READONLY },
|
|
{ "dsn", T_OBJECT, offsetof(cxoConnection, dsn), READONLY },
|
|
{ "tnsentry", T_OBJECT, offsetof(cxoConnection, dsn), READONLY },
|
|
{ "autocommit", T_INT, offsetof(cxoConnection, autocommit), 0 },
|
|
{ "inputtypehandler", T_OBJECT,
|
|
offsetof(cxoConnection, inputTypeHandler), 0 },
|
|
{ "outputtypehandler", T_OBJECT,
|
|
offsetof(cxoConnection, outputTypeHandler), 0 },
|
|
{ NULL }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// declaration of calculated members for Python type "Connection"
|
|
//-----------------------------------------------------------------------------
|
|
static PyGetSetDef cxoConnectionCalcMembers[] = {
|
|
{ "version", (getter) cxoConnection_getVersion, 0, 0, 0 },
|
|
{ "encoding", (getter) cxoConnection_getEncoding, 0, 0, 0 },
|
|
{ "nencoding", (getter) cxoConnection_getNationalEncoding, 0, 0, 0 },
|
|
{ "maxBytesPerCharacter", (getter) cxoConnection_getMaxBytesPerCharacter,
|
|
0, 0, 0 },
|
|
{ "stmtcachesize", (getter) cxoConnection_getStmtCacheSize,
|
|
(setter) cxoConnection_setStmtCacheSize, 0, 0 },
|
|
{ "module", 0, (setter) cxoConnection_setModule, 0, 0 },
|
|
{ "action", 0, (setter) cxoConnection_setAction, 0, 0 },
|
|
{ "clientinfo", 0, (setter) cxoConnection_setClientInfo, 0, 0 },
|
|
{ "client_identifier", 0, (setter) cxoConnection_setClientIdentifier, 0,
|
|
0 },
|
|
{ "current_schema", (getter) cxoConnection_getCurrentSchema,
|
|
(setter) cxoConnection_setCurrentSchema, 0, 0 },
|
|
{ "external_name", (getter) cxoConnection_getExternalName,
|
|
(setter) cxoConnection_setExternalName, 0, 0 },
|
|
{ "internal_name", (getter) cxoConnection_getInternalName,
|
|
(setter) cxoConnection_setInternalName, 0, 0 },
|
|
{ "dbop", 0, (setter) cxoConnection_setDbOp, 0, 0 },
|
|
{ "edition", (getter) cxoConnection_getEdition, 0, 0, 0 },
|
|
{ "ltxid", (getter) cxoConnection_getLTXID, 0, 0, 0 },
|
|
{ "handle", (getter) cxoConnection_getHandle, 0, 0, 0 },
|
|
{ "Error", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoErrorException },
|
|
{ "Warning", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoWarningException },
|
|
{ "InterfaceError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoInterfaceErrorException },
|
|
{ "DatabaseError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoDatabaseErrorException },
|
|
{ "InternalError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoInternalErrorException },
|
|
{ "OperationalError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoOperationalErrorException },
|
|
{ "ProgrammingError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoProgrammingErrorException },
|
|
{ "IntegrityError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoIntegrityErrorException },
|
|
{ "DataError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoDataErrorException },
|
|
{ "NotSupportedError", (getter) cxoConnection_getException, NULL, NULL,
|
|
&cxoNotSupportedErrorException },
|
|
{ NULL }
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// declaration of Python type "Connection"
|
|
//-----------------------------------------------------------------------------
|
|
PyTypeObject cxoPyTypeConnection = {
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
"cx_Oracle.Connection", // tp_name
|
|
sizeof(cxoConnection), // tp_basicsize
|
|
0, // tp_itemsize
|
|
(destructor) cxoConnection_free, // tp_dealloc
|
|
0, // tp_print
|
|
0, // tp_getattr
|
|
0, // tp_setattr
|
|
0, // tp_compare
|
|
(reprfunc) cxoConnection_repr, // 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
|
|
cxoConnectionMethods, // tp_methods
|
|
cxoConnectionMembers, // tp_members
|
|
cxoConnectionCalcMembers, // tp_getset
|
|
0, // tp_base
|
|
0, // tp_dict
|
|
0, // tp_descr_get
|
|
0, // tp_descr_set
|
|
0, // tp_dictoffset
|
|
(initproc) cxoConnection_init, // tp_init
|
|
0, // tp_alloc
|
|
(newfunc) cxoConnection_new, // tp_new
|
|
0, // tp_free
|
|
0, // tp_is_gc
|
|
0 // tp_bases
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// structure used to help in establishing a connection
|
|
//-----------------------------------------------------------------------------
|
|
typedef struct {
|
|
const char *encoding;
|
|
const char *nencoding;
|
|
cxoBuffer userNameBuffer;
|
|
cxoBuffer passwordBuffer;
|
|
cxoBuffer newPasswordBuffer;
|
|
cxoBuffer dsnBuffer;
|
|
cxoBuffer connectionClassBuffer;
|
|
cxoBuffer editionBuffer;
|
|
cxoBuffer tagBuffer;
|
|
uint32_t numAppContext;
|
|
dpiAppContext *appContext;
|
|
cxoBuffer *ctxNamespaceBuffers;
|
|
cxoBuffer *ctxNameBuffers;
|
|
cxoBuffer *ctxValueBuffers;
|
|
dpiShardingKeyColumn *shardingKeyColumns;
|
|
cxoBuffer *shardingKeyBuffers;
|
|
uint32_t numShardingKeyColumns;
|
|
dpiShardingKeyColumn *superShardingKeyColumns;
|
|
uint32_t numSuperShardingKeyColumns;
|
|
cxoBuffer *superShardingKeyBuffers;
|
|
} cxoConnectionParams;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnectionParams_initialize()
|
|
// Initialize the parameters to default values.
|
|
//-----------------------------------------------------------------------------
|
|
static void cxoConnectionParams_initialize(cxoConnectionParams *params)
|
|
{
|
|
cxoBuffer_init(¶ms->userNameBuffer);
|
|
cxoBuffer_init(¶ms->passwordBuffer);
|
|
cxoBuffer_init(¶ms->newPasswordBuffer);
|
|
cxoBuffer_init(¶ms->dsnBuffer);
|
|
cxoBuffer_init(¶ms->connectionClassBuffer);
|
|
cxoBuffer_init(¶ms->editionBuffer);
|
|
cxoBuffer_init(¶ms->tagBuffer);
|
|
params->numAppContext = 0;
|
|
params->appContext = NULL;
|
|
params->ctxNamespaceBuffers = NULL;
|
|
params->ctxNameBuffers = NULL;
|
|
params->ctxValueBuffers = NULL;
|
|
params->numShardingKeyColumns = 0;
|
|
params->shardingKeyColumns = NULL;
|
|
params->shardingKeyBuffers = NULL;
|
|
params->numSuperShardingKeyColumns = 0;
|
|
params->superShardingKeyColumns = NULL;
|
|
params->superShardingKeyBuffers = NULL;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnectionParams_ProcessContext()
|
|
// Process context for the connection parameters. This validates that the
|
|
// context passed in is a list of 3-tuples (namespace, name, value) and
|
|
// populates the parametrs with buffers for each of these.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnectionParams_processContext(cxoConnectionParams *params,
|
|
PyObject *context)
|
|
{
|
|
uint32_t numEntries, i;
|
|
dpiAppContext *entry;
|
|
PyObject *entryObj;
|
|
size_t memorySize;
|
|
|
|
// validate context is a list with at least one entry in it
|
|
if (!context)
|
|
return 0;
|
|
if (!PyList_Check(context)) {
|
|
PyErr_SetString(PyExc_TypeError,
|
|
"appcontext should be a list of 3-tuples");
|
|
return -1;
|
|
}
|
|
numEntries = (uint32_t) PyList_GET_SIZE(context);
|
|
if (numEntries == 0)
|
|
return 0;
|
|
|
|
// allocate memory for the buffers used to communicate with DPI
|
|
params->appContext = PyMem_Malloc(numEntries * sizeof(dpiAppContext));
|
|
memorySize = numEntries * sizeof(cxoBuffer);
|
|
params->ctxNamespaceBuffers = PyMem_Malloc(memorySize);
|
|
params->ctxNameBuffers = PyMem_Malloc(memorySize);
|
|
params->ctxValueBuffers = PyMem_Malloc(memorySize);
|
|
if (!params->appContext || !params->ctxNamespaceBuffers ||
|
|
!params->ctxNameBuffers || !params->ctxValueBuffers) {
|
|
PyErr_NoMemory();
|
|
return -1;
|
|
}
|
|
|
|
// initialize buffers
|
|
for (i = 0; i < numEntries; i++) {
|
|
cxoBuffer_init(¶ms->ctxNamespaceBuffers[i]);
|
|
cxoBuffer_init(¶ms->ctxNameBuffers[i]);
|
|
cxoBuffer_init(¶ms->ctxValueBuffers[i]);
|
|
}
|
|
params->numAppContext = numEntries;
|
|
|
|
// process each entry
|
|
for (i = 0; i < numEntries; i++) {
|
|
entryObj = PyList_GET_ITEM(context, i);
|
|
if (!PyTuple_Check(entryObj) || PyTuple_GET_SIZE(entryObj) != 3) {
|
|
PyErr_SetString(PyExc_TypeError,
|
|
"appcontext should be a list of 3-tuples");
|
|
return -1;
|
|
}
|
|
if (cxoBuffer_fromObject(¶ms->ctxNamespaceBuffers[i],
|
|
PyTuple_GET_ITEM(entryObj, 0), params->encoding) < 0)
|
|
return -1;
|
|
if (cxoBuffer_fromObject(¶ms->ctxNameBuffers[i],
|
|
PyTuple_GET_ITEM(entryObj, 1), params->encoding) < 0)
|
|
return -1;
|
|
if (cxoBuffer_fromObject(¶ms->ctxValueBuffers[i],
|
|
PyTuple_GET_ITEM(entryObj, 2), params->encoding) < 0)
|
|
return -1;
|
|
entry = ¶ms->appContext[i];
|
|
entry->namespaceName = params->ctxNamespaceBuffers[i].ptr;
|
|
entry->namespaceNameLength = params->ctxNamespaceBuffers[i].size;
|
|
entry->name = params->ctxNameBuffers[i].ptr;
|
|
entry->nameLength = params->ctxNameBuffers[i].size;
|
|
entry->value = params->ctxValueBuffers[i].ptr;
|
|
entry->valueLength = params->ctxValueBuffers[i].size;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnectionParams_processShardingKeyValue()
|
|
// Process a single sharding key value.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnectionParams_processShardingKeyValue(
|
|
cxoConnectionParams *params, PyObject *value,
|
|
dpiShardingKeyColumn *column, cxoBuffer *buffer)
|
|
{
|
|
cxoTransformNum transformNum;
|
|
|
|
transformNum = cxoTransform_getNumFromValue(value);
|
|
if (cxoTransform_fromPython(transformNum, value, &column->value, buffer,
|
|
params->encoding, params->nencoding, NULL, 0) < 0)
|
|
return -1;
|
|
cxoTransform_getTypeInfo(transformNum, &column->oracleTypeNum,
|
|
&column->nativeTypeNum);
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnectionParams_processShardingKey()
|
|
// Process either the sharding key or the super sharding key. A sharding key
|
|
// is expected to be a sequence of values. A null value or a sequence of size
|
|
// 0 is ignored.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnectionParams_processShardingKey(cxoConnectionParams *params,
|
|
PyObject *shardingKeyObj, int isSuperShardingKey)
|
|
{
|
|
dpiShardingKeyColumn *columns;
|
|
uint32_t i, numColumns;
|
|
cxoBuffer *buffers;
|
|
PyObject *value;
|
|
|
|
// validate sharding key
|
|
if (!shardingKeyObj || shardingKeyObj == Py_None)
|
|
return 0;
|
|
if (!PySequence_Check(shardingKeyObj)) {
|
|
PyErr_SetString(PyExc_TypeError, "expecting a sequence");
|
|
return -1;
|
|
}
|
|
numColumns = (uint32_t) PySequence_Size(shardingKeyObj);
|
|
if (numColumns == 0)
|
|
return 0;
|
|
|
|
// allocate memory for the sharding key values
|
|
columns = PyMem_Malloc(numColumns * sizeof(dpiShardingKeyColumn));
|
|
buffers = PyMem_Malloc(numColumns * sizeof(cxoBuffer));
|
|
if (isSuperShardingKey) {
|
|
params->superShardingKeyColumns = columns;
|
|
params->superShardingKeyBuffers = buffers;
|
|
params->numSuperShardingKeyColumns = numColumns;
|
|
} else {
|
|
params->shardingKeyColumns = columns;
|
|
params->shardingKeyBuffers = buffers;
|
|
params->numShardingKeyColumns = numColumns;
|
|
}
|
|
if (!columns || !buffers) {
|
|
PyErr_NoMemory();
|
|
return -1;
|
|
}
|
|
|
|
// process each value
|
|
for (i = 0; i < numColumns; i++) {
|
|
cxoBuffer_init(&buffers[i]);
|
|
value = PySequence_GetItem(shardingKeyObj, i);
|
|
if (!value)
|
|
return -1;
|
|
if (cxoConnectionParams_processShardingKeyValue(params, value,
|
|
&columns[i], &buffers[i]) < 0)
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnectionParams_finalize()
|
|
// Finalize the parameters, freeing any resources that were allocated. The
|
|
// return value is a convenience to the caller.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnectionParams_finalize(cxoConnectionParams *params)
|
|
{
|
|
uint32_t i;
|
|
|
|
cxoBuffer_clear(¶ms->userNameBuffer);
|
|
cxoBuffer_clear(¶ms->passwordBuffer);
|
|
cxoBuffer_clear(¶ms->newPasswordBuffer);
|
|
cxoBuffer_clear(¶ms->dsnBuffer);
|
|
cxoBuffer_clear(¶ms->connectionClassBuffer);
|
|
cxoBuffer_clear(¶ms->editionBuffer);
|
|
cxoBuffer_clear(¶ms->tagBuffer);
|
|
for (i = 0; i < params->numAppContext; i++) {
|
|
cxoBuffer_clear(¶ms->ctxNamespaceBuffers[i]);
|
|
cxoBuffer_clear(¶ms->ctxNameBuffers[i]);
|
|
cxoBuffer_clear(¶ms->ctxValueBuffers[i]);
|
|
}
|
|
params->numAppContext = 0;
|
|
if (params->appContext) {
|
|
PyMem_Free(params->appContext);
|
|
params->appContext = NULL;
|
|
}
|
|
if (params->ctxNamespaceBuffers) {
|
|
PyMem_Free(params->ctxNamespaceBuffers);
|
|
params->ctxNamespaceBuffers = NULL;
|
|
}
|
|
if (params->ctxNameBuffers) {
|
|
PyMem_Free(params->ctxNameBuffers);
|
|
params->ctxNameBuffers = NULL;
|
|
}
|
|
if (params->ctxValueBuffers) {
|
|
PyMem_Free(params->ctxValueBuffers);
|
|
params->ctxValueBuffers = NULL;
|
|
}
|
|
for (i = 0; i < params->numShardingKeyColumns; i++)
|
|
cxoBuffer_clear(¶ms->shardingKeyBuffers[i]);
|
|
if (params->shardingKeyColumns) {
|
|
PyMem_Free(params->shardingKeyColumns);
|
|
params->shardingKeyColumns = NULL;
|
|
}
|
|
if (params->shardingKeyBuffers) {
|
|
PyMem_Free(params->shardingKeyBuffers);
|
|
params->shardingKeyBuffers = NULL;
|
|
}
|
|
for (i = 0; i < params->numSuperShardingKeyColumns; i++)
|
|
cxoBuffer_clear(¶ms->superShardingKeyBuffers[i]);
|
|
if (params->superShardingKeyColumns) {
|
|
PyMem_Free(params->superShardingKeyColumns);
|
|
params->superShardingKeyColumns = NULL;
|
|
}
|
|
if (params->superShardingKeyBuffers) {
|
|
PyMem_Free(params->superShardingKeyBuffers);
|
|
params->superShardingKeyBuffers = NULL;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_isConnected()
|
|
// Determines if the connection object is connected to the database. If not,
|
|
// a Python exception is raised.
|
|
//-----------------------------------------------------------------------------
|
|
int cxoConnection_isConnected(cxoConnection *conn)
|
|
{
|
|
if (!conn->handle) {
|
|
cxoError_raiseFromString(cxoInterfaceErrorException, "not connected");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getAttrText()
|
|
// Get the value of the attribute returned from the given function. The value
|
|
// is assumed to be a text value.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getAttrText(cxoConnection *conn,
|
|
int (*func)(dpiConn *conn, const char **value, uint32_t *valueLength))
|
|
{
|
|
uint32_t valueLength;
|
|
const char *value;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
if ((*func)(conn->handle, &value, &valueLength) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
if (!value)
|
|
Py_RETURN_NONE;
|
|
return cxoPyString_fromEncodedString(value, valueLength,
|
|
conn->encodingInfo.encoding);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setAttrText()
|
|
// Set the value of the attribute using the given function. The value is
|
|
// assumed to be a text value.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setAttrText(cxoConnection *conn, PyObject *value,
|
|
int (*func)(dpiConn *conn, const char *value, uint32_t valueLength))
|
|
{
|
|
cxoBuffer buffer;
|
|
int status;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return -1;
|
|
if (cxoBuffer_fromObject(&buffer, value, conn->encodingInfo.encoding))
|
|
return -1;
|
|
status = (*func)(conn->handle, buffer.ptr, buffer.size);
|
|
cxoBuffer_clear(&buffer);
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnInt();
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_changePassword()
|
|
// Change the password for the given connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_changePassword(cxoConnection *conn,
|
|
PyObject *args)
|
|
{
|
|
cxoBuffer usernameBuffer, oldPasswordBuffer, newPasswordBuffer;
|
|
PyObject *oldPasswordObj, *newPasswordObj;
|
|
int status;
|
|
|
|
// parse the arguments
|
|
if (!PyArg_ParseTuple(args, "OO", &oldPasswordObj, &newPasswordObj))
|
|
return NULL;
|
|
|
|
// populate buffers
|
|
cxoBuffer_init(&usernameBuffer);
|
|
cxoBuffer_init(&oldPasswordBuffer);
|
|
cxoBuffer_init(&newPasswordBuffer);
|
|
if (cxoBuffer_fromObject(&usernameBuffer, conn->username,
|
|
conn->encodingInfo.encoding) < 0 ||
|
|
cxoBuffer_fromObject(&oldPasswordBuffer, oldPasswordObj,
|
|
conn->encodingInfo.encoding) < 0 ||
|
|
cxoBuffer_fromObject(&newPasswordBuffer, newPasswordObj,
|
|
conn->encodingInfo.encoding) < 0) {
|
|
cxoBuffer_clear(&usernameBuffer);
|
|
cxoBuffer_clear(&oldPasswordBuffer);
|
|
cxoBuffer_clear(&newPasswordBuffer);
|
|
return NULL;
|
|
}
|
|
|
|
// change the password
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_changePassword(conn->handle, usernameBuffer.ptr,
|
|
usernameBuffer.size, oldPasswordBuffer.ptr, oldPasswordBuffer.size,
|
|
newPasswordBuffer.ptr, newPasswordBuffer.size);
|
|
Py_END_ALLOW_THREADS
|
|
cxoBuffer_clear(&usernameBuffer);
|
|
cxoBuffer_clear(&oldPasswordBuffer);
|
|
cxoBuffer_clear(&newPasswordBuffer);
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_new()
|
|
// Create a new connection object and return it.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_new(PyTypeObject *type, PyObject *args,
|
|
PyObject *keywordArgs)
|
|
{
|
|
return type->tp_alloc(type, 0);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_splitComponent()
|
|
// Split the component out of the source and replace the source with the
|
|
// characters up to the split string and put the characters after the split
|
|
// string in to the target.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_splitComponent(PyObject **sourceObj,
|
|
PyObject **targetObj, const char *splitString)
|
|
{
|
|
PyObject *temp, *posObj;
|
|
Py_ssize_t size, pos;
|
|
|
|
if (!*sourceObj || *targetObj)
|
|
return 0;
|
|
posObj = PyObject_CallMethod(*sourceObj, "find", "s", splitString);
|
|
if (!posObj)
|
|
return -1;
|
|
pos = PyInt_AsLong(posObj);
|
|
Py_DECREF(posObj);
|
|
if (PyErr_Occurred())
|
|
return -1;
|
|
if (pos >= 0) {
|
|
size = PySequence_Size(*sourceObj);
|
|
if (PyErr_Occurred())
|
|
return -1;
|
|
*targetObj = PySequence_GetSlice(*sourceObj, pos + 1, size);
|
|
if (!*targetObj)
|
|
return -1;
|
|
temp = PySequence_GetSlice(*sourceObj, 0, pos);
|
|
if (!temp)
|
|
return -1;
|
|
*sourceObj = temp;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_init()
|
|
// Initialize the connection members.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_init(cxoConnection *conn, PyObject *args,
|
|
PyObject *keywordArgs)
|
|
{
|
|
PyObject *tagObj, *matchAnyTagObj, *threadedObj, *eventsObj, *contextObj;
|
|
PyObject *usernameObj, *passwordObj, *dsnObj, *cclassObj, *editionObj;
|
|
PyObject *shardingKeyObj, *superShardingKeyObj;
|
|
dpiCommonCreateParams dpiCommonParams;
|
|
dpiConnCreateParams dpiCreateParams;
|
|
unsigned long long externalHandle;
|
|
cxoConnectionParams params;
|
|
PyObject *newPasswordObj;
|
|
cxoSessionPool *pool;
|
|
int status, temp;
|
|
|
|
// define keyword arguments
|
|
static char *keywordList[] = { "user", "password", "dsn", "mode",
|
|
"handle", "pool", "threaded", "events", "cclass", "purity",
|
|
"newpassword", "encoding", "nencoding", "edition", "appcontext",
|
|
"tag", "matchanytag", "shardingkey", "supershardingkey", NULL };
|
|
|
|
// parse arguments
|
|
pool = NULL;
|
|
externalHandle = 0;
|
|
threadedObj = eventsObj = newPasswordObj = usernameObj = NULL;
|
|
passwordObj = dsnObj = cclassObj = editionObj = tagObj = NULL;
|
|
matchAnyTagObj = contextObj = shardingKeyObj = superShardingKeyObj = NULL;
|
|
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_initConnCreateParams(cxoDpiContext, &dpiCreateParams) < 0)
|
|
return cxoError_raiseAndReturnInt();
|
|
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs,
|
|
"|OOOiKO!OOOiOssOOOOOO", keywordList, &usernameObj, &passwordObj,
|
|
&dsnObj, &dpiCreateParams.authMode, &externalHandle,
|
|
&cxoPyTypeSessionPool, &pool, &threadedObj, &eventsObj, &cclassObj,
|
|
&dpiCreateParams.purity, &newPasswordObj,
|
|
&dpiCommonParams.encoding, &dpiCommonParams.nencoding, &editionObj,
|
|
&contextObj, &tagObj, &matchAnyTagObj, &shardingKeyObj,
|
|
&superShardingKeyObj))
|
|
return -1;
|
|
dpiCreateParams.externalHandle = (void*) externalHandle;
|
|
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(matchAnyTagObj, 0,
|
|
&dpiCreateParams.matchAnyTag) < 0)
|
|
return -1;
|
|
|
|
// keep a copy of the user name and connect string (DSN)
|
|
Py_XINCREF(usernameObj);
|
|
conn->username = usernameObj;
|
|
Py_XINCREF(dsnObj);
|
|
conn->dsn = dsnObj;
|
|
|
|
// perform some parsing, if necessary
|
|
if (cxoConnection_splitComponent(&conn->username, &passwordObj, "/") < 0)
|
|
return -1;
|
|
if (cxoConnection_splitComponent(&passwordObj, &conn->dsn, "@") < 0)
|
|
return -1;
|
|
|
|
// setup parameters
|
|
cxoConnectionParams_initialize(¶ms);
|
|
if (pool) {
|
|
dpiCreateParams.pool = pool->handle;
|
|
params.encoding = pool->encodingInfo.encoding;
|
|
params.nencoding = pool->encodingInfo.nencoding;
|
|
} else {
|
|
params.encoding =
|
|
cxoUtils_getAdjustedEncoding(dpiCommonParams.encoding);
|
|
params.nencoding =
|
|
cxoUtils_getAdjustedEncoding(dpiCommonParams.nencoding);
|
|
}
|
|
if (cxoConnectionParams_processContext(¶ms, contextObj) < 0)
|
|
return cxoConnectionParams_finalize(¶ms);
|
|
if (cxoConnectionParams_processShardingKey(¶ms, shardingKeyObj, 0) < 0)
|
|
return cxoConnectionParams_finalize(¶ms);
|
|
if (cxoConnectionParams_processShardingKey(¶ms, superShardingKeyObj,
|
|
1) < 0)
|
|
return cxoConnectionParams_finalize(¶ms);
|
|
if (cxoBuffer_fromObject(¶ms.userNameBuffer, conn->username,
|
|
params.encoding) < 0 ||
|
|
cxoBuffer_fromObject(¶ms.passwordBuffer, passwordObj,
|
|
params.encoding) < 0 ||
|
|
cxoBuffer_fromObject(¶ms.dsnBuffer, conn->dsn,
|
|
params.encoding) < 0 ||
|
|
cxoBuffer_fromObject(¶ms.connectionClassBuffer, cclassObj,
|
|
params.encoding) < 0 ||
|
|
cxoBuffer_fromObject(¶ms.newPasswordBuffer, newPasswordObj,
|
|
params.encoding) < 0 ||
|
|
cxoBuffer_fromObject(¶ms.editionBuffer, editionObj,
|
|
params.encoding) < 0 ||
|
|
cxoBuffer_fromObject(¶ms.tagBuffer, tagObj,
|
|
params.encoding) < 0)
|
|
return cxoConnectionParams_finalize(¶ms);
|
|
if (params.userNameBuffer.size == 0 && params.passwordBuffer.size == 0)
|
|
dpiCreateParams.externalAuth = 1;
|
|
dpiCreateParams.connectionClass = params.connectionClassBuffer.ptr;
|
|
dpiCreateParams.connectionClassLength = params.connectionClassBuffer.size;
|
|
dpiCreateParams.newPassword = params.newPasswordBuffer.ptr;
|
|
dpiCreateParams.newPasswordLength = params.newPasswordBuffer.size;
|
|
dpiCommonParams.edition = params.editionBuffer.ptr;
|
|
dpiCommonParams.editionLength = params.editionBuffer.size;
|
|
dpiCreateParams.tag = params.tagBuffer.ptr;
|
|
dpiCreateParams.tagLength = params.tagBuffer.size;
|
|
dpiCreateParams.appContext = params.appContext;
|
|
dpiCreateParams.numAppContext = params.numAppContext;
|
|
dpiCreateParams.shardingKeyColumns = params.shardingKeyColumns;
|
|
dpiCreateParams.numShardingKeyColumns = params.numShardingKeyColumns;
|
|
dpiCreateParams.superShardingKeyColumns = params.superShardingKeyColumns;
|
|
dpiCreateParams.numSuperShardingKeyColumns =
|
|
params.numSuperShardingKeyColumns;
|
|
if (pool && !pool->homogeneous && pool->username && conn->username) {
|
|
temp = PyObject_RichCompareBool(conn->username, pool->username, Py_EQ);
|
|
if (temp < 0)
|
|
return cxoConnectionParams_finalize(¶ms);
|
|
if (temp)
|
|
params.userNameBuffer.size = 0;
|
|
}
|
|
|
|
// create connection
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_create(cxoDpiContext, params.userNameBuffer.ptr,
|
|
params.userNameBuffer.size, params.passwordBuffer.ptr,
|
|
params.passwordBuffer.size, params.dsnBuffer.ptr,
|
|
params.dsnBuffer.size, &dpiCommonParams, &dpiCreateParams,
|
|
&conn->handle);
|
|
Py_END_ALLOW_THREADS
|
|
cxoConnectionParams_finalize(¶ms);
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnInt();
|
|
|
|
// determine encodings to use
|
|
if (pool)
|
|
conn->encodingInfo = pool->encodingInfo;
|
|
else {
|
|
if (dpiConn_getEncodingInfo(conn->handle, &conn->encodingInfo) < 0)
|
|
return cxoError_raiseAndReturnInt();
|
|
conn->encodingInfo.encoding =
|
|
cxoUtils_getAdjustedEncoding(conn->encodingInfo.encoding);
|
|
conn->encodingInfo.nencoding =
|
|
cxoUtils_getAdjustedEncoding(conn->encodingInfo.nencoding);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_free()
|
|
// Deallocate the connection, disconnecting from the database if necessary.
|
|
//-----------------------------------------------------------------------------
|
|
static void cxoConnection_free(cxoConnection *conn)
|
|
{
|
|
if (conn->handle) {
|
|
Py_BEGIN_ALLOW_THREADS
|
|
dpiConn_release(conn->handle);
|
|
Py_END_ALLOW_THREADS
|
|
conn->handle = NULL;
|
|
}
|
|
Py_CLEAR(conn->sessionPool);
|
|
Py_CLEAR(conn->username);
|
|
Py_CLEAR(conn->dsn);
|
|
Py_CLEAR(conn->version);
|
|
Py_CLEAR(conn->inputTypeHandler);
|
|
Py_CLEAR(conn->outputTypeHandler);
|
|
Py_TYPE(conn)->tp_free((PyObject*) conn);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_repr()
|
|
// Return a string representation of the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_repr(cxoConnection *connection)
|
|
{
|
|
PyObject *module, *name, *result;
|
|
|
|
if (cxoUtils_getModuleAndName(Py_TYPE(connection), &module, &name) < 0)
|
|
return NULL;
|
|
if (connection->username && connection->username != Py_None &&
|
|
connection->dsn && connection->dsn != Py_None) {
|
|
result = cxoUtils_formatString("<%s.%s to %s@%s>",
|
|
PyTuple_Pack(4, module, name, connection->username,
|
|
connection->dsn));
|
|
} else if (connection->username && connection->username != Py_None) {
|
|
result = cxoUtils_formatString("<%s.%s to user %s@local>",
|
|
PyTuple_Pack(3, module, name, connection->username));
|
|
} else {
|
|
result = cxoUtils_formatString("<%s.%s to externally identified user>",
|
|
PyTuple_Pack(2, module, name));
|
|
}
|
|
Py_DECREF(module);
|
|
Py_DECREF(name);
|
|
return result;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getStmtCacheSize()
|
|
// Return the Oracle statement cache size.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getStmtCacheSize(cxoConnection* conn, void* arg)
|
|
{
|
|
uint32_t cacheSize;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
if (dpiConn_getStmtCacheSize(conn->handle, &cacheSize) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
return PyInt_FromLong(cacheSize);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setStmtCacheSize()
|
|
// Set the Oracle statement cache size.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setStmtCacheSize(cxoConnection* conn, PyObject *value,
|
|
void* arg)
|
|
{
|
|
uint32_t cacheSize;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return -1;
|
|
if (!PyInt_Check(value)) {
|
|
PyErr_SetString(PyExc_TypeError, "value must be an integer");
|
|
return -1;
|
|
}
|
|
cacheSize = (uint32_t) PyInt_AsLong(value);
|
|
if (dpiConn_setStmtCacheSize(conn->handle, cacheSize) < 0)
|
|
return cxoError_raiseAndReturnInt();
|
|
return 0;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getType()
|
|
// Return a type object given its name.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getType(cxoConnection *conn, PyObject *nameObj)
|
|
{
|
|
return (PyObject*) cxoObjectType_newByName(conn, nameObj);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_createLob()
|
|
// Create a new temporary LOB and return it.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_createLob(cxoConnection *conn,
|
|
PyObject *lobType)
|
|
{
|
|
dpiOracleTypeNum oracleTypeNum;
|
|
dpiLob *handle;
|
|
PyObject *lob;
|
|
|
|
// verify connection is open
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
|
|
// verify the LOB type
|
|
if (lobType == (PyObject*) &cxoPyTypeClobVar)
|
|
oracleTypeNum = DPI_ORACLE_TYPE_CLOB;
|
|
else if (lobType == (PyObject*) &cxoPyTypeBlobVar)
|
|
oracleTypeNum = DPI_ORACLE_TYPE_BLOB;
|
|
else if (lobType == (PyObject*) &cxoPyTypeNclobVar)
|
|
oracleTypeNum = DPI_ORACLE_TYPE_NCLOB;
|
|
else {
|
|
PyErr_SetString(PyExc_TypeError,
|
|
"parameter should be one of cx_Oracle.CLOB, cx_Oracle.BLOB "
|
|
"or cx_Oracle.NCLOB");
|
|
return NULL;
|
|
}
|
|
|
|
// create a temporary LOB
|
|
if (dpiConn_newTempLob(conn->handle, oracleTypeNum, &handle) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
lob = cxoLob_new(conn, oracleTypeNum, handle);
|
|
if (!lob)
|
|
dpiLob_release(handle);
|
|
return lob;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getVersion()
|
|
// Retrieve the version of the database and return it. Note that this
|
|
// function also places the result in the associated dictionary so it is only
|
|
// calculated once.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getVersion(cxoConnection *conn, void *unused)
|
|
{
|
|
uint32_t releaseStringLength;
|
|
dpiVersionInfo versionInfo;
|
|
const char *releaseString;
|
|
char buffer[25];
|
|
int status;
|
|
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_getServerVersion(conn->handle, &releaseString,
|
|
&releaseStringLength, &versionInfo);
|
|
Py_END_ALLOW_THREADS
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.%d", versionInfo.versionNum,
|
|
versionInfo.releaseNum, versionInfo.updateNum,
|
|
versionInfo.portReleaseNum, versionInfo.portUpdateNum);
|
|
return cxoPyString_fromAscii(buffer);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getEncoding()
|
|
// Return the encoding associated with the environment of the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getEncoding(cxoConnection *conn, void *unused)
|
|
{
|
|
return cxoPyString_fromAscii(conn->encodingInfo.encoding);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getLTXID()
|
|
// Return the logical transaction id used with Transaction Guard.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getLTXID(cxoConnection *conn, void *unused)
|
|
{
|
|
uint32_t ltxidLength;
|
|
const char *ltxid;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
if (dpiConn_getLTXID(conn->handle, <xid, <xidLength) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
return PyBytes_FromStringAndSize(ltxid, ltxidLength);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getHandle()
|
|
// Return the OCI handle used by the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getHandle(cxoConnection *conn, void *unused)
|
|
{
|
|
void *handle;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
if (dpiConn_getHandle(conn->handle, &handle) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
return PyLong_FromUnsignedLongLong((unsigned long long) handle);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getNationalEncoding()
|
|
// Return the national encoding associated with the environment of the
|
|
// connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getNationalEncoding(cxoConnection *conn,
|
|
void *unused)
|
|
{
|
|
return cxoPyString_fromAscii(conn->encodingInfo.nencoding);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getMaxBytesPerCharacter()
|
|
// Return the maximum number of bytes per character.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getMaxBytesPerCharacter(cxoConnection *conn,
|
|
void *unused)
|
|
{
|
|
return PyInt_FromLong(conn->encodingInfo.maxBytesPerCharacter);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_close()
|
|
// Close the connection, disconnecting from the database.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_close(cxoConnection *conn, PyObject *args)
|
|
{
|
|
int status;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_close(conn->handle, DPI_MODE_CONN_CLOSE_DEFAULT, NULL, 0);
|
|
Py_END_ALLOW_THREADS
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_commit()
|
|
// Commit the transaction on the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_commit(cxoConnection *conn, PyObject *args)
|
|
{
|
|
int status;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_commit(conn->handle);
|
|
Py_END_ALLOW_THREADS
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_begin()
|
|
// Begin a new transaction on the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_begin(cxoConnection *conn, PyObject *args)
|
|
{
|
|
uint32_t transactionIdLength, branchIdLength;
|
|
const char *transactionId, *branchId;
|
|
int formatId, status;
|
|
|
|
// parse the arguments
|
|
formatId = -1;
|
|
transactionId = branchId = NULL;
|
|
transactionIdLength = branchIdLength = 0;
|
|
if (!PyArg_ParseTuple(args, "|is#s#", &formatId, &transactionId,
|
|
&transactionIdLength, &branchId, &branchIdLength))
|
|
return NULL;
|
|
|
|
// make sure we are actually connected
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
|
|
// begin the distributed transaction
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_beginDistribTrans(conn->handle, formatId, transactionId,
|
|
transactionIdLength, branchId, branchIdLength);
|
|
Py_END_ALLOW_THREADS
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_prepare()
|
|
// Commit the transaction on the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_prepare(cxoConnection *conn, PyObject *args)
|
|
{
|
|
int status, commitNeeded;
|
|
|
|
// make sure we are actually connected
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
|
|
// perform the prepare
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_prepareDistribTrans(conn->handle, &commitNeeded);
|
|
Py_END_ALLOW_THREADS
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
// return whether a commit is needed in order to allow for avoiding the
|
|
// call to commit() which will fail with ORA-24756 (transaction does not
|
|
// exist)
|
|
return PyBool_FromLong(commitNeeded);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_rollback()
|
|
// Rollback the transaction on the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_rollback(cxoConnection *conn, PyObject *args)
|
|
{
|
|
int status;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_rollback(conn->handle);
|
|
Py_END_ALLOW_THREADS
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_newCursor()
|
|
// Create a new cursor (statement) referencing the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_newCursor(cxoConnection *conn, PyObject *args,
|
|
PyObject *keywordArgs)
|
|
{
|
|
PyObject *createArgs, *result, *arg;
|
|
Py_ssize_t numArgs = 0, i;
|
|
|
|
if (args)
|
|
numArgs = PyTuple_GET_SIZE(args);
|
|
createArgs = PyTuple_New(1 + numArgs);
|
|
if (!createArgs)
|
|
return NULL;
|
|
Py_INCREF(conn);
|
|
PyTuple_SET_ITEM(createArgs, 0, (PyObject*) conn);
|
|
for (i = 0; i < numArgs; i++) {
|
|
arg = PyTuple_GET_ITEM(args, i);
|
|
Py_INCREF(arg);
|
|
PyTuple_SET_ITEM(createArgs, i + 1, arg);
|
|
}
|
|
result = PyObject_Call( (PyObject*) &cxoPyTypeCursor, createArgs,
|
|
keywordArgs);
|
|
Py_DECREF(createArgs);
|
|
return result;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_cancel()
|
|
// Cause Oracle to issue an immediate (asynchronous) abort of any currently
|
|
// executing statement.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_cancel(cxoConnection *conn, PyObject *args)
|
|
{
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
if (dpiConn_breakExecution(conn->handle) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_newEnqueueOptions()
|
|
// Creates a new enqueue options object and returns it.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_newEnqueueOptions(cxoConnection *conn,
|
|
PyObject *args)
|
|
{
|
|
return (PyObject*) cxoEnqOptions_new(conn);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_newDequeueOptions()
|
|
// Creates a new dequeue options object and returns it.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_newDequeueOptions(cxoConnection *conn,
|
|
PyObject *args)
|
|
{
|
|
return (PyObject*) cxoDeqOptions_new(conn);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_newMessageProperties()
|
|
// Creates a new message properties object and returns it.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_newMessageProperties(cxoConnection *conn,
|
|
PyObject *args)
|
|
{
|
|
return (PyObject*) cxoMsgProps_new(conn);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_dequeue()
|
|
// Dequeues a message using Advanced Queuing capabilities. The message ID is
|
|
// returned if a message is available or None if no message is available.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_dequeue(cxoConnection *conn, PyObject* args,
|
|
PyObject* keywordArgs)
|
|
{
|
|
static char *keywordList[] = { "name", "options", "msgproperties",
|
|
"payload", NULL };
|
|
cxoMsgProps *propertiesObj;
|
|
const char *messageIdValue;
|
|
cxoDeqOptions *optionsObj;
|
|
uint32_t messageIdLength;
|
|
cxoObject *payloadObj;
|
|
cxoBuffer nameBuffer;
|
|
PyObject *nameObj;
|
|
int status;
|
|
|
|
// parse arguments
|
|
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "OO!O!O!", keywordList,
|
|
&nameObj, &cxoPyTypeDeqOptions, &optionsObj, &cxoPyTypeMsgProps,
|
|
&propertiesObj, &cxoPyTypeObject, &payloadObj))
|
|
return NULL;
|
|
if (cxoBuffer_fromObject(&nameBuffer, nameObj,
|
|
conn->encodingInfo.encoding) < 0)
|
|
return NULL;
|
|
|
|
// dequeue payload
|
|
status = dpiConn_deqObject(conn->handle, nameBuffer.ptr, nameBuffer.size,
|
|
optionsObj->handle, propertiesObj->handle, payloadObj->handle,
|
|
&messageIdValue, &messageIdLength);
|
|
cxoBuffer_clear(&nameBuffer);
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
// return message id
|
|
if (!messageIdValue)
|
|
Py_RETURN_NONE;
|
|
return PyBytes_FromStringAndSize(messageIdValue, messageIdLength);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_enqueue()
|
|
// Enqueues a message using Advanced Queuing capabilities. The message ID is
|
|
// returned.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_enqueue(cxoConnection *conn, PyObject* args,
|
|
PyObject* keywordArgs)
|
|
{
|
|
static char *keywordList[] = { "name", "options", "msgproperties",
|
|
"payload", NULL };
|
|
cxoMsgProps *propertiesObj;
|
|
const char *messageIdValue;
|
|
cxoEnqOptions *optionsObj;
|
|
uint32_t messageIdLength;
|
|
cxoObject *payloadObj;
|
|
cxoBuffer nameBuffer;
|
|
PyObject *nameObj;
|
|
int status;
|
|
|
|
// parse arguments
|
|
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "OO!O!O!", keywordList,
|
|
&nameObj, &cxoPyTypeEnqOptions, &optionsObj, &cxoPyTypeMsgProps,
|
|
&propertiesObj, &cxoPyTypeObject, &payloadObj))
|
|
return NULL;
|
|
if (cxoBuffer_fromObject(&nameBuffer, nameObj,
|
|
conn->encodingInfo.encoding) < 0)
|
|
return NULL;
|
|
|
|
// enqueue payload
|
|
status = dpiConn_enqObject(conn->handle, nameBuffer.ptr, nameBuffer.size,
|
|
optionsObj->handle, propertiesObj->handle, payloadObj->handle,
|
|
&messageIdValue, &messageIdLength);
|
|
cxoBuffer_clear(&nameBuffer);
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
// return message id
|
|
return PyBytes_FromStringAndSize(messageIdValue, messageIdLength);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_contextManagerEnter()
|
|
// Called when the connection is used as a context manager and simply returns
|
|
// itconn as a convenience to the caller.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_contextManagerEnter(cxoConnection *conn,
|
|
PyObject* args)
|
|
{
|
|
Py_INCREF(conn);
|
|
return (PyObject*) conn;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_contextManagerExit()
|
|
// Called when the connection is used as a context manager and if any
|
|
// exception a rollback takes place; otherwise, a commit takes place.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_contextManagerExit(cxoConnection *conn,
|
|
PyObject* args)
|
|
{
|
|
PyObject *excType, *excValue, *excTraceback, *result;
|
|
|
|
if (!PyArg_ParseTuple(args, "OOO", &excType, &excValue, &excTraceback))
|
|
return NULL;
|
|
if (cxoFutureObj && cxoFutureObj->contextManagerClose)
|
|
result = cxoConnection_close(conn, NULL);
|
|
else if (excType == Py_None && excValue == Py_None &&
|
|
excTraceback == Py_None)
|
|
result = cxoConnection_commit(conn, NULL);
|
|
else result = cxoConnection_rollback(conn, NULL);
|
|
if (!result)
|
|
return NULL;
|
|
Py_DECREF(result);
|
|
|
|
Py_INCREF(Py_False);
|
|
return Py_False;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_ping()
|
|
// Makes a round trip call to the server to confirm that the connection and
|
|
// server are active.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_ping(cxoConnection *conn, PyObject* args)
|
|
{
|
|
int status;
|
|
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
Py_BEGIN_ALLOW_THREADS
|
|
status = dpiConn_ping(conn->handle);
|
|
Py_END_ALLOW_THREADS
|
|
if (status < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_shutdown()
|
|
// Shuts down the database. Note that this must be done in two phases except
|
|
// in the situation where the instance is aborted.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_shutdown(cxoConnection *conn, PyObject* args,
|
|
PyObject* keywordArgs)
|
|
{
|
|
static char *keywordList[] = { "mode", NULL };
|
|
dpiShutdownMode mode;
|
|
|
|
// parse arguments
|
|
mode = DPI_MODE_SHUTDOWN_DEFAULT;
|
|
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|i", keywordList,
|
|
&mode))
|
|
return NULL;
|
|
|
|
// make sure we are actually connected
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
|
|
// perform the work
|
|
if (dpiConn_shutdownDatabase(conn->handle, mode) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_startup()
|
|
// Starts up the database, equivalent to "startup nomount" in SQL*Plus.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_startup(cxoConnection *conn, PyObject* args,
|
|
PyObject* keywordArgs)
|
|
{
|
|
static char *keywordList[] = { "force", "restrict", NULL };
|
|
PyObject *forceObj, *restrictObj;
|
|
dpiStartupMode mode;
|
|
int temp;
|
|
|
|
// parse arguments
|
|
forceObj = restrictObj = NULL;
|
|
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|OO", keywordList,
|
|
&forceObj, &restrictObj))
|
|
return NULL;
|
|
|
|
// set the flags to use during startup
|
|
mode = DPI_MODE_STARTUP_DEFAULT;
|
|
if (cxoUtils_getBooleanValue(forceObj, 0, &temp) < 0)
|
|
return NULL;
|
|
if (temp)
|
|
mode |= DPI_MODE_STARTUP_FORCE;
|
|
if (cxoUtils_getBooleanValue(restrictObj, 0, &temp) < 0)
|
|
return NULL;
|
|
if (temp)
|
|
mode |= DPI_MODE_STARTUP_RESTRICT;
|
|
|
|
// make sure we are actually connected
|
|
if (cxoConnection_isConnected(conn) < 0)
|
|
return NULL;
|
|
|
|
// perform the work
|
|
if (dpiConn_startupDatabase(conn->handle, mode) < 0)
|
|
return cxoError_raiseAndReturnNull();
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_subscribe()
|
|
// Create a subscription to events that take place in the database.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_subscribe(cxoConnection *conn, PyObject* args,
|
|
PyObject* keywordArgs)
|
|
{
|
|
static char *keywordList[] = { "namespace", "protocol", "callback",
|
|
"timeout", "operations", "port", "qos", "ipAddress", NULL };
|
|
uint32_t namespace, protocol, port, timeout, operations, qos;
|
|
PyObject *callback, *ipAddress;
|
|
|
|
timeout = port = qos = 0;
|
|
callback = ipAddress = NULL;
|
|
namespace = DPI_SUBSCR_NAMESPACE_DBCHANGE;
|
|
protocol = DPI_SUBSCR_PROTO_CALLBACK;
|
|
operations = DPI_OPCODE_ALL_OPS;
|
|
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|iiOiiiiO",
|
|
keywordList, &namespace, &protocol, &callback, &timeout,
|
|
&operations, &port, &qos, &ipAddress))
|
|
return NULL;
|
|
return (PyObject*) cxoSubscr_new(conn, namespace, protocol, ipAddress,
|
|
port, callback, timeout, operations, qos);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getCurrentSchema()
|
|
// Return the current schema associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getCurrentSchema(cxoConnection* conn,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_getAttrText(conn, dpiConn_getCurrentSchema);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getEdition()
|
|
// Return the edition associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getEdition(cxoConnection* conn, void* unused)
|
|
{
|
|
return cxoConnection_getAttrText(conn, dpiConn_getEdition);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getExternalName()
|
|
// Return the external name associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getExternalName(cxoConnection* conn,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_getAttrText(conn, dpiConn_getExternalName);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getInternalName()
|
|
// Return the internal name associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getInternalName(cxoConnection* conn,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_getAttrText(conn, dpiConn_getInternalName);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_getException()
|
|
// Return the requested exception.
|
|
//-----------------------------------------------------------------------------
|
|
static PyObject *cxoConnection_getException(cxoConnection *conn, void *arg)
|
|
{
|
|
PyObject *exc = * (PyObject**) arg;
|
|
|
|
Py_INCREF(exc);
|
|
return exc;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setAction()
|
|
// Set the action associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setAction(cxoConnection* conn, PyObject *value,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setAction);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setClientIdentifier()
|
|
// Set the client identifier associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setClientIdentifier(cxoConnection* conn,
|
|
PyObject *value, void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setClientIdentifier);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setClientInfo()
|
|
// Set the client info associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setClientInfo(cxoConnection* conn, PyObject *value,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setClientInfo);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setCurrentSchema()
|
|
// Set the current schema associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setCurrentSchema(cxoConnection* conn, PyObject *value,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setCurrentSchema);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setDbOp()
|
|
// Set the database operation associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setDbOp(cxoConnection* conn, PyObject *value,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setDbOp);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setExternalName()
|
|
// Set the external name associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setExternalName(cxoConnection* conn, PyObject *value,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setExternalName);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setInternalName()
|
|
// Set the internal name associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setInternalName(cxoConnection* conn, PyObject *value,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setInternalName);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cxoConnection_setModule()
|
|
// Set the module associated with the connection.
|
|
//-----------------------------------------------------------------------------
|
|
static int cxoConnection_setModule(cxoConnection* conn, PyObject *value,
|
|
void* unused)
|
|
{
|
|
return cxoConnection_setAttrText(conn, value, dpiConn_setModule);
|
|
}
|
|
|