Last public release from Computronix.
|
@ -0,0 +1,328 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Callback.c
|
||||
// Definition of OCI callback functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_NewVariable()
|
||||
// Return a new variable from a callback.
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_Variable *Callback_NewVariable(
|
||||
udt_Connection *connection, // connection to use
|
||||
ub2 oracleType, // Oracle type of data
|
||||
ub4 maxLength, // maximum length of elements
|
||||
void *data, // data pointer
|
||||
void *indicator, // indicator pointer
|
||||
ub2 *returnCode, // return code pointer
|
||||
ub2 *actualLength) // actual length pointer
|
||||
{
|
||||
udt_VariableType *type;
|
||||
udt_Variable *var;
|
||||
|
||||
// determine the type to use
|
||||
type = Variable_TypeByOracleDataType(oracleType, SQLCS_IMPLICIT);
|
||||
if (!type)
|
||||
return NULL;
|
||||
|
||||
// attempt to allocate the object
|
||||
var = PyObject_NEW(udt_Variable, type->pythonType);
|
||||
if (!var)
|
||||
return NULL;
|
||||
|
||||
// perform basic initialization
|
||||
// note that the number of allocated elements is set arbitrarily high
|
||||
// because the OCI doesn't give information about how many elements are
|
||||
// actually allocated; that has to be implied by the number of rows
|
||||
// passed to OCIStmtFetch and OCIStmtExecute
|
||||
Py_INCREF(connection->environment);
|
||||
var->environment = connection->environment;
|
||||
var->boundCursorHandle = NULL;
|
||||
var->bindHandle = NULL;
|
||||
var->defineHandle = NULL;
|
||||
var->boundName = NULL;
|
||||
var->allocatedElements = 2147483647;
|
||||
var->actualElements = 0;
|
||||
var->isArray = 0;
|
||||
var->isAllocatedInternally = 0;
|
||||
var->type = type;
|
||||
var->indicator = indicator;
|
||||
var->data = data;
|
||||
var->actualLength = actualLength;
|
||||
var->returnCode = returnCode;
|
||||
var->maxLength = type->elementLength;
|
||||
if (type->isVariableLength)
|
||||
var->maxLength = maxLength;
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_BindByNameArgs()
|
||||
// Return the arguments to be passed when OCIBindByName is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *Callback_BindByNameArgs(
|
||||
udt_Connection *connection, // connection to use
|
||||
va_list args) // arguments to OCI function
|
||||
{
|
||||
ub4 nameLength, allocatedElements, *actualElements;
|
||||
ub2 dataType, *actualLength, *returnCode;
|
||||
dvoid *indicator, *value;
|
||||
OCIBind **bindHandlePtr;
|
||||
OCIError *errorHandle;
|
||||
udt_Variable *var;
|
||||
PyObject *result;
|
||||
sb4 valueLength;
|
||||
OCIStmt *handle;
|
||||
text *name;
|
||||
|
||||
handle = va_arg(args, OCIStmt*);
|
||||
bindHandlePtr = va_arg(args, OCIBind**);
|
||||
errorHandle = va_arg(args, OCIError*);
|
||||
name = va_arg(args, text*);
|
||||
nameLength = va_arg(args, ub4);
|
||||
value = va_arg(args, dvoid*);
|
||||
valueLength = va_arg(args, sb4);
|
||||
dataType = va_arg(args, int);
|
||||
indicator = va_arg(args, dvoid*);
|
||||
actualLength = va_arg(args, ub2*);
|
||||
returnCode = va_arg(args, ub2*);
|
||||
allocatedElements = va_arg(args, ub4);
|
||||
actualElements = va_arg(args, ub4*);
|
||||
|
||||
var = Callback_NewVariable(connection, dataType, valueLength, value,
|
||||
indicator, returnCode, actualLength);
|
||||
if (!var)
|
||||
return NULL;
|
||||
if (allocatedElements > 0) {
|
||||
var->isArray = 1;
|
||||
var->actualElements = *actualElements;
|
||||
}
|
||||
|
||||
result = Py_BuildValue("ls#O", handle, name, nameLength, var);
|
||||
Py_DECREF(var);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_DefineByPosArgs()
|
||||
// Return the arguments to be passed when OCIDefineByPos is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *Callback_DefineByPosArgs(
|
||||
udt_Connection *connection, // connection to use
|
||||
va_list args) // arguments to OCI function
|
||||
{
|
||||
ub2 dataType, *actualLength, *returnCode;
|
||||
OCIDefine **defineHandle;
|
||||
dvoid *indicator, *value;
|
||||
OCIError *errorHandle;
|
||||
udt_Variable *var;
|
||||
PyObject *result;
|
||||
OCIStmt *handle;
|
||||
sb4 valueLength;
|
||||
ub4 position;
|
||||
|
||||
handle = va_arg(args, OCIStmt*);
|
||||
defineHandle = va_arg(args, OCIDefine**);
|
||||
errorHandle = va_arg(args, OCIError*);
|
||||
position = va_arg(args, ub4);
|
||||
value = va_arg(args, dvoid*);
|
||||
valueLength = va_arg(args, sb4);
|
||||
dataType = va_arg(args, int);
|
||||
indicator = va_arg(args, dvoid*);
|
||||
actualLength = va_arg(args, ub2*);
|
||||
returnCode = va_arg(args, ub2*);
|
||||
|
||||
// create a variable
|
||||
var = Callback_NewVariable(connection, dataType, valueLength, value,
|
||||
indicator, returnCode, actualLength);
|
||||
if (!var)
|
||||
return NULL;
|
||||
|
||||
result = Py_BuildValue("liO", handle, position, var);
|
||||
Py_DECREF(var);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_ExecuteArgs()
|
||||
// Return the arguments to be passed when OCIStmtExecute is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *Callback_ExecuteArgs(
|
||||
va_list args) // arguments to OCI function
|
||||
{
|
||||
OCISvcCtx* serviceContextHandle;
|
||||
OCIError *errorHandle;
|
||||
ub4 iters, rowoff;
|
||||
OCIStmt *handle;
|
||||
|
||||
serviceContextHandle = va_arg(args, OCISvcCtx*);
|
||||
handle = va_arg(args, OCIStmt*);
|
||||
errorHandle = va_arg(args, OCIError*);
|
||||
iters = va_arg(args, ub4);
|
||||
rowoff = va_arg(args, ub4);
|
||||
|
||||
return Py_BuildValue("lii", handle, iters, rowoff);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_FetchArgs()
|
||||
// Return the arguments to be passed when OCIStmtFetch is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *Callback_FetchArgs(
|
||||
udt_Connection *connection, // connection to use
|
||||
va_list args) // arguments to OCI function
|
||||
{
|
||||
ub4 numRows, rowCount;
|
||||
OCIError *errorHandle;
|
||||
OCIStmt *handle;
|
||||
sword status;
|
||||
|
||||
handle = va_arg(args, OCIStmt*);
|
||||
errorHandle = va_arg(args, OCIError*);
|
||||
numRows = va_arg(args, ub4);
|
||||
|
||||
status = OCIAttrGet(handle, OCI_HTYPE_STMT, &rowCount, 0,
|
||||
OCI_ATTR_ROW_COUNT, connection->environment->errorHandle);
|
||||
if (Environment_CheckForError(connection->environment, status,
|
||||
"Callback_FetchArgs()") < 0)
|
||||
return NULL;
|
||||
|
||||
return Py_BuildValue("lii", handle, numRows, rowCount);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_PrepareArgs()
|
||||
// Return the arguments to be passed when OCIStmtPrepare is called.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *Callback_PrepareArgs(
|
||||
va_list args) // arguments to OCI function
|
||||
{
|
||||
OCIError *errorHandle;
|
||||
ub4 statementLength;
|
||||
OCIStmt *handle;
|
||||
text *statement;
|
||||
|
||||
handle = va_arg(args, OCIStmt*);
|
||||
errorHandle = va_arg(args, OCIError*);
|
||||
statement = va_arg(args, text *);
|
||||
statementLength = va_arg(args, ub4);
|
||||
|
||||
return Py_BuildValue("ls#", handle, statement, statementLength);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_GetArgs()
|
||||
// Return the arguments to be passed to the Python callback method.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *Callback_GetArgs(
|
||||
udt_Connection *connection, // connection to use
|
||||
ub4 functionCode, // function code
|
||||
va_list args) // OCI function arguments
|
||||
{
|
||||
switch (functionCode) {
|
||||
case OCI_FNCODE_BINDBYNAME:
|
||||
return Callback_BindByNameArgs(connection, args);
|
||||
case OCI_FNCODE_DEFINEBYPOS:
|
||||
return Callback_DefineByPosArgs(connection, args);
|
||||
case OCI_FNCODE_STMTEXECUTE:
|
||||
return Callback_ExecuteArgs(args);
|
||||
case OCI_FNCODE_STMTFETCH:
|
||||
return Callback_FetchArgs(connection, args);
|
||||
case OCI_FNCODE_STMTPREPARE:
|
||||
return Callback_PrepareArgs(args);
|
||||
}
|
||||
|
||||
return PyTuple_New(0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_Call()
|
||||
// Actually make the call to the Python function.
|
||||
//-----------------------------------------------------------------------------
|
||||
static sword Callback_Call(
|
||||
PyObject *tuple, // tuple containing connection/callback
|
||||
ub4 functionCode, // function code
|
||||
va_list args) // arguments
|
||||
{
|
||||
PyObject *callback, *callbackArgs, *result;
|
||||
udt_Connection *connection;
|
||||
|
||||
// determine the connection and callback
|
||||
connection = (udt_Connection*) PyTuple_GET_ITEM(tuple, 0);
|
||||
callback = PyTuple_GET_ITEM(tuple, 1);
|
||||
|
||||
// determine the arguments to pass to the function
|
||||
callbackArgs = Callback_GetArgs(connection, functionCode, args);
|
||||
if (!callbackArgs)
|
||||
return OCI_ERROR;
|
||||
|
||||
// actually make the call to the method
|
||||
result = PyEval_CallObject(callback, callbackArgs);
|
||||
Py_DECREF(callbackArgs);
|
||||
if (!result)
|
||||
return OCI_ERROR;
|
||||
|
||||
Py_DECREF(result);
|
||||
return OCI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Callback_Handler()
|
||||
// Callback handler for calling Python code within an OCI callback.
|
||||
//-----------------------------------------------------------------------------
|
||||
static sword Callback_Handler(
|
||||
PyObject *tuple, // tuple containing connection/callback
|
||||
dvoid *handle, // pointer to handle
|
||||
ub4 handleType, // handle type
|
||||
ub4 functionCode, // function code
|
||||
ub1 when, // when being called
|
||||
sword returnCode, // return code
|
||||
ub4 *errorCode, // error code (IN/OUT)
|
||||
va_list args) // arguments
|
||||
{
|
||||
#ifdef WITH_THREAD
|
||||
PyThreadState *threadState;
|
||||
#endif
|
||||
sword result;
|
||||
|
||||
// create new thread state, if necessary
|
||||
#ifdef WITH_THREAD
|
||||
threadState = PyThreadState_Swap(NULL);
|
||||
if (threadState) {
|
||||
PyThreadState_Swap(threadState);
|
||||
threadState = NULL;
|
||||
} else {
|
||||
threadState = PyThreadState_New(g_InterpreterState);
|
||||
if (!threadState) {
|
||||
PyErr_Print();
|
||||
return OCI_ERROR;
|
||||
}
|
||||
PyEval_AcquireThread(threadState);
|
||||
}
|
||||
#endif
|
||||
|
||||
// perform the call
|
||||
result = Callback_Call(tuple, functionCode, args);
|
||||
if (result != OCI_CONTINUE)
|
||||
PyErr_Print();
|
||||
|
||||
// restore thread state, if necessary
|
||||
#ifdef WITH_THREAD
|
||||
if (threadState) {
|
||||
PyThreadState_Clear(threadState);
|
||||
PyEval_ReleaseThread(threadState);
|
||||
PyThreadState_Delete(threadState);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// CursorVar.c
|
||||
// Defines the routines specific to the cursor type.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cursor variable type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
OCIStmt **data;
|
||||
udt_Connection *connection;
|
||||
PyObject *cursors;
|
||||
} udt_CursorVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of cursor variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int CursorVar_Initialize(udt_CursorVar*, udt_Cursor*);
|
||||
static void CursorVar_Finalize(udt_CursorVar*);
|
||||
static int CursorVar_SetValue(udt_CursorVar*, unsigned, PyObject*);
|
||||
static PyObject *CursorVar_GetValue(udt_CursorVar*, unsigned);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_CursorVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.CURSOR", // tp_name
|
||||
sizeof(udt_CursorVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_Cursor = {
|
||||
(InitializeProc) CursorVar_Initialize,
|
||||
(FinalizeProc) CursorVar_Finalize,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) CursorVar_SetValue,
|
||||
(GetValueProc) CursorVar_GetValue,
|
||||
&g_CursorVarType, // Python type
|
||||
SQLT_RSET, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCIStmt*), // element length
|
||||
0, // is variable length
|
||||
0, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CursorVar_Initialize()
|
||||
// Initialize the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int CursorVar_Initialize(
|
||||
udt_CursorVar *var, // variable to initialize
|
||||
udt_Cursor *cursor) // cursor created by
|
||||
{
|
||||
udt_Cursor *tempCursor;
|
||||
ub4 i;
|
||||
|
||||
Py_INCREF(cursor->connection);
|
||||
var->connection = cursor->connection;
|
||||
var->cursors = PyList_New(var->allocatedElements);
|
||||
if (!var->cursors)
|
||||
return -1;
|
||||
for (i = 0; i < var->allocatedElements; i++) {
|
||||
tempCursor = (udt_Cursor*) Connection_NewCursor(var->connection, NULL);
|
||||
if (!tempCursor) {
|
||||
Py_DECREF(var);
|
||||
return -1;
|
||||
}
|
||||
PyList_SET_ITEM(var->cursors, i, (PyObject*) tempCursor);
|
||||
if (Cursor_AllocateHandle(tempCursor) < 0) {
|
||||
Py_DECREF(var);
|
||||
return -1;
|
||||
}
|
||||
var->data[i] = tempCursor->handle;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CursorVar_Finalize()
|
||||
// Prepare for variable destruction.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void CursorVar_Finalize(
|
||||
udt_CursorVar *var) // variable to free
|
||||
{
|
||||
Py_DECREF(var->connection);
|
||||
Py_XDECREF(var->cursors);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CursorVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int CursorVar_SetValue(
|
||||
udt_CursorVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
udt_Cursor *cursor;
|
||||
|
||||
if (!PyObject_IsInstance(value, (PyObject*) &g_CursorType)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting cursor");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py_XDECREF(PyList_GET_ITEM(var->cursors, pos));
|
||||
Py_INCREF(value);
|
||||
PyList_SET_ITEM(var->cursors, pos, value);
|
||||
cursor = (udt_Cursor *) value;
|
||||
#ifdef ORACLE_9I
|
||||
if (!cursor->isOwned) {
|
||||
if (Cursor_FreeHandle(cursor, 1) < 0)
|
||||
return -1;
|
||||
cursor->isOwned = 1;
|
||||
if (Cursor_AllocateHandle(cursor) < 0)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
var->data[pos] = cursor->handle;
|
||||
cursor->statementType = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CursorVar_GetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *CursorVar_GetValue(
|
||||
udt_CursorVar *var, // variable to set value for
|
||||
unsigned pos) // array position to set
|
||||
{
|
||||
PyObject *cursor;
|
||||
|
||||
cursor = PyList_GET_ITEM(var->cursors, pos);
|
||||
((udt_Cursor*) cursor)->statementType = -1;
|
||||
Py_INCREF(cursor);
|
||||
return cursor;
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// DateTimeVar.c
|
||||
// Defines the routines for handling date (time) variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DateTime type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
OCIDate *data;
|
||||
} udt_DateTimeVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of date/time variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int DateTimeVar_SetValue(udt_DateTimeVar*, unsigned, PyObject*);
|
||||
static PyObject *DateTimeVar_GetValue(udt_DateTimeVar*, unsigned);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_DateTimeVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.DATETIME", // tp_name
|
||||
sizeof(udt_DateTimeVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_DateTime = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) DateTimeVar_SetValue,
|
||||
(GetValueProc) DateTimeVar_GetValue,
|
||||
&g_DateTimeVarType, // Python type
|
||||
SQLT_ODT, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCIDate), // element length (default)
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
#ifdef NATIVE_DATETIME
|
||||
static udt_VariableType vt_Date = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) DateTimeVar_SetValue,
|
||||
(GetValueProc) DateTimeVar_GetValue,
|
||||
&g_DateTimeVarType, // Python type
|
||||
SQLT_ODT, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCIDate), // element length (default)
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DateTimeVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int DateTimeVar_SetValue(
|
||||
udt_DateTimeVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
ub1 month, day, hour, minute, second;
|
||||
short year;
|
||||
|
||||
if (PyDateTime_Check(value)) {
|
||||
year = (short) PyDateTime_GET_YEAR(value);
|
||||
month = PyDateTime_GET_MONTH(value);
|
||||
day = PyDateTime_GET_DAY(value);
|
||||
hour = PyDateTime_DATE_GET_HOUR(value);
|
||||
minute = PyDateTime_DATE_GET_MINUTE(value);
|
||||
second = PyDateTime_DATE_GET_SECOND(value);
|
||||
} else if (PyDate_Check(value)) {
|
||||
year = (short) PyDateTime_GET_YEAR(value);
|
||||
month = PyDateTime_GET_MONTH(value);
|
||||
day = PyDateTime_GET_DAY(value);
|
||||
hour = minute = second = 0;
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting date data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// store a copy of the value
|
||||
OCIDateSetDate(&var->data[pos], year, month, day);
|
||||
OCIDateSetTime(&var->data[pos], hour, minute, second);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DateTimeVar_GetAttribute()
|
||||
// Get the attribute from the object and convert it to an integer.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int DateTimeVar_GetAttribute(
|
||||
PyObject *value, // value to get attribute for
|
||||
char *name, // name to acquire
|
||||
unsigned *outputValue) // output value
|
||||
{
|
||||
PyObject *attrValue;
|
||||
|
||||
attrValue = PyObject_GetAttrString(value, name);
|
||||
if (!attrValue)
|
||||
return -1;
|
||||
*outputValue = PyInt_AsLong(attrValue);
|
||||
if (PyErr_Occurred())
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DateTimeVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int DateTimeVar_SetValue(
|
||||
udt_DateTimeVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
unsigned year, month, day, hour, minute, second;
|
||||
udt_ExternalDateTimeVar *dateValue;
|
||||
sword status;
|
||||
uword valid;
|
||||
|
||||
// handle internal cx_Oracle date type
|
||||
if (value->ob_type == &g_ExternalDateTimeVarType) {
|
||||
dateValue = (udt_ExternalDateTimeVar*) value;
|
||||
year = dateValue->year;
|
||||
month = dateValue->month;
|
||||
day = dateValue->day;
|
||||
hour = dateValue->hour;
|
||||
minute = dateValue->minute;
|
||||
second = dateValue->second;
|
||||
|
||||
// handle Python 2.3 datetime type
|
||||
} else if (value->ob_type == g_DateTimeType) {
|
||||
if (DateTimeVar_GetAttribute(value, "year", &year) < 0)
|
||||
return -1;
|
||||
if (DateTimeVar_GetAttribute(value, "month", &month) < 0)
|
||||
return -1;
|
||||
if (DateTimeVar_GetAttribute(value, "day", &day) < 0)
|
||||
return -1;
|
||||
if (DateTimeVar_GetAttribute(value, "hour", &hour) < 0)
|
||||
return -1;
|
||||
if (DateTimeVar_GetAttribute(value, "minute", &minute) < 0)
|
||||
return -1;
|
||||
if (DateTimeVar_GetAttribute(value, "second", &second) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting date data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// store a copy of the value
|
||||
OCIDateSetDate(&var->data[pos], (sb2) year, (ub1) month, (ub1) day);
|
||||
OCIDateSetTime(&var->data[pos], (ub1) hour, (ub1) minute, (ub1) second);
|
||||
status = OCIDateCheck(var->environment->errorHandle, &var->data[pos],
|
||||
&valid);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"DateTimeVar_SetValue()") < 0)
|
||||
return -1;
|
||||
if (valid != 0) {
|
||||
PyErr_Format(g_DataErrorException, "invalid date: %d/%d/%d %d:%d:%d",
|
||||
year, month, day, hour, minute, second);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DateTimeVar_GetValue()
|
||||
// Returns the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *DateTimeVar_GetValue(
|
||||
udt_DateTimeVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
return OracleDateToPythonDate(var->type, &var->data[pos]);
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Environment.c
|
||||
// Environment handling.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// structure for the Python type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
OCIEnv *handle;
|
||||
OCIError *errorHandle;
|
||||
int maxBytesPerCharacter;
|
||||
int fixedWidth;
|
||||
ub4 maxStringBytes;
|
||||
} udt_Environment;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// maximum number of characters applicable to strings
|
||||
//-----------------------------------------------------------------------------
|
||||
#define MAX_STRING_CHARS 4000
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static void Environment_Free(udt_Environment*);
|
||||
static int Environment_CheckForError(udt_Environment*, sword, const char*);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of Python type
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_EnvironmentType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"OracleEnvironment", // tp_name
|
||||
sizeof(udt_Environment), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Environment_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, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
#include "Error.c"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Environment_New()
|
||||
// Create a new environment object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_Environment *Environment_New(
|
||||
int threaded) // use threaded mode?
|
||||
{
|
||||
udt_Environment *environment;
|
||||
sword status;
|
||||
ub4 mode;
|
||||
|
||||
// create a new object for the Oracle environment
|
||||
environment = PyObject_NEW(udt_Environment, &g_EnvironmentType);
|
||||
if (!environment)
|
||||
return NULL;
|
||||
environment->handle = NULL;
|
||||
environment->errorHandle = NULL;
|
||||
environment->maxBytesPerCharacter = 1;
|
||||
environment->fixedWidth = 1;
|
||||
environment->maxStringBytes = MAX_STRING_CHARS;
|
||||
|
||||
// turn threading mode on, if desired
|
||||
mode = OCI_OBJECT;
|
||||
if (threaded)
|
||||
mode |= OCI_THREADED;
|
||||
|
||||
// create the environment handle
|
||||
status = OCIEnvCreate(&environment->handle, mode, NULL, NULL,
|
||||
NULL, NULL, 0, NULL);
|
||||
if (!environment->handle) {
|
||||
Py_DECREF(environment);
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"Unable to acquire Oracle environment handle");
|
||||
return NULL;
|
||||
}
|
||||
if (Environment_CheckForError(environment, status,
|
||||
"Environment_New(): create env handle") < 0) {
|
||||
environment->handle = NULL;
|
||||
Py_DECREF(environment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create the error handle
|
||||
status = OCIHandleAlloc(environment->handle,
|
||||
(dvoid**) &environment->errorHandle, OCI_HTYPE_ERROR, 0, 0);
|
||||
if (Environment_CheckForError(environment, status,
|
||||
"Environment_New(): create error handle") < 0) {
|
||||
Py_DECREF(environment);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// acquire max bytes per character
|
||||
#ifdef OCI_NLS_CHARSET_MAXBYTESZ
|
||||
status = OCINlsNumericInfoGet(environment->handle,
|
||||
environment->errorHandle, &environment->maxBytesPerCharacter,
|
||||
OCI_NLS_CHARSET_MAXBYTESZ);
|
||||
if (Environment_CheckForError(environment, status,
|
||||
"Environment_New(): get max bytes per character") < 0) {
|
||||
Py_DECREF(environment);
|
||||
return NULL;
|
||||
}
|
||||
environment->maxStringBytes =
|
||||
MAX_STRING_CHARS * environment->maxBytesPerCharacter;
|
||||
|
||||
// acquire whether character set is fixed width
|
||||
status = OCINlsNumericInfoGet(environment->handle,
|
||||
environment->errorHandle, &environment->fixedWidth,
|
||||
OCI_NLS_CHARSET_FIXEDWIDTH);
|
||||
if (Environment_CheckForError(environment, status,
|
||||
"Environment_New(): determine if charset is fixed width") < 0) {
|
||||
Py_DECREF(environment);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return environment;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Environment_Free()
|
||||
// Deallocate the environment. Note that destroying the environment handle
|
||||
// will automatically destroy any child handles that were created.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void Environment_Free(
|
||||
udt_Environment *environment) // environment object
|
||||
{
|
||||
if (environment->handle)
|
||||
OCIHandleFree(environment->handle, OCI_HTYPE_ENV);
|
||||
PyObject_DEL(environment);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Environment_RaiseError()
|
||||
// Reads the error that was caused by the last Oracle statement and raise an
|
||||
// exception for Python. At this point it is assumed that the Oracle
|
||||
// environment is fully initialized.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void Environment_RaiseError(
|
||||
udt_Environment *environment, // environment to raise error for
|
||||
const char *context) // context in which error occurred
|
||||
{
|
||||
PyObject *exceptionType;
|
||||
udt_Error *error;
|
||||
|
||||
error = Error_New(environment, context);
|
||||
if (error) {
|
||||
if (error->errorNumber == 1 ||
|
||||
(error->errorNumber >= 2290 && error->errorNumber <= 2292))
|
||||
exceptionType = g_IntegrityErrorException;
|
||||
else exceptionType = g_DatabaseErrorException;
|
||||
PyErr_SetObject(exceptionType, (PyObject*) error);
|
||||
Py_DECREF(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Environment_CheckForError()
|
||||
// Check for an error in the last call and if an error has occurred, raise a
|
||||
// Python exception.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int Environment_CheckForError(
|
||||
udt_Environment *environment, // environment to raise error in
|
||||
sword status, // status of last call
|
||||
const char *context) // context
|
||||
{
|
||||
if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) {
|
||||
if (status == OCI_INVALID_HANDLE)
|
||||
PyErr_SetString(g_DatabaseErrorException, "Invalid handle!");
|
||||
else Environment_RaiseError(environment, context);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Error.c
|
||||
// Error handling.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// structure for the Python type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
sb4 errorNumber;
|
||||
char errorText[1024];
|
||||
const char *context;
|
||||
} udt_Error;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// forward declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static void Error_Free(udt_Error*);
|
||||
static PyObject *Error_Str(udt_Error*);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of members
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMemberDef g_ErrorMembers[] = {
|
||||
{ "code", T_INT, offsetof(udt_Error, errorNumber), READONLY },
|
||||
{ "message", T_STRING_INPLACE, offsetof(udt_Error, errorText), READONLY },
|
||||
{ "context", T_STRING, offsetof(udt_Error, context), READONLY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of Python type
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_ErrorType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle._Error", // tp_name
|
||||
sizeof(udt_Error), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Error_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
|
||||
(reprfunc) Error_Str, // tp_str
|
||||
0, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0, // tp_doc
|
||||
0, // tp_traverse
|
||||
0, // tp_clear
|
||||
0, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
0, // tp_methods
|
||||
g_ErrorMembers, // tp_members
|
||||
0 // tp_getset
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Error_New()
|
||||
// Create a new error object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_Error *Error_New(
|
||||
udt_Environment *environment, // environment object
|
||||
const char *context) // context in which error occurred
|
||||
{
|
||||
udt_Error *error;
|
||||
ub4 handleType;
|
||||
dvoid *handle;
|
||||
sword status;
|
||||
|
||||
error = PyObject_NEW(udt_Error, &g_ErrorType);
|
||||
if (!error)
|
||||
return NULL;
|
||||
error->context = context;
|
||||
if (environment->errorHandle) {
|
||||
handle = environment->errorHandle;
|
||||
handleType = OCI_HTYPE_ERROR;
|
||||
} else {
|
||||
handle = environment->handle;
|
||||
handleType = OCI_HTYPE_ENV;
|
||||
}
|
||||
status = OCIErrorGet(handle, 1, 0, &error->errorNumber,
|
||||
(unsigned char*) error->errorText, sizeof(error->errorText),
|
||||
handleType);
|
||||
if (status != OCI_SUCCESS) {
|
||||
Py_DECREF(error);
|
||||
PyErr_SetString(g_InternalErrorException, "No Oracle error?");
|
||||
return NULL;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Error_Free()
|
||||
// Deallocate the environment, disconnecting from the database if necessary.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void Error_Free(
|
||||
udt_Error *self) // error object
|
||||
{
|
||||
self->ob_type->tp_free((PyObject*) self);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Error_Str()
|
||||
// Return a string representation of the error variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *Error_Str(
|
||||
udt_Error *self) // variable to return the string for
|
||||
{
|
||||
return PyString_FromString(self->errorText);
|
||||
}
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// ExternalDateTimeVar.c
|
||||
// Defines the routines for handling date variables external to this module.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// external date/time type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
unsigned year;
|
||||
unsigned month;
|
||||
unsigned day;
|
||||
unsigned hour;
|
||||
unsigned minute;
|
||||
unsigned second;
|
||||
unsigned fsecond;
|
||||
} udt_ExternalDateTimeVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of external date variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ExternalDateTimeVar_Free(udt_ExternalDateTimeVar*);
|
||||
static PyObject *ExternalDateTimeVar_Str(udt_ExternalDateTimeVar*);
|
||||
static int ExternalDateTimeVar_Cmp(udt_ExternalDateTimeVar*,
|
||||
udt_ExternalDateTimeVar*);
|
||||
static PyObject *ExternalDateTimeVar_New(PyTypeObject*, PyObject*, PyObject*);
|
||||
static PyObject *ExternalDateTimeVar_Reduce(udt_ExternalDateTimeVar*);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of members for Python type
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMemberDef g_ExternalDateTimeVarMembers[] = {
|
||||
{ "year", T_INT, offsetof(udt_ExternalDateTimeVar, year), READONLY },
|
||||
{ "month", T_INT, offsetof(udt_ExternalDateTimeVar, month), READONLY },
|
||||
{ "day", T_INT, offsetof(udt_ExternalDateTimeVar, day), READONLY },
|
||||
{ "hour", T_INT, offsetof(udt_ExternalDateTimeVar, hour), READONLY },
|
||||
{ "minute", T_INT, offsetof(udt_ExternalDateTimeVar, minute), READONLY },
|
||||
{ "second", T_INT, offsetof(udt_ExternalDateTimeVar, second), READONLY },
|
||||
{ "fsecond", T_INT, offsetof(udt_ExternalDateTimeVar, fsecond), READONLY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of methods for Python type
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMethodDef g_ExternalDateTimeVarMethods[] = {
|
||||
{"__reduce__", (PyCFunction) ExternalDateTimeVar_Reduce, METH_NOARGS },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_ExternalDateTimeVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.Timestamp", // tp_name
|
||||
sizeof(udt_ExternalDateTimeVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) ExternalDateTimeVar_Free,
|
||||
// tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
(cmpfunc) ExternalDateTimeVar_Cmp, // tp_compare
|
||||
(reprfunc) ExternalDateTimeVar_Str, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
(reprfunc) ExternalDateTimeVar_Str, // tp_str
|
||||
// tp_getattro
|
||||
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
|
||||
g_ExternalDateTimeVarMethods, // tp_methods
|
||||
g_ExternalDateTimeVarMembers, // tp_members
|
||||
0, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
0, // tp_descr_get
|
||||
0, // tp_descr_set
|
||||
0, // tp_dictoffset
|
||||
0, // tp_init
|
||||
0, // tp_alloc
|
||||
ExternalDateTimeVar_New, // tp_new
|
||||
0, // tp_free
|
||||
0, // tp_is_gc
|
||||
0 // tp_bases
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalDateTimeVar_NewFromC()
|
||||
// Create a new external date variable from C code.
|
||||
//-----------------------------------------------------------------------------
|
||||
PyObject *ExternalDateTimeVar_NewFromC(
|
||||
PyTypeObject *type, // type of object
|
||||
unsigned year, // year
|
||||
unsigned month, // month
|
||||
unsigned day, // day
|
||||
unsigned hour, // hour
|
||||
unsigned minute, // minute
|
||||
unsigned second, // second
|
||||
unsigned fsecond) // fractional seconds
|
||||
{
|
||||
udt_ExternalDateTimeVar *var;
|
||||
|
||||
var = (udt_ExternalDateTimeVar*) type->tp_alloc(type, 0);
|
||||
if (var) {
|
||||
var->year = year;
|
||||
var->month = month;
|
||||
var->day = day;
|
||||
var->hour = hour;
|
||||
var->minute = minute;
|
||||
var->second = second;
|
||||
var->fsecond = fsecond;
|
||||
}
|
||||
|
||||
return (PyObject*) var;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalDateTimeVar_New()
|
||||
// Create a new cursor object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalDateTimeVar_New(
|
||||
PyTypeObject *type, // type object
|
||||
PyObject *args, // arguments
|
||||
PyObject *keywordArgs) // keyword arguments
|
||||
{
|
||||
unsigned year, month, day, hour, minute, second, fsecond;
|
||||
|
||||
hour = minute = second = fsecond = 0;
|
||||
if (!PyArg_ParseTuple(args, "iii|iiii", &year, &month, &day, &hour,
|
||||
&minute, &second, &fsecond))
|
||||
return NULL;
|
||||
return ExternalDateTimeVar_NewFromC(type, year, month, day, hour, minute,
|
||||
second, fsecond);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalDateTimeVar_Reduce()
|
||||
// Provide information for pickling and unpickling.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject* ExternalDateTimeVar_Reduce(
|
||||
udt_ExternalDateTimeVar* self) // object to pickle
|
||||
{
|
||||
return Py_BuildValue("(O, (iiiiiii))", &g_ExternalDateTimeVarType,
|
||||
self->year, self->month, self->day, self->hour, self->minute,
|
||||
self->second, self->fsecond);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalDateTimeVar_Free()
|
||||
// Free an external date variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ExternalDateTimeVar_Free(
|
||||
udt_ExternalDateTimeVar *var) // variable to free
|
||||
{
|
||||
PyObject_DEL(var);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalDateTimeVar_Str()
|
||||
// Return the string representation of the external date variable object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalDateTimeVar_Str(
|
||||
udt_ExternalDateTimeVar *var) // external date variable object
|
||||
{
|
||||
char value[100];
|
||||
|
||||
sprintf(value, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", var->year,
|
||||
var->month, var->day, var->hour, var->minute, var->second);
|
||||
if (var->fsecond > 0)
|
||||
sprintf(value + strlen(value), ".%.6d", var->fsecond);
|
||||
return PyString_FromString(value);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalDateTimeVar_Cmp()
|
||||
// Return -1 if the second date is less than the first; 0 if the dates are
|
||||
// the same and +1 if the second date is greater than the first.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ExternalDateTimeVar_Cmp(
|
||||
udt_ExternalDateTimeVar *var1, // first date
|
||||
udt_ExternalDateTimeVar *var2) // second date
|
||||
{
|
||||
if (var1->year < var2->year)
|
||||
return -1;
|
||||
if (var1->year > var2->year)
|
||||
return 1;
|
||||
if (var1->month < var2->month)
|
||||
return -1;
|
||||
if (var1->month > var2->month)
|
||||
return 1;
|
||||
if (var1->day < var2->day)
|
||||
return -1;
|
||||
if (var1->day > var2->day)
|
||||
return 1;
|
||||
if (var1->hour < var2->hour)
|
||||
return -1;
|
||||
if (var1->hour > var2->hour)
|
||||
return 1;
|
||||
if (var1->minute < var2->minute)
|
||||
return -1;
|
||||
if (var1->minute > var2->minute)
|
||||
return 1;
|
||||
if (var1->second < var2->second)
|
||||
return -1;
|
||||
if (var1->second > var2->second)
|
||||
return 1;
|
||||
if (var1->fsecond < var2->fsecond)
|
||||
return -1;
|
||||
if (var1->fsecond > var2->fsecond)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,518 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar.c
|
||||
// Defines the routines for handling LOB variables external to this module.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// external LOB type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
udt_LobVar *lobVar;
|
||||
unsigned pos;
|
||||
unsigned internalFetchNum;
|
||||
} udt_ExternalLobVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of external LOB variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ExternalLobVar_Free(udt_ExternalLobVar*);
|
||||
static PyObject *ExternalLobVar_Str(udt_ExternalLobVar*);
|
||||
static PyObject *ExternalLobVar_GetAttr(udt_ExternalLobVar*, PyObject*);
|
||||
static PyObject *ExternalLobVar_Size(udt_ExternalLobVar*, PyObject*);
|
||||
static PyObject *ExternalLobVar_Read(udt_ExternalLobVar*, PyObject*,
|
||||
PyObject*);
|
||||
static PyObject *ExternalLobVar_Write(udt_ExternalLobVar*, PyObject*,
|
||||
PyObject*);
|
||||
static PyObject *ExternalLobVar_Trim(udt_ExternalLobVar*, PyObject*,
|
||||
PyObject*);
|
||||
static PyObject *ExternalLobVar_GetFileName(udt_ExternalLobVar*, PyObject*);
|
||||
static PyObject *ExternalLobVar_SetFileName(udt_ExternalLobVar*, PyObject*);
|
||||
static PyObject *ExternalLobVar_FileExists(udt_ExternalLobVar*, PyObject*);
|
||||
static PyObject *ExternalLobVar_Reduce(udt_ExternalLobVar*);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_ExternalLobVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.LOB", // tp_name
|
||||
sizeof(udt_ExternalLobVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) ExternalLobVar_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
|
||||
(reprfunc) ExternalLobVar_Str, // tp_str
|
||||
(getattrofunc) ExternalLobVar_GetAttr,
|
||||
// tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of methods for Python type "ExternalLOBVar"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMethodDef g_ExternalLobVarMethods[] = {
|
||||
{ "size", (PyCFunction) ExternalLobVar_Size, METH_NOARGS },
|
||||
{ "read", (PyCFunction) ExternalLobVar_Read,
|
||||
METH_VARARGS | METH_KEYWORDS },
|
||||
{ "write", (PyCFunction) ExternalLobVar_Write,
|
||||
METH_VARARGS | METH_KEYWORDS },
|
||||
{ "trim", (PyCFunction) ExternalLobVar_Trim,
|
||||
METH_VARARGS | METH_KEYWORDS },
|
||||
{ "getfilename", (PyCFunction) ExternalLobVar_GetFileName, METH_NOARGS },
|
||||
{ "setfilename", (PyCFunction) ExternalLobVar_SetFileName, METH_VARARGS },
|
||||
{ "fileexists", (PyCFunction) ExternalLobVar_FileExists, METH_NOARGS },
|
||||
{ "__reduce__", (PyCFunction) ExternalLobVar_Reduce, METH_NOARGS },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_New()
|
||||
// Create a new external LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
PyObject *ExternalLobVar_New(
|
||||
udt_LobVar *var, // variable to encapsulate
|
||||
unsigned pos) // position in array to encapsulate
|
||||
{
|
||||
udt_ExternalLobVar *newVar;
|
||||
|
||||
newVar = PyObject_NEW(udt_ExternalLobVar, &g_ExternalLobVarType);
|
||||
if (!newVar)
|
||||
return NULL;
|
||||
newVar->pos = pos;
|
||||
newVar->internalFetchNum = var->internalFetchNum;
|
||||
Py_INCREF(var);
|
||||
newVar->lobVar = var;
|
||||
|
||||
return (PyObject*) newVar;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Free()
|
||||
// Free an external LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ExternalLobVar_Free(
|
||||
udt_ExternalLobVar *var) // variable to free
|
||||
{
|
||||
Py_DECREF(var->lobVar);
|
||||
PyObject_DEL(var);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Verify()
|
||||
// Verify that the external LOB var is still valid.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ExternalLobVar_Verify(
|
||||
udt_ExternalLobVar *var) // variable to verify
|
||||
{
|
||||
if (var->internalFetchNum != var->lobVar->internalFetchNum) {
|
||||
PyErr_SetString(g_ProgrammingErrorException,
|
||||
"LOB variable no longer valid after subsequent fetch");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_GetAttr()
|
||||
// Retrieve an attribute on the external LOB variable object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_GetAttr(
|
||||
udt_ExternalLobVar *var, // cursor object
|
||||
PyObject *name) // name of attribute
|
||||
{
|
||||
return Py_FindMethod(g_ExternalLobVarMethods, (PyObject*) var,
|
||||
PyString_AS_STRING(name));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_InternalRead()
|
||||
// Return the size of the LOB variable for internal comsumption.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ExternalLobVar_InternalRead(
|
||||
udt_ExternalLobVar *var, // variable to return the size of
|
||||
char *buffer, // buffer in which to put data
|
||||
ub4 bufferSize, // size of buffer
|
||||
ub4 *length, // length of data (IN/OUT)
|
||||
int offset) // offset
|
||||
{
|
||||
sword status;
|
||||
|
||||
if (var->lobVar->isFile) {
|
||||
status = OCILobFileOpen(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle,
|
||||
var->lobVar->data[var->pos], OCI_FILE_READONLY);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_FileOpen()") < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = OCILobRead(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle,
|
||||
var->lobVar->data[var->pos], length, offset, buffer,
|
||||
bufferSize, NULL, NULL, 0, var->lobVar->type->charsetForm);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_LobRead()") < 0) {
|
||||
OCILobFileClose(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle,
|
||||
var->lobVar->data[var->pos]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (var->lobVar->isFile) {
|
||||
status = OCILobFileClose(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle,
|
||||
var->lobVar->data[var->pos]);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_FileClose()") < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_InternalSize()
|
||||
// Return the size of the LOB variable for internal comsumption.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ExternalLobVar_InternalSize(
|
||||
udt_ExternalLobVar *var) // variable to return the size of
|
||||
{
|
||||
sword status;
|
||||
ub4 length;
|
||||
|
||||
status = OCILobGetLength(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle,
|
||||
var->lobVar->data[var->pos], &length);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_InternalSize()") < 0)
|
||||
return -1;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Value()
|
||||
// Return a portion (or all) of the data in the external LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_Value(
|
||||
udt_ExternalLobVar *var, // variable to return the size of
|
||||
int offset, // offset into LOB
|
||||
int amount) // amount to read from LOB
|
||||
{
|
||||
ub4 length, bufferSize;
|
||||
PyObject *result;
|
||||
char *buffer;
|
||||
|
||||
// modify the arguments
|
||||
if (offset < 0)
|
||||
offset = 1;
|
||||
if (amount < 0) {
|
||||
amount = ExternalLobVar_InternalSize(var);
|
||||
if (amount < 0)
|
||||
return NULL;
|
||||
amount = amount - offset + 1;
|
||||
if (amount <= 0)
|
||||
amount = 1;
|
||||
}
|
||||
length = amount;
|
||||
bufferSize = amount * var->lobVar->environment->maxBytesPerCharacter;
|
||||
|
||||
// create a string for retrieving the value
|
||||
buffer = (char*) PyMem_Malloc(bufferSize);
|
||||
if (!buffer)
|
||||
return PyErr_NoMemory();
|
||||
if (ExternalLobVar_InternalRead(var, buffer, bufferSize, &length,
|
||||
offset) < 0) {
|
||||
PyMem_Free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// return the result
|
||||
if (var->lobVar->environment->fixedWidth)
|
||||
length = length * var->lobVar->environment->maxBytesPerCharacter;
|
||||
result = PyString_FromStringAndSize(buffer, length);
|
||||
PyMem_Free(buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Size()
|
||||
// Return the size of the data in the LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_Size(
|
||||
udt_ExternalLobVar *var, // variable to return the size of
|
||||
PyObject *args) // arguments
|
||||
{
|
||||
int length;
|
||||
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
length = ExternalLobVar_InternalSize(var);
|
||||
if (length < 0)
|
||||
return NULL;
|
||||
return PyInt_FromLong(length);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Read()
|
||||
// Return a portion (or all) of the data in the external LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_Read(
|
||||
udt_ExternalLobVar *var, // variable to return the size of
|
||||
PyObject *args, // arguments
|
||||
PyObject *keywordArgs) // keyword arguments
|
||||
{
|
||||
static char *keywordList[] = { "offset", "amount", NULL };
|
||||
int offset, amount;
|
||||
|
||||
// offset and amount are expected, both optional
|
||||
offset = amount = -1;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|ii", keywordList,
|
||||
&offset, &amount))
|
||||
return NULL;
|
||||
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
return ExternalLobVar_Value(var, offset, amount);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Str()
|
||||
// Return all of the data in the external LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_Str(
|
||||
udt_ExternalLobVar *var) // variable to return the string for
|
||||
{
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
return ExternalLobVar_Value(var, 1, -1);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Write()
|
||||
// Write a value to the LOB variable; return the number of bytes written.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_Write(
|
||||
udt_ExternalLobVar *var, // variable to perform write against
|
||||
PyObject *args, // arguments
|
||||
PyObject *keywordArgs) // keyword arguments
|
||||
{
|
||||
static char *keywordList[] = { "data", "offset", NULL };
|
||||
int offset, bufferLength, length;
|
||||
char *buffer;
|
||||
sword status;
|
||||
|
||||
// buffer and offset are expected, offset is optional
|
||||
offset = -1;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "s#|i", keywordList,
|
||||
&buffer, &bufferLength, &offset))
|
||||
return NULL;
|
||||
if (offset < 0)
|
||||
offset = 1;
|
||||
|
||||
// create a string for retrieving the value
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
length = bufferLength;
|
||||
status = OCILobWrite(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
|
||||
(unsigned int*) &length, offset, buffer, bufferLength,
|
||||
OCI_ONE_PIECE, NULL, NULL, 0, var->lobVar->type->charsetForm);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_Write()") < 0)
|
||||
return NULL;
|
||||
|
||||
// return the result
|
||||
return PyInt_FromLong(length);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Trim()
|
||||
// Trim the LOB variable to the specified length.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_Trim(
|
||||
udt_ExternalLobVar *var, // variable to perform write against
|
||||
PyObject *args, // arguments
|
||||
PyObject *keywordArgs) // keyword arguments
|
||||
{
|
||||
static char *keywordList[] = { "newSize", NULL };
|
||||
sword status;
|
||||
ub4 newSize;
|
||||
|
||||
// buffer and offset are expected, offset is optional
|
||||
newSize = 0;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "|i", keywordList,
|
||||
&newSize))
|
||||
return NULL;
|
||||
|
||||
// create a string for retrieving the value
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
status = OCILobTrim(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
|
||||
newSize);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_Trim()") < 0)
|
||||
return NULL;
|
||||
|
||||
// return the result
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_Reduce()
|
||||
// Method provided for pickling/unpickling of LOB variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_Reduce(
|
||||
udt_ExternalLobVar *self) // variable to dump
|
||||
{
|
||||
PyObject *result, *value;
|
||||
|
||||
value = ExternalLobVar_Str(self);
|
||||
if (!value)
|
||||
return NULL;
|
||||
result = Py_BuildValue("(O(O))", &PyString_Type, value);
|
||||
Py_DECREF(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_GetFileName()
|
||||
// Return the directory alias and file name for the BFILE lob.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_GetFileName(
|
||||
udt_ExternalLobVar *var, // variable to perform write against
|
||||
PyObject *args) // arguments
|
||||
{
|
||||
char dirAlias[30], name[255];
|
||||
ub2 dirAliasLength, nameLength;
|
||||
PyObject *result, *temp;
|
||||
sword status;
|
||||
|
||||
// determine the directory alias and name
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
dirAliasLength = sizeof(dirAlias);
|
||||
nameLength = sizeof(name);
|
||||
status = OCILobFileGetName(var->lobVar->environment->handle,
|
||||
var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
|
||||
(text*) dirAlias, &dirAliasLength, (text*) name, &nameLength);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_GetFileName()") < 0)
|
||||
return NULL;
|
||||
|
||||
// create the two-tuple for returning
|
||||
result = PyTuple_New(2);
|
||||
if (!result)
|
||||
return NULL;
|
||||
temp = PyString_FromStringAndSize(dirAlias, dirAliasLength);
|
||||
if (!temp) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
PyTuple_SET_ITEM(result, 0, temp);
|
||||
temp = PyString_FromStringAndSize(name, nameLength);
|
||||
if (!temp) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
PyTuple_SET_ITEM(result, 1, temp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_SetFileName()
|
||||
// Set the directory alias and file name for the BFILE lob.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_SetFileName(
|
||||
udt_ExternalLobVar *var, // variable to perform write against
|
||||
PyObject *args) // arguments
|
||||
{
|
||||
int dirAliasLength, nameLength;
|
||||
char *dirAlias, *name;
|
||||
sword status;
|
||||
|
||||
// get the directory alias and name as strings
|
||||
if (!PyArg_ParseTuple(args, "s#s#", &dirAlias, &dirAliasLength, &name,
|
||||
&nameLength))
|
||||
return NULL;
|
||||
|
||||
// create a string for retrieving the value
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
status = OCILobFileSetName(var->lobVar->environment->handle,
|
||||
var->lobVar->environment->errorHandle,
|
||||
&var->lobVar->data[var->pos], (text*) dirAlias,
|
||||
(ub2) dirAliasLength, (text*) name, (ub2) nameLength);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_SetFileName()") < 0)
|
||||
return NULL;
|
||||
|
||||
// return the result
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalLobVar_FileExists()
|
||||
// Return a boolean indicating if the BFIILE lob exists.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalLobVar_FileExists(
|
||||
udt_ExternalLobVar *var, // variable to perform write against
|
||||
PyObject *args) // arguments
|
||||
{
|
||||
PyObject *result;
|
||||
sword status;
|
||||
boolean flag;
|
||||
|
||||
if (ExternalLobVar_Verify(var) < 0)
|
||||
return NULL;
|
||||
status = OCILobFileExists(var->lobVar->connection->handle,
|
||||
var->lobVar->environment->errorHandle, var->lobVar->data[var->pos],
|
||||
&flag);
|
||||
if (Environment_CheckForError(var->lobVar->environment, status,
|
||||
"ExternalLobVar_FileExists()") < 0)
|
||||
return NULL;
|
||||
|
||||
// return the result
|
||||
if (flag)
|
||||
result = Py_True;
|
||||
else result = Py_False;
|
||||
Py_INCREF(result);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar.c
|
||||
// Defines the routines for handling object variables external to this
|
||||
// module.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// external Object type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *referencedObject;
|
||||
udt_ObjectType *objectType;
|
||||
dvoid *instance;
|
||||
dvoid *indicator;
|
||||
int isIndependent;
|
||||
} udt_ExternalObjectVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of external object variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ExternalObjectVar_Free(udt_ExternalObjectVar*);
|
||||
static PyObject *ExternalObjectVar_GetAttr(udt_ExternalObjectVar*, PyObject*);
|
||||
static PyObject *ExternalObjectVar_ConvertToPython(udt_Environment*,
|
||||
OCITypeCode, dvoid*, dvoid*, PyObject*, udt_ObjectType*);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_ExternalObjectVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.OBJECT", // tp_name
|
||||
sizeof(udt_ExternalObjectVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) ExternalObjectVar_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
|
||||
(getattrofunc) ExternalObjectVar_GetAttr,
|
||||
// tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar_New()
|
||||
// Create a new external LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
PyObject *ExternalObjectVar_New(
|
||||
PyObject *referencedObject, // referenced object
|
||||
udt_ObjectType *objectType, // type of object
|
||||
dvoid *instance, // object instance data
|
||||
dvoid *indicator, // indicator structure
|
||||
int isIndependent) // is object independent?
|
||||
{
|
||||
udt_ExternalObjectVar *newVar;
|
||||
|
||||
newVar = PyObject_NEW(udt_ExternalObjectVar, &g_ExternalObjectVarType);
|
||||
if (!newVar)
|
||||
return NULL;
|
||||
Py_INCREF(referencedObject);
|
||||
newVar->referencedObject = referencedObject;
|
||||
Py_INCREF(objectType);
|
||||
newVar->objectType = objectType;
|
||||
newVar->instance = instance;
|
||||
newVar->indicator = indicator;
|
||||
newVar->isIndependent = isIndependent;
|
||||
return (PyObject*) newVar;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar_Free()
|
||||
// Free an external LOB variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ExternalObjectVar_Free(
|
||||
udt_ExternalObjectVar *self) // variable to free
|
||||
{
|
||||
if (self->isIndependent)
|
||||
OCIObjectFree(self->objectType->environment->handle,
|
||||
self->objectType->environment->errorHandle,
|
||||
self->instance, OCI_OBJECTFREE_FORCE);
|
||||
Py_DECREF(self->objectType);
|
||||
Py_DECREF(self->referencedObject);
|
||||
PyObject_DEL(self);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar_ConvertCollectionElements()
|
||||
// Convert the collection elements to Python values.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ExternalObjectVar_ConvertCollectionElements(
|
||||
udt_Environment *environment, // environment to use
|
||||
OCIIter *iter, // iterator
|
||||
PyObject *list, // list result
|
||||
PyObject *referencedObject, // referenced object
|
||||
udt_ObjectType *objectType) // collection type information
|
||||
{
|
||||
dvoid *elementValue, *elementIndicator;
|
||||
PyObject *elementObject;
|
||||
boolean endOfCollection;
|
||||
sword status;
|
||||
|
||||
while (list) {
|
||||
status = OCIIterNext(environment->handle, environment->errorHandle,
|
||||
iter, &elementValue, &elementIndicator, &endOfCollection);
|
||||
if (Environment_CheckForError(environment, status,
|
||||
"ExternalObjectVar_ConvertCollection(): get next") < 0)
|
||||
return -1;
|
||||
if (endOfCollection)
|
||||
break;
|
||||
elementObject = ExternalObjectVar_ConvertToPython(environment,
|
||||
objectType->elementTypeCode, elementValue, elementIndicator,
|
||||
referencedObject, (udt_ObjectType*) objectType->elementType);
|
||||
if (!elementObject)
|
||||
return -1;
|
||||
if (PyList_Append(list, elementObject) < 0) {
|
||||
Py_DECREF(elementObject);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(elementObject);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar_ConvertCollection()
|
||||
// Convert a collection to a Python list.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalObjectVar_ConvertCollection(
|
||||
udt_Environment *environment, // environment to use
|
||||
OCIColl *collectionValue, // collection value
|
||||
PyObject *referencedObject, // referenced object
|
||||
udt_ObjectType *objectType) // collection type information
|
||||
{
|
||||
PyObject *list;
|
||||
OCIIter *iter;
|
||||
sword status;
|
||||
int result;
|
||||
|
||||
// create the iterator
|
||||
status = OCIIterCreate(environment->handle, environment->errorHandle,
|
||||
collectionValue, &iter);
|
||||
if (Environment_CheckForError(environment, status,
|
||||
"ExternalObjectVar_ConvertCollection(): creating iterator") < 0)
|
||||
return NULL;
|
||||
|
||||
// create the result list
|
||||
list = PyList_New(0);
|
||||
if (list) {
|
||||
result = ExternalObjectVar_ConvertCollectionElements(environment, iter,
|
||||
list, referencedObject, objectType);
|
||||
if (result < 0) {
|
||||
Py_DECREF(list);
|
||||
list = NULL;
|
||||
}
|
||||
}
|
||||
OCIIterDelete(environment->handle, environment->errorHandle, &iter);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar_ConvertToPython()
|
||||
// Convert an Oracle value to a Python value.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalObjectVar_ConvertToPython(
|
||||
udt_Environment *environment, // environment to use
|
||||
OCITypeCode typeCode, // type of Oracle data
|
||||
dvoid *value, // Oracle value
|
||||
dvoid *indicator, // null indicator
|
||||
PyObject *referencedObject, // referenced object (for sub objects)
|
||||
udt_ObjectType *subType) // sub type (for sub objects)
|
||||
{
|
||||
OraText *stringValue;
|
||||
|
||||
// null values returned as None
|
||||
if (* (OCIInd*) indicator == OCI_IND_NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
switch (typeCode) {
|
||||
case OCI_TYPECODE_VARCHAR2:
|
||||
stringValue = OCIStringPtr(environment->handle,
|
||||
* (OCIString**) value);
|
||||
return PyString_FromString((char*) stringValue);
|
||||
case OCI_TYPECODE_NUMBER:
|
||||
return OracleNumberToPythonFloat(environment, (OCINumber*) value);
|
||||
case OCI_TYPECODE_DATE:
|
||||
return OracleDateToPythonDate(&vt_DateTime, (OCIDate*) value);
|
||||
case OCI_TYPECODE_OBJECT:
|
||||
return ExternalObjectVar_New(referencedObject, subType, value,
|
||||
indicator, 0);
|
||||
case OCI_TYPECODE_NAMEDCOLLECTION:
|
||||
return ExternalObjectVar_ConvertCollection(environment,
|
||||
* (OCIColl**) value, referencedObject, subType);
|
||||
};
|
||||
|
||||
return PyErr_Format(g_NotSupportedErrorException,
|
||||
"ExternalObjectVar_GetAttributeValue(): unhandled data type %d",
|
||||
typeCode);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar_GetAttributeValue()
|
||||
// Retrieve an attribute on the external LOB variable object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalObjectVar_GetAttributeValue(
|
||||
udt_ExternalObjectVar *self, // object
|
||||
udt_ObjectAttribute *attribute) // attribute to get
|
||||
{
|
||||
dvoid *valueIndicator, *value;
|
||||
OCIInd scalarValueIndicator;
|
||||
ub4 nameLength;
|
||||
sword status;
|
||||
OCIType *tdo;
|
||||
char *name;
|
||||
|
||||
// get the value for the attribute
|
||||
name = PyString_AS_STRING(attribute->name);
|
||||
nameLength = PyString_GET_SIZE(attribute->name);
|
||||
status = OCIObjectGetAttr(self->objectType->environment->handle,
|
||||
self->objectType->environment->errorHandle, self->instance,
|
||||
self->indicator, self->objectType->tdo, (const OraText**) &name,
|
||||
&nameLength, 1, 0, 0, &scalarValueIndicator, &valueIndicator,
|
||||
&value, &tdo);
|
||||
if (Environment_CheckForError(self->objectType->environment, status,
|
||||
"ExternalObjectVar_GetAttributeValue(): getting value") < 0)
|
||||
return NULL;
|
||||
|
||||
// determine the proper null indicator
|
||||
if (!valueIndicator)
|
||||
valueIndicator = &scalarValueIndicator;
|
||||
|
||||
return ExternalObjectVar_ConvertToPython(self->objectType->environment,
|
||||
attribute->typeCode, value, valueIndicator, (PyObject*) self,
|
||||
attribute->subType);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ExternalObjectVar_GetAttr()
|
||||
// Retrieve an attribute on the external LOB variable object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ExternalObjectVar_GetAttr(
|
||||
udt_ExternalObjectVar *self, // object
|
||||
PyObject *nameObject) // name of attribute
|
||||
{
|
||||
udt_ObjectAttribute *attribute;
|
||||
char *name;
|
||||
|
||||
attribute = (udt_ObjectAttribute*)
|
||||
PyDict_GetItem(self->objectType->attributesByName, nameObject);
|
||||
if (attribute)
|
||||
return ExternalObjectVar_GetAttributeValue(self, attribute);
|
||||
name = PyString_AS_STRING(nameObject);
|
||||
if (name[0] == 't' && strcmp(name, "type") == 0) {
|
||||
Py_INCREF(self->objectType);
|
||||
return (PyObject*) self->objectType;
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_AttributeError, name);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
Changes from 4.3 to 4.3.1
|
||||
1) Ensure that if the client buffer size exceeds 4000 bytes that the server
|
||||
buffer size does not as strings may only contain 4000 bytes; this allows
|
||||
handling of multibyte character sets on the server as well as the client.
|
||||
2) Added support for using buffer objects to populate binary data and made the
|
||||
Binary() constructor the buffer type as requested by Ken Mason.
|
||||
3) Fix potential crash when using full optimization with some compilers.
|
||||
Thanks to Aris Motas for noticing this and providing the initial patch and
|
||||
to Amaury Forgeot d'Arc for providing an even simpler solution.
|
||||
4) Pass the correct charset form in to the write call in order to support
|
||||
writing to national character set LOB values properly. Thanks to Ian Kelly
|
||||
for noticing this discrepancy.
|
||||
|
||||
Changes from 4.2.1 to 4.3
|
||||
1) Added preliminary support for fetching Oracle objects (SQL types) as
|
||||
requested by Kristof Beyls (who kindly provided an initial patch).
|
||||
Additional work needs to be done to support binding and updating objects
|
||||
but the basic structure is now in place.
|
||||
2) Added connection.maxBytesPerCharacter which indicates the maximum number of
|
||||
bytes each character can use; use this value to also determine the size of
|
||||
local buffers in order to handle discrepancies between the client character
|
||||
set and the server character set. Thanks to Andreas Mock for providing the
|
||||
initial patch and working with me to resolve this issue.
|
||||
3) Added support for querying native floats in Oracle 10g as requested by
|
||||
Danny Boxhoorn.
|
||||
4) Add support for temporary LOB variables created via PL/SQL instead of only
|
||||
directly by cx_Oracle; thanks to Henning von Bargen for discovering this
|
||||
problem.
|
||||
5) Added support for specifying variable types using the builtin types int,
|
||||
float, str and datetime.date which allows for finer control of what type of
|
||||
Python object is returned from cursor.callfunc() for example.
|
||||
6) Added support for passing booleans to callproc() and callfunc() as
|
||||
requested by Anana Aiyer.
|
||||
7) Fixed support for 64-bit environments in Python 2.5.
|
||||
8) Thanks to Filip Ballegeer and a number of his co-workers, an intermittent
|
||||
crash was tracked down; specifically, if a connection is closed, then the
|
||||
call to OCIStmtRelease() will free memory twice. Preventing the call when
|
||||
the connection is closed solves the problem.
|
||||
|
||||
Changes from 4.2 to 4.2.1
|
||||
1) Added additional type (NCLOB) to handle CLOBs that use the national
|
||||
character set as requested by Chris Dunscombe.
|
||||
2) Added support for returning cursors from functions as requested by Daniel
|
||||
Steinmann.
|
||||
3) Added support for getting/setting the "get" mode on session pools as
|
||||
requested by Anand Aiyer.
|
||||
4) Added support for binding subclassed cursors.
|
||||
5) Fixed binding of decimal objects with absolute values less than 0.1.
|
||||
|
||||
Changes from 4.1.2 to 4.2
|
||||
1) Added support for parsing an Oracle statement as requested by Patrick
|
||||
Blackwill.
|
||||
2) Added support for BFILEs at the request of Matthew Cahn.
|
||||
3) Added support for binding decimal.Decimal objects to cursors.
|
||||
4) Added support for reading from NCLOBs as requested by Chris Dunscombe.
|
||||
5) Added connection attributes encoding and nencoding which return the IANA
|
||||
character set name for the character set and national character set in use
|
||||
by the client.
|
||||
6) Rework module initialization to use the techniques recommended by the
|
||||
Python documentation as one user was experiencing random segfaults due
|
||||
to the use of the module dictionary after the initialization was complete.
|
||||
7) Removed support for the OPT_Threading attribute. Use the threaded keyword
|
||||
when creating connections and session pools instead.
|
||||
8) Removed support for the OPT_NumbersAsStrings attribute. Use the
|
||||
numbersAsStrings attribute on cursors instead.
|
||||
9) Use type long rather than type int in order to support long integers on
|
||||
64-bit machines as reported by Uwe Hoffmann.
|
||||
10) Add cursor attribute "bindarraysize" which is defaulted to 1 and is used
|
||||
to determine the size of the arrays created for bind variables.
|
||||
11) Added repr() methods to provide something a little more useful than the
|
||||
standard type name and memory address.
|
||||
12) Added keyword argument support to the functions that imply such in the
|
||||
documentation as requested by Harald Armin Massa.
|
||||
13) Treat an empty dictionary passed through to cursor.execute() as keyword
|
||||
arguments the same as if no keyword arguments were specified at all, as
|
||||
requested by Fabien Grumelard.
|
||||
14) Fixed memory leak when a LOB read would fail.
|
||||
15) Set the LDFLAGS value in the environment rather than directly in the
|
||||
setup.py file in order to satisfy those who wish to enable the use of
|
||||
debugging symbols.
|
||||
16) Use __DATE__ and __TIME__ to determine the date and time of the build
|
||||
rather than passing it through directly.
|
||||
17) Use Oracle types and add casts to reduce warnings as requested by Amaury
|
||||
Forgeot d'Arc.
|
||||
18) Fixed typo in error message.
|
||||
|
||||
Changes from 4.1.1 to 4.1.2
|
||||
1) Restore support of Oracle 9i features when using the Oracle 10g client.
|
||||
|
||||
Changes from 4.1 to 4.1.1
|
||||
1) Add support for dropping a connection from a session pool.
|
||||
2) Add support for write only attributes "module", "action" and "clientinfo"
|
||||
which work only in Oracle 10g as requested by Egor Starostin.
|
||||
3) Add support for pickling database errors.
|
||||
4) Use the previously created bind variable as a template if available when
|
||||
creating a new variable of a larger size. Thanks to Ted Skolnick for the
|
||||
initial patch.
|
||||
5) Fixed tests to work properly in the Python 2.4 environment where dates and
|
||||
timestamps are different Python types. Thanks to Henning von Bargen for
|
||||
pointing this out.
|
||||
6) Added additional directories to search for include files and libraries in
|
||||
order to better support the Oracle 10g instant client.
|
||||
7) Set the internal fetch number to 0 in order to satisfy very picky source
|
||||
analysis tools as requested by Amaury Fogeot d'Arc.
|
||||
8) Improve the documentation for building and installing the module from
|
||||
source as some people are unaware of the standard methods for building
|
||||
Python modules using distutils.
|
||||
9) Added note in the documentation indicating that the arraysize attribute
|
||||
can drastically affect performance of queries since this seems to be a
|
||||
common misunderstanding of first time users of cx_Oracle.
|
||||
10) Add a comment indicating that on HP-UX Itanium with Oracle 10g the library
|
||||
ttsh10 must alos be linked against. Thanks to Bernard Delmee for the
|
||||
information.
|
||||
|
||||
Changes from 4.1 beta 1 to 4.1
|
||||
1) Fixed bug where subclasses of Cursor do not pass the connection in the
|
||||
constructor causing a segfault.
|
||||
2) DDL statements must be reparsed before execution as noted by Mihai
|
||||
Ibanescu.
|
||||
3) Add support for setting input sizes by position.
|
||||
4) Fixed problem with catching an exception during execute and then still
|
||||
attempting to perform a fetch afterwards as noted by Leith Parkin.
|
||||
5) Rename the types so that they can be pickled and unpickled. Thanks to Harri
|
||||
Pasanen for pointing out the problem.
|
||||
6) Handle invalid NLS_LANG setting properly (Oracle seems to like to provide a
|
||||
handle back even though it is invalid) and determine the number of bytes
|
||||
per character in order to allow for proper support in the future of
|
||||
multibyte and variable width character sets.
|
||||
7) Remove date checking from the native case since Python already checks that
|
||||
dates are valid; enhance error message when invalid dates are encountered
|
||||
so that additional processing can be done.
|
||||
8) Fix bug executing SQL using numeric parameter names with predefined
|
||||
variables (such as what takes place when calling stored procedures with out
|
||||
parameters).
|
||||
9) Add support for reading CLOB values using multibyte or variable length
|
||||
character sets.
|
||||
|
||||
Changes from 4.0.1 to 4.1 beta 1
|
||||
1) Added support for Python 2.4. In Python 2.4, the datetime module is used
|
||||
for both binding and fetching of date and timestamp data. In Python 2.3,
|
||||
objects from the datetime module can be bound but the internal datetime
|
||||
objects will be returned from queries.
|
||||
2) Added pickling support for LOB and datetime data.
|
||||
3) Fully qualified the table name that was missing in an alter table
|
||||
statement in the setup test script as noted by Marc Gehling.
|
||||
4) Added a section allowing for the setting of the RPATH linker directive in
|
||||
setup.py as requested by Iustin Pop.
|
||||
5) Added code to raise a programming error exception when an attempt is made
|
||||
to access a LOB locator variable in a subsequent fetch.
|
||||
6) The username, password and dsn (tnsentry) are stored on the connection
|
||||
object when specified, regardless of whether or not a standard connection
|
||||
takes place.
|
||||
7) Added additional module level constant called "LOB" as requested by Joseph
|
||||
Canedo.
|
||||
8) Changed exception type to IntegrityError for constraint violations as
|
||||
requested by Joseph Canedo.
|
||||
9) If scale and precision are not specified, an attempt is made to return a
|
||||
long integer as requested by Joseph Canedo.
|
||||
10) Added workaround for Oracle bug which returns an invalid handle when the
|
||||
prepare call fails. Thanks to alantam@hsbc.com for providing the code that
|
||||
demonstrated the problem.
|
||||
11) The cusor method arravar() will now accept the actual list so that it is
|
||||
not necessary to call cursor.arrayvar() followed immediately by
|
||||
var.setvalue().
|
||||
12) Fixed bug where attempts to execute the statement "None" with bind
|
||||
variables would cause a segmentation fault.
|
||||
13) Added support for binding by position (paramstyle = "numeric").
|
||||
14) Removed memory leak created by calls to OCIParamGet() which were not
|
||||
mirrored by calls to OCIDescriptorFree(). Thanks to Mihai Ibanescu for
|
||||
pointing this out and providing a patch.
|
||||
15) Added support for calling cursor.executemany() with statement None
|
||||
implying that the previously prepared statement ought to be executed.
|
||||
Thanks to Mihai Ibanescu for providing a patch.
|
||||
16) Added support for rebinding variables when a subsequent call to
|
||||
cursor.executemany() uses a different number of rows. Thanks to Mihai
|
||||
Ibanescu for supplying a patch.
|
||||
17) The microseconds are now displayed in datetime variables when nonzero
|
||||
similar to method used in the datetime module.
|
||||
18) Added support for binary_float and binary_double columns in Oracle 10g.
|
||||
|
||||
Changes from 4.0 to 4.0.1
|
||||
1) Fixed bugs on 64-bit platforms that caused segmentation faults and bus
|
||||
errors in session pooling and determining the bind variables associated
|
||||
with a statement.
|
||||
2) Modified test suite so that 64-bit platforms are tested properly.
|
||||
3) Added missing commit statements in the test setup scripts. Thanks to Keith
|
||||
Lyon for pointing this out.
|
||||
4) Fix setup.py for Cygwin environments. Thanks to Doug Henderson for
|
||||
providing the necessary fix.
|
||||
5) Added support for compiling cx_Oracle without thread support. Thanks to
|
||||
Andre Reitz for pointing this out.
|
||||
6) Added support for a new keyword parameter called threaded on connections
|
||||
and session pools. This parameter defaults to False and indicates whether
|
||||
threaded mode ought to be used. It replaces the module level attribute
|
||||
OPT_Threading although examining the attribute will be retained until the
|
||||
next release at least.
|
||||
7) Added support for a new keyword parameter called twophase on connections.
|
||||
This parameter defaults to False and indicates whether support for two
|
||||
phase (distributed or global) transactions ought to be present. Note that
|
||||
support for distributed transactions is buggy when crossing major version
|
||||
boundaries (Oracle 8i to Oracle 9i for example).
|
||||
8) Ensure that the rowcount attribute is set properly when an exception is
|
||||
raised during execution. Thanks to Gary Aviv for pointing out this problem
|
||||
and its solution.
|
||||
|
||||
Changes from 3.1 to 4.0
|
||||
1) Added support for subclassing connections, cursors and session pools. The
|
||||
changes involved made it necessary to drop support for Python 2.1 and
|
||||
earlier although a branch exists in CVS to allow for support of Python 2.1
|
||||
and earlier if needed.
|
||||
2) Connections and session pools can now be created with keyword parameters,
|
||||
not just sequential parameters.
|
||||
3) Queries now return integers whenever possible and long integers if the
|
||||
number will overflow a simple integer. Floats are only returned when it is
|
||||
known that the number is a floating point number or the integer conversion
|
||||
fails.
|
||||
4) Added initial support for user callbacks on OCI functions. See the
|
||||
documentation for more details.
|
||||
5) Add support for retrieving the bind variable names associated with a
|
||||
cursor with a new method bindnames().
|
||||
6) Add support for temporary LOB variables. This means that setinputsizes()
|
||||
can be used with the values CLOB and BLOB to create these temporary LOB
|
||||
variables and allow for the equivalent of empty_clob() and empty_blob()
|
||||
since otherwise Oracle will treat empty strings as NULL values.
|
||||
7) Automatically switch to long strings when the data size exceeds the
|
||||
maximum string size that Oracle allows (4000 characters) and raise an
|
||||
error if an attempt is made to set a string variable to a size that it
|
||||
does not support. This avoids truncation errors as reported by Jon Franz.
|
||||
8) Add support for global (distributed) transactions and two phase commit.
|
||||
9) Force the NLS settings for the session so that test tables are populated
|
||||
correctly in all circumstances; problems were noted by Ralf Braun and
|
||||
Allan Poulsen.
|
||||
10) Display error messages using the environment handle when the error handle
|
||||
has not yet been created; this provides better error messages during this
|
||||
rather rare situation.
|
||||
11) Removed memory leak in callproc() that was reported by Todd Whiteman.
|
||||
12) Make consistent the calls to manipulate memory; otherwise segfaults can
|
||||
occur when the pymalloc option is used, as reported by Matt Hoskins.
|
||||
13) Force a rollback when a session is released back to the session pool.
|
||||
Apparently the connections are not as stateless as Oracle's documentation
|
||||
suggests and this makes the logic consistent with normal connections.
|
||||
14) Removed module method attach(). This can be replaced with a call to
|
||||
Connection(handle=) if needed.
|
||||
|
||||
Changes from 3.0a to 3.1
|
||||
1) Added support for connecting with SYSDBA and SYSOPER access which is
|
||||
needed for connecting as sys in Oracle 9i.
|
||||
2) Only check the dictionary size if the variable is not NULL; otherwise, an
|
||||
error takes place which is not caught or cleared; this eliminates a
|
||||
spurious "Objects/dictobject.c:1258: bad argument to internal function" in
|
||||
Python 2.3.
|
||||
3) Add support for session pooling. This is only support for Oracle 9i but
|
||||
is amazingly fast -- about 100 times faster than connecting.
|
||||
4) Add support for statement caching when pooling sessions, this reduces the
|
||||
parse time considerably. Unfortunately, the Oracle OCI does not allow this
|
||||
to be easily turned on for normal sessions.
|
||||
5) Add method trim() on CLOB and BLOB variables for trimming the size.
|
||||
6) Add support for externally identified users; to use this feature leave the
|
||||
username and password fields empty when connecting.
|
||||
7) Add method cancel() on connection objects to cancel long running queries.
|
||||
Note that this only works on non-Windows platforms.
|
||||
8) Add method callfunc() on cursor objects to allow calling a function
|
||||
without using an anonymous PL/SQL block.
|
||||
9) Added documentation on objects that were not documented. At this point all
|
||||
objects, methods and constants in cx_Oracle have been documented.
|
||||
10) Added support for timestamp columns in Oracle 9i.
|
||||
11) Added module level method makedsn() which creates a data source name given
|
||||
the host, port and SID.
|
||||
12) Added constant "buildtime" which is the time when the module was built as
|
||||
an additional means of identifying the build that is in use.
|
||||
13) Binding a value that is incompatible to the previous value that was bound
|
||||
(data types do not match or array size is larger) will now result in a
|
||||
new bind taking place. This is more consistent with the DB API although
|
||||
it does imply a performance penalty when used.
|
||||
|
||||
Changes from 3.0 to 3.0a
|
||||
1) Fixed bug where zero length PL/SQL arrays were being mishandled
|
||||
2) Fixed support for the data type "float" in Oracle; added one to the
|
||||
display size to allow for the sign of the number, if necessary; changed
|
||||
the display size of unconstrained numbers to 127, which is the largest
|
||||
number that Oracle can handle
|
||||
3) Added support for retrieving the description of a bound cursor before
|
||||
fetching it
|
||||
4) Fixed a couple of build issues on Mac OS X, AIX and Solaris (64-bit)
|
||||
5) Modified documentation slightly based on comments from several people
|
||||
6) Included files in MANIFEST that are needed to generate the binaries
|
||||
7) Modified test suite to work within the test environment at Computronix
|
||||
as well as within the packages that are distributed
|
||||
|
||||
Changes from 2.5a to 3.0
|
||||
1) Removed support for connection to Oracle7 databases; it is entirely
|
||||
possible that it will still work but I no longer have any way of testing
|
||||
and Oracle has dropped any meaningful support for Oracle7 anyway
|
||||
2) Fetching of strings is now done with predefined memory areas rather than
|
||||
dynamic memory areas; dynamic fetching of strings was causing problems
|
||||
with Oracle 9i in some instances and databases using a different character
|
||||
set other than US ASCII
|
||||
3) Fixed bug where segfault would occur if the '/' character preceded the '@'
|
||||
character in a connect string
|
||||
4) Added two new cursor methods var() and arrayvar() in order to eliminate
|
||||
the need for setinputsizes() when defining PL/SQL arrays and as a generic
|
||||
method of acquiring bind variables directly when needed
|
||||
5) Fixed support for binding cursors and added support for fetching cursors
|
||||
(these are known as ref cursors in PL/SQL).
|
||||
6) Eliminated discrepancy between the array size used internally and the
|
||||
array size specified by the interface user; this was done earlier to avoid
|
||||
bus errors on 64-bit platforms but another way has been found to get
|
||||
around that issue and a number of people were getting confused because of
|
||||
the discrepancy
|
||||
7) Added support for the attribute "connection" on cursors, an optional
|
||||
DB API extension
|
||||
8) Added support for passing a dictionary as the second parameter for the
|
||||
cursor.execute() method in order to comply with the DB API more closely;
|
||||
the method of passing parameters with keyword arguments is still supported
|
||||
and is in fact preferred
|
||||
9) Added support for the attribute "statement" on cursors which is a
|
||||
reference to the last SQL statement prepared or executed
|
||||
10) Added support for passing any sequence to callproc() rather than just
|
||||
lists as before
|
||||
11) Fixed bug where segfault would occur if the array size was changed after
|
||||
the cursor was executed but before it was fetched
|
||||
12) Ignore array size when performing executemany() and use the length of the
|
||||
list of arguments instead
|
||||
13) Rollback when connection is closed or destroyed to follow DB API rather
|
||||
than use the Oracle default (which is commit)
|
||||
14) Added check for array size too large causing an integer overflow
|
||||
15) Added support for iterators for Python 2.2 and above
|
||||
16) Added test suite based on PyUnitTest
|
||||
17) Added documentation in HTML format similar to the documentation for the
|
||||
core Python library
|
||||
|
||||
Changes from 2.5 to 2.5a
|
||||
1) Fix problem with Oracle 9i and retrieving strings; it seems that Oracle 9i
|
||||
uses the correct method for dynamic callback but Oracle 8i will not work
|
||||
with that method so an #ifdef was added to check for the existence of an
|
||||
Oracle 9i feature; thanks to Paul Denize for discovering this problem
|
||||
|
||||
Changes from 2.4 to 2.5
|
||||
1) Added flag OPT_NoOracle7 which, if set, assumes that connections are being
|
||||
made to Oracle8 or higher databases; this allows for eliminating the
|
||||
overhead in performing this check at connect time
|
||||
2) Added flag OPT_NumbersAsStrings which, if set, returns all numbers as
|
||||
strings rather than integers or floats; this flag is used when defined
|
||||
variables are created (during select statements only)
|
||||
3) Added flag OPT_Threading which, if set, uses OCI threading mode; there is a
|
||||
significant performance degradation in this mode (about 15-20%) but it does
|
||||
allow threads to share connections (threadsafety level 2 according to the
|
||||
Python Database API 2.0); note that in order to support this, Oracle 8i or
|
||||
higher is now required
|
||||
4) Added Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS pairs where
|
||||
applicable to support threading during blocking OCI calls
|
||||
5) Added global method attach() to cx_Oracle to support attaching to an
|
||||
existing database handle (as provided by PowerBuilder, for example)
|
||||
6) Eliminated the cursor method fetchbinds() which was used for returning the
|
||||
list of bind variables after execution to get the values of out variables;
|
||||
the cursor method setinputsizes() was modified to return the list of bind
|
||||
variables and the cursor method execute() was modified to return the list
|
||||
of defined variables in the case of a select statement being executed;
|
||||
these variables have three methods available to them: getvalue([<pos>]) to
|
||||
get the value of a variable, setvalue(<pos>, <value>) to set its value and
|
||||
copy(<var>, <src_pos>, <targ_pos>) to copy the value from a variable in a
|
||||
more efficient manner than setvalue(getvalue())
|
||||
7) Implemented cursor method executemany() which expects a list of
|
||||
dictionaries for the arguments
|
||||
8) Implemented cursor method callproc()
|
||||
9) Added cursr method prepare() which parses (prepares) the statement for
|
||||
execution; subsequent execute() or executemany() calls can pass None as the
|
||||
statement which will imply use of the previously prepared statement; used
|
||||
for high performance only
|
||||
10) Added cursor method fetchraw() which will perform a raw fetch of the cursor
|
||||
returning the number of rows thus fetched; this is used to avoid the
|
||||
overhead of generating result sets; used for high performance only
|
||||
11) Added cursor method executemanyprepared() which is identical to the method
|
||||
executemany() except that it takes a single argument which is the number of
|
||||
times to execute a previously prepared statement and it assumes that the
|
||||
bind variables already have their values set; used for high performance
|
||||
only
|
||||
12) Added support for rowid being returned in a select statement
|
||||
13) Added support for comparing dates returned by cx_Oracle
|
||||
14) Integrated patch from Andre Reitz to set the null ok flag in the
|
||||
description attribute of the cursor
|
||||
15) Integrated patch from Andre Reitz to setup.py to support compilation with
|
||||
Python 1.5
|
||||
16) Integrated patch from Benjamin Kearns to setup.py to support compilation
|
||||
on Cygwin
|
||||
|
||||
Changes from 2.3 to 2.4
|
||||
|
||||
1) String variables can now be made any length (previously restricted to the
|
||||
64K limit imposed by Oracle for default binding); use the type
|
||||
cx_Oracle.LONG_STRING as the argument to setinputsizes() for binding in
|
||||
string values larger than 4000 bytes.
|
||||
2) Raw and long raw columns are now supported; use the types cx_Oracle.BINARY
|
||||
and cx_Oracle.LONG_BINARY as the argument to setinputsizes() for binding in
|
||||
values of these types.
|
||||
3) Functions DateFromTicks(), TimeFromTicks() and TimestampFromTicks()
|
||||
are now implemented.
|
||||
4) Function cursor.setoutputsize() implemented
|
||||
5) Added the ability to bind arrays as out parameters to procedures; use the
|
||||
format [cx_Oracle.<DataType>, <NumElems>] as the input to the function
|
||||
setinputsizes() for binding arrays
|
||||
6) Discovered from the Oracle 8.1.6 version of the documentation of the OCI
|
||||
libraries, that the size of the memory location required for the precision
|
||||
variable is larger than the printed documentation says; this was causing a
|
||||
problem with the code on the Sun platform.
|
||||
7) Now support building RPMs for Linux.
|
||||
|
||||
Changes from 2.2 to 2.3
|
||||
|
||||
1) Incremental performance enhancements (dealing with reusing cursors and
|
||||
bind handles)
|
||||
2) Ensured that arrays of integers with a single float in them are all
|
||||
treated as floats, as suggested by Martin Koch.
|
||||
3) Fixed code dealing with scale and precision for both defining a numeric
|
||||
variable and for providing the cursor description; this eliminates the
|
||||
problem of an underflow error (OCI-22054) when retrieving data with
|
||||
non-zero scale.
|
||||
|
||||
Changes from 2.1 to 2.2
|
||||
|
||||
1) Upgraded thread safety to level 1 (according to the Python DB API 2.0) as
|
||||
an internal project required the ability to share the module between
|
||||
threads.
|
||||
2) Added ability to bind ref cursors to PL/SQL blocks as requested by
|
||||
Brad Powell.
|
||||
3) Added function write(Value, [Offset]) to LOB variables as requested by
|
||||
Matthias Kirst.
|
||||
4) Procedure execute() on Cursor objects now permits a value None for the
|
||||
statement which means that the previously prepared statement will be
|
||||
executed and any input sizes set earlier will be retained. This was done to
|
||||
improve the performance of scripts that execute one statement many times.
|
||||
5) Modified module global constants BINARY and DATETIME to point to the
|
||||
external representations of those types so that the expression
|
||||
type(var) == cx_Oracle.DATETIME will work as expected.
|
||||
6) Added global constant version to provide means of determining the current
|
||||
version of the module.
|
||||
7) Modified error checking routine to distinguish between an Oracle error and
|
||||
invalid handles.
|
||||
8) Added error checking to avoid setting the value of a bind variable to a
|
||||
value that it cannot support and raised an exception to indicate this fact.
|
||||
9) Added extra compile arguments for the AIX platform as suggested by Jehwan
|
||||
Ryu.
|
||||
10) Added section to the README to indicate the method for a binary
|
||||
installation as suggested by Steve Holden.
|
||||
11) Added simple usage example as requested by many people.
|
||||
12) Added HISTORY file to the distribution.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
Copyright © 2001-2007, Computronix (Canada) Ltd., Edmonton, Alberta, Canada.
|
||||
All rights reserved.
|
||||
|
||||
License for cx_Oracle
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the disclaimer that follows.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of Computronix nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
DISCLAIMER:
|
||||
THIS SOFTWARE IS PROVIDED BY COMPUTRONIX AND CONTRIBUTORS *AS IS*
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COMPUTRONIX
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Computronix® is a registered trademark of Computronix (Canada) Ltd.
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// LobVar.c
|
||||
// Defines the routines for handling LOB variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LOB type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
OCILobLocator **data;
|
||||
udt_Connection *connection;
|
||||
int isFile;
|
||||
} udt_LobVar;
|
||||
|
||||
#include "ExternalLobVar.c"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of LOB variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int LobVar_Initialize(udt_LobVar*, udt_Cursor*);
|
||||
static void LobVar_Finalize(udt_LobVar*);
|
||||
static PyObject *LobVar_GetValue(udt_LobVar*, unsigned);
|
||||
static int LobVar_SetValue(udt_LobVar*, unsigned, PyObject*);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_CLOBVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.CLOB", // tp_name
|
||||
sizeof(udt_LobVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_NCLOBVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.NCLOB", // tp_name
|
||||
sizeof(udt_LobVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_BLOBVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.BLOB", // tp_name
|
||||
sizeof(udt_LobVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_BFILEVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.BFILE", // tp_name
|
||||
sizeof(udt_LobVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_CLOB = {
|
||||
(InitializeProc) LobVar_Initialize,
|
||||
(FinalizeProc) LobVar_Finalize,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) LobVar_SetValue,
|
||||
(GetValueProc) LobVar_GetValue,
|
||||
&g_CLOBVarType, // Python type
|
||||
SQLT_CLOB, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCILobLocator*), // element length
|
||||
0, // is variable length
|
||||
0, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_NCLOB = {
|
||||
(InitializeProc) LobVar_Initialize,
|
||||
(FinalizeProc) LobVar_Finalize,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) LobVar_SetValue,
|
||||
(GetValueProc) LobVar_GetValue,
|
||||
&g_NCLOBVarType, // Python type
|
||||
SQLT_CLOB, // Oracle type
|
||||
SQLCS_NCHAR, // charset form
|
||||
sizeof(OCILobLocator*), // element length
|
||||
0, // is variable length
|
||||
0, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_BLOB = {
|
||||
(InitializeProc) LobVar_Initialize,
|
||||
(FinalizeProc) LobVar_Finalize,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) LobVar_SetValue,
|
||||
(GetValueProc) LobVar_GetValue,
|
||||
&g_BLOBVarType, // Python type
|
||||
SQLT_BLOB, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCILobLocator*), // element length
|
||||
0, // is variable length
|
||||
0, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_BFILE = {
|
||||
(InitializeProc) LobVar_Initialize,
|
||||
(FinalizeProc) LobVar_Finalize,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) LobVar_SetValue,
|
||||
(GetValueProc) LobVar_GetValue,
|
||||
&g_BFILEVarType, // Python type
|
||||
SQLT_BFILE, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCILobLocator*), // element length
|
||||
0, // is variable length
|
||||
0, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LobVar_Initialize()
|
||||
// Initialize the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int LobVar_Initialize(
|
||||
udt_LobVar *var, // variable to initialize
|
||||
udt_Cursor *cursor) // cursor created by
|
||||
{
|
||||
sword status;
|
||||
ub4 i;
|
||||
|
||||
// initialize members
|
||||
Py_INCREF(cursor->connection);
|
||||
var->connection = cursor->connection;
|
||||
var->isFile = (var->type == &vt_BFILE);
|
||||
|
||||
// initialize the LOB locators
|
||||
for (i = 0; i < var->allocatedElements; i++) {
|
||||
status = OCIDescriptorAlloc(var->environment->handle,
|
||||
(dvoid**) &var->data[i], OCI_DTYPE_LOB, 0, 0);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"LobVar_Initialize()") < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LobVar_Finalize()
|
||||
// Prepare for variable destruction.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void LobVar_Finalize(
|
||||
udt_LobVar *var) // variable to free
|
||||
{
|
||||
boolean isTemporary;
|
||||
ub4 i;
|
||||
|
||||
for (i = 0; i < var->allocatedElements; i++) {
|
||||
if (var->data[i]) {
|
||||
OCILobIsTemporary(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[i], &isTemporary);
|
||||
if (isTemporary)
|
||||
OCILobFreeTemporary(var->connection->handle,
|
||||
var->environment->errorHandle, var->data[i]);
|
||||
OCIDescriptorFree(var->data[i], OCI_DTYPE_LOB);
|
||||
}
|
||||
}
|
||||
Py_DECREF(var->connection);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LobVar_GetValue()
|
||||
// Returns the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *LobVar_GetValue(
|
||||
udt_LobVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
return ExternalLobVar_New(var, pos);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LobVar_SetValue()
|
||||
// Sets the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int LobVar_SetValue(
|
||||
udt_LobVar *var, // variable to determine value for
|
||||
unsigned pos, // array position
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
boolean isTemporary;
|
||||
sword status;
|
||||
ub1 lobType;
|
||||
ub4 length;
|
||||
|
||||
// only support strings
|
||||
if (!PyString_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting string data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// make sure have temporary LOBs set up
|
||||
status = OCILobIsTemporary(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[pos], &isTemporary);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"LobVar_SetValue(): is temporary?") < 0)
|
||||
return -1;
|
||||
if (!isTemporary) {
|
||||
if (var->type->oracleType == SQLT_BLOB)
|
||||
lobType = OCI_TEMP_BLOB;
|
||||
else lobType = OCI_TEMP_CLOB;
|
||||
status = OCILobCreateTemporary(var->connection->handle,
|
||||
var->environment->errorHandle, var->data[pos], OCI_DEFAULT,
|
||||
OCI_DEFAULT, lobType, FALSE, OCI_DURATION_SESSION);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"LobVar_SetValue(): create temporary") < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// trim the current value
|
||||
status = OCILobTrim(var->connection->handle,
|
||||
var->environment->errorHandle, var->data[pos], 0);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"LobVar_SetValue(): trim") < 0)
|
||||
return -1;
|
||||
|
||||
// set the current value
|
||||
length = PyString_GET_SIZE(value);
|
||||
if (length) {
|
||||
status = OCILobWrite(var->connection->handle,
|
||||
var->environment->errorHandle, var->data[pos],
|
||||
&length, 1, PyString_AS_STRING(value),
|
||||
PyString_GET_SIZE(value), OCI_ONE_PIECE, NULL, NULL, 0, 0);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"LobVar_SetValue(): write") < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// LongVar.c
|
||||
// Defines the routines specific to the long type.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// long type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
char *data;
|
||||
} udt_LongVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of long variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int LongVar_SetValue(udt_LongVar*, unsigned, PyObject*);
|
||||
static PyObject *LongVar_GetValue(udt_LongVar*, unsigned);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_LongStringVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.LONG_STRING", // tp_name
|
||||
sizeof(udt_LongVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_LongBinaryVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.LONG_BINARY", // tp_name
|
||||
sizeof(udt_LongVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_LongString = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) LongVar_SetValue,
|
||||
(GetValueProc) LongVar_GetValue,
|
||||
&g_LongStringVarType, // Python type
|
||||
SQLT_LVC, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
128 * 1024, // element length (default)
|
||||
1, // is variable length
|
||||
1, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_LongBinary = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) LongVar_SetValue,
|
||||
(GetValueProc) LongVar_GetValue,
|
||||
&g_LongBinaryVarType, // Python type
|
||||
SQLT_LVB, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
128 * 1024, // element length (default)
|
||||
1, // is variable length
|
||||
1, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LongVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int LongVar_SetValue(
|
||||
udt_LongVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
Py_ssize_t bufferSize;
|
||||
const void *buffer;
|
||||
char *ptr;
|
||||
|
||||
// get the buffer data and size for binding
|
||||
if (PyString_Check(value)) {
|
||||
buffer = PyString_AS_STRING(value);
|
||||
bufferSize = PyString_GET_SIZE(value);
|
||||
} else if (PyBuffer_Check(value)) {
|
||||
if (PyObject_AsReadBuffer(value, &buffer, &bufferSize) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting string or buffer data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// copy the string to the Oracle buffer
|
||||
if (bufferSize + sizeof(ub4) > var->maxLength) {
|
||||
if (Variable_Resize( (udt_Variable*) var,
|
||||
bufferSize + sizeof(ub4)) < 0)
|
||||
return -1;
|
||||
}
|
||||
ptr = var->data + var->maxLength * pos;
|
||||
*((ub4 *) ptr) = (ub4) bufferSize;
|
||||
if (bufferSize)
|
||||
memcpy(ptr + sizeof(ub4), buffer, bufferSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LongVar_GetValue()
|
||||
// Returns the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *LongVar_GetValue(
|
||||
udt_LongVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
char *ptr;
|
||||
ub4 size;
|
||||
|
||||
ptr = var->data + var->maxLength * pos;
|
||||
size = *((ub4 *) ptr);
|
||||
return PyString_FromStringAndSize(ptr + sizeof(ub4), size);
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
setup.py
|
||||
setup.cfg
|
||||
README.txt
|
||||
LICENSE.txt
|
||||
HISTORY.txt
|
||||
MANIFEST
|
||||
Callback.c
|
||||
Connection.c
|
||||
Cursor.c
|
||||
CursorVar.c
|
||||
cx_Oracle.c
|
||||
DateTimeVar.c
|
||||
Environment.c
|
||||
Error.c
|
||||
ExternalDateTimeVar.c
|
||||
ExternalLobVar.c
|
||||
ExternalObjectVar.c
|
||||
LobVar.c
|
||||
LongVar.c
|
||||
NumberVar.c
|
||||
ObjectType.c
|
||||
ObjectVar.c
|
||||
SessionPool.c
|
||||
StringVar.c
|
||||
TimestampVar.c
|
||||
Transforms.c
|
||||
Variable.c
|
||||
html/about.html
|
||||
html/blank.png
|
||||
html/connobj.html
|
||||
html/contents.html
|
||||
html/contents.png
|
||||
html/cursorobj.html
|
||||
html/cx_Oracle.css
|
||||
html/cx_Oracle.html
|
||||
html/dateobj.html
|
||||
html/front.html
|
||||
html/index.html
|
||||
html/index.png
|
||||
html/lobobj.html
|
||||
html/module.html
|
||||
html/modules.png
|
||||
html/next.png
|
||||
html/node12.html
|
||||
html/node4.html
|
||||
html/node5.html
|
||||
html/previous.png
|
||||
html/sesspool.html
|
||||
html/up.png
|
||||
html/varobj.html
|
||||
test/Connection.py
|
||||
test/Cursor.py
|
||||
test/CursorVar.py
|
||||
test/DateTimeVar.py
|
||||
test/LobVar.py
|
||||
test/LongVar.py
|
||||
test/NumberVar.py
|
||||
test/ObjectVar.py
|
||||
test/SessionPool.py
|
||||
test/SetupTest_9i.sql
|
||||
test/SetupTest.sql
|
||||
test/StringVar.py
|
||||
test/test_dbapi20.py
|
||||
test/TestEnv.py
|
||||
test/test.py
|
||||
test/TimestampVar.py
|
|
@ -0,0 +1,508 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// NumberVar.c
|
||||
// Defines the routines for handling numeric variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// define number format used for acquiring long integers
|
||||
//-----------------------------------------------------------------------------
|
||||
static const char gc_NumberFormat[63] =
|
||||
"999999999999999999999999999999999999999999999999999999999999999";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Number type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
OCINumber *data;
|
||||
} udt_NumberVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of number variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_PreDefine(udt_NumberVar*, OCIParam*);
|
||||
static int NumberVar_SetValue(udt_NumberVar*, unsigned, PyObject*);
|
||||
static PyObject *NumberVar_GetValue(udt_NumberVar*, unsigned);
|
||||
#ifdef SQLT_BFLOAT
|
||||
static int NumberVar_SetValueAsDouble(udt_NumberVar*, unsigned, PyObject*);
|
||||
static PyObject *NumberVar_GetValueAsDouble(udt_NumberVar*, unsigned);
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declaration
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_NumberVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.NUMBER", // tp_name
|
||||
sizeof(udt_NumberVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_Float = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NumberVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) NumberVar_SetValue,
|
||||
(GetValueProc) NumberVar_GetValue,
|
||||
&g_NumberVarType, // Python type
|
||||
SQLT_VNU, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCINumber), // element length
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
#ifdef SQLT_BFLOAT
|
||||
static udt_VariableType vt_NativeFloat = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) NumberVar_SetValueAsDouble,
|
||||
(GetValueProc) NumberVar_GetValueAsDouble,
|
||||
&g_NumberVarType, // Python type
|
||||
SQLT_BDOUBLE, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(double), // element length
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static udt_VariableType vt_Integer = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NumberVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) NumberVar_SetValue,
|
||||
(GetValueProc) NumberVar_GetValue,
|
||||
&g_NumberVarType, // Python type
|
||||
SQLT_VNU, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCINumber), // element length
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_LongInteger = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NumberVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) NumberVar_SetValue,
|
||||
(GetValueProc) NumberVar_GetValue,
|
||||
&g_NumberVarType, // Python type
|
||||
SQLT_VNU, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCINumber), // element length
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_NumberAsString = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NumberVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) NumberVar_SetValue,
|
||||
(GetValueProc) NumberVar_GetValue,
|
||||
&g_NumberVarType, // Python type
|
||||
SQLT_VNU, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCINumber), // element length
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_Boolean = {
|
||||
(InitializeProc) NULL,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NumberVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) NumberVar_SetValue,
|
||||
(GetValueProc) NumberVar_GetValue,
|
||||
&g_NumberVarType, // Python type
|
||||
SQLT_VNU, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCINumber), // element length
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_PreDefine()
|
||||
// Set the type of value (integer, float or string) that will be returned
|
||||
// when values are fetched from this variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_PreDefine(
|
||||
udt_NumberVar *var, // variable to initialize
|
||||
OCIParam *param) // parameter handle
|
||||
{
|
||||
sb2 precision;
|
||||
sword status;
|
||||
sb1 scale;
|
||||
|
||||
// if the return type has not already been specified, check to see if the
|
||||
// number can fit inside an integer by looking at the precision and scale
|
||||
if (var->type == &vt_Float) {
|
||||
scale = 0;
|
||||
precision = 0;
|
||||
status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &scale, 0,
|
||||
OCI_ATTR_SCALE, var->environment->errorHandle);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_PreDefine(): scale") < 0)
|
||||
return -1;
|
||||
status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &precision, 0,
|
||||
OCI_ATTR_PRECISION, var->environment->errorHandle);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_PreDefine(): precision") < 0)
|
||||
return -1;
|
||||
if (scale == 0 && precision > 0 && precision < 10)
|
||||
var->type = &vt_Integer;
|
||||
else if (scale == 0 || (scale == -127 && precision == 0))
|
||||
var->type = &vt_LongInteger;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if (PY_VERSION_HEX >= 0x02030000)
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_SetValueFromBoolean()
|
||||
// Set the value of the variable from a Python boolean.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_SetValueFromBoolean(
|
||||
udt_NumberVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
long integerValue;
|
||||
sword status;
|
||||
|
||||
integerValue = (value == Py_True);
|
||||
status = OCINumberFromInt(var->environment->errorHandle, &integerValue,
|
||||
sizeof(long), OCI_NUMBER_SIGNED, &var->data[pos]);
|
||||
return Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_SetValueFromBoolean()");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_SetValueFromInteger()
|
||||
// Set the value of the variable from a Python integer.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_SetValueFromInteger(
|
||||
udt_NumberVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
long integerValue;
|
||||
sword status;
|
||||
|
||||
integerValue = PyInt_AS_LONG(value);
|
||||
status = OCINumberFromInt(var->environment->errorHandle, &integerValue,
|
||||
sizeof(long), OCI_NUMBER_SIGNED, &var->data[pos]);
|
||||
return Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_SetValueFromInteger()");
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_SetValueFromFloat()
|
||||
// Set the value of the variable from a Python float.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_SetValueFromFloat(
|
||||
udt_NumberVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
double doubleValue;
|
||||
sword status;
|
||||
|
||||
doubleValue = PyFloat_AS_DOUBLE(value);
|
||||
status = OCINumberFromReal(var->environment->errorHandle, &doubleValue,
|
||||
sizeof(double), &var->data[pos]);
|
||||
return Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_SetValueFromFloat()");
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_SetValueFromLong()
|
||||
// Set the value of the variable from a Python long.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_SetValueFromLong(
|
||||
udt_NumberVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
PyObject *textValue;
|
||||
sword status;
|
||||
|
||||
textValue = PyObject_Str(value);
|
||||
if (!textValue)
|
||||
return -1;
|
||||
status = OCINumberFromText(var->environment->errorHandle,
|
||||
(OraText*) PyString_AS_STRING(textValue),
|
||||
PyString_GET_SIZE(textValue), (OraText*) gc_NumberFormat,
|
||||
sizeof(gc_NumberFormat), NULL, 0, &var->data[pos]);
|
||||
Py_DECREF(textValue);
|
||||
return Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_SetValueFromLong()");
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_GetFormatAndTextFromDecimal()
|
||||
// Return the number format and text to use for the Decimal object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_GetFormatAndTextFromDecimal(
|
||||
PyObject *tupleValue, // decimal as_tuple() value
|
||||
char **textValue, // text string for conversion
|
||||
char **format) // format for conversion
|
||||
{
|
||||
long numDigits, scale, i, sign, length, digit;
|
||||
char *valuePtr, *formatPtr;
|
||||
PyObject *digits;
|
||||
|
||||
// acquire basic information from the value tuple
|
||||
sign = PyInt_AS_LONG(PyTuple_GET_ITEM(tupleValue, 0));
|
||||
digits = PyTuple_GET_ITEM(tupleValue, 1);
|
||||
scale = PyInt_AS_LONG(PyTuple_GET_ITEM(tupleValue, 2));
|
||||
numDigits = PyTuple_GET_SIZE(digits);
|
||||
|
||||
// allocate memory for the string and format to use in conversion
|
||||
length = numDigits + abs(scale) + 3;
|
||||
*textValue = valuePtr = PyMem_Malloc(length);
|
||||
if (!*textValue) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
*format = formatPtr = PyMem_Malloc(length);
|
||||
if (!*format) {
|
||||
PyMem_Free(*textValue);
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// populate the string and format
|
||||
if (sign)
|
||||
*valuePtr++ = '-';
|
||||
for (i = 0; i < numDigits + scale; i++) {
|
||||
*formatPtr++ = '9';
|
||||
if (i < numDigits)
|
||||
digit = PyInt_AS_LONG(PyTuple_GetItem(digits, i));
|
||||
else digit = 0;
|
||||
*valuePtr++ = '0' + (char) digit;
|
||||
}
|
||||
if (scale < 0) {
|
||||
*formatPtr++ = 'D';
|
||||
*valuePtr++ = '.';
|
||||
for (i = scale; i < 0; i++) {
|
||||
*formatPtr++ = '9';
|
||||
if (numDigits + i < 0)
|
||||
digit = 0;
|
||||
else digit = PyInt_AS_LONG(PyTuple_GetItem(digits, numDigits + i));
|
||||
*valuePtr++ = '0' + (char) digit;
|
||||
}
|
||||
}
|
||||
*formatPtr = '\0';
|
||||
*valuePtr = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_SetValueFromDecimal()
|
||||
// Set the value of the variable from a Python decimal.Decimal object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_SetValueFromDecimal(
|
||||
udt_NumberVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
char *textValue, *format;
|
||||
PyObject *tupleValue;
|
||||
sword status;
|
||||
|
||||
tupleValue = PyObject_CallMethod(value, "as_tuple", NULL);
|
||||
if (!tupleValue)
|
||||
return -1;
|
||||
if (NumberVar_GetFormatAndTextFromDecimal(tupleValue, &textValue,
|
||||
&format) < 0) {
|
||||
Py_DECREF(tupleValue);
|
||||
return -1;
|
||||
}
|
||||
status = OCINumberFromText(var->environment->errorHandle,
|
||||
(OraText*) textValue, strlen(textValue), (OraText*) format,
|
||||
strlen(format), NULL, 0, &var->data[pos]);
|
||||
Py_DECREF(tupleValue);
|
||||
PyMem_Free(textValue);
|
||||
PyMem_Free(format);
|
||||
return Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_SetValueFromDecimal()");
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_SetValue(
|
||||
udt_NumberVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
if (PyInt_Check(value))
|
||||
return NumberVar_SetValueFromInteger(var, pos, value);
|
||||
#if (PY_VERSION_HEX >= 0x02030000)
|
||||
else if (PyBool_Check(value))
|
||||
return NumberVar_SetValueFromBoolean(var, pos, value);
|
||||
#endif
|
||||
else if (PyFloat_Check(value))
|
||||
return NumberVar_SetValueFromFloat(var, pos, value);
|
||||
else if (PyLong_Check(value))
|
||||
return NumberVar_SetValueFromLong(var, pos, value);
|
||||
else if (value->ob_type == g_DecimalType)
|
||||
return NumberVar_SetValueFromDecimal(var, pos, value);
|
||||
PyErr_SetString(PyExc_TypeError, "expecting numeric data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SQLT_BFLOAT
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_SetValueAsDouble()
|
||||
// Set the value of the variable which should be a native double.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NumberVar_SetValueAsDouble(
|
||||
udt_NumberVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
double *doublePtr;
|
||||
|
||||
if (!PyFloat_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting float");
|
||||
return -1;
|
||||
}
|
||||
|
||||
doublePtr = (double*) &var->data[pos];
|
||||
*doublePtr = PyFloat_AS_DOUBLE(value);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_GetValue()
|
||||
// Returns the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *NumberVar_GetValue(
|
||||
udt_NumberVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
char stringValue[200];
|
||||
long integerValue;
|
||||
ub4 stringLength;
|
||||
PyObject *result;
|
||||
sword status;
|
||||
|
||||
if (var->type == &vt_Integer || var->type == &vt_Boolean) {
|
||||
status = OCINumberToInt(var->environment->errorHandle, &var->data[pos],
|
||||
sizeof(long), OCI_NUMBER_SIGNED, (dvoid*) &integerValue);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_GetValue(): as integer") < 0)
|
||||
return NULL;
|
||||
if (var->type == &vt_Integer)
|
||||
return PyInt_FromLong(integerValue);
|
||||
#if (PY_VERSION_HEX >= 0x02030000)
|
||||
return PyBool_FromLong(integerValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (var->type == &vt_NumberAsString || var->type == &vt_LongInteger) {
|
||||
stringLength = sizeof(stringValue);
|
||||
status = OCINumberToText(var->environment->errorHandle,
|
||||
&var->data[pos], (unsigned char*) "TM9", 3, NULL, 0,
|
||||
&stringLength, (unsigned char*) stringValue);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"NumberVar_GetValue(): as string") < 0)
|
||||
return NULL;
|
||||
if (var->type == &vt_NumberAsString)
|
||||
return PyString_FromStringAndSize(stringValue, stringLength);
|
||||
result = PyInt_FromString(stringValue, NULL, 10);
|
||||
if (result || !PyErr_ExceptionMatches(PyExc_ValueError))
|
||||
return result;
|
||||
PyErr_Clear();
|
||||
result = PyLong_FromString(stringValue, NULL, 10);
|
||||
if (result || !PyErr_ExceptionMatches(PyExc_ValueError))
|
||||
return result;
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
return OracleNumberToPythonFloat(var->environment, &var->data[pos]);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SQLT_BFLOAT
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_GetValueAsDouble()
|
||||
// Returns the value stored at the given array position as a float.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *NumberVar_GetValueAsDouble(
|
||||
udt_NumberVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
double *doublePtr;
|
||||
|
||||
doublePtr = (double*) &var->data[pos];
|
||||
return PyFloat_FromDouble(*doublePtr);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,518 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// ObjectType.c
|
||||
// Defines the routines for handling Oracle type information.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// structures used for handling object types
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
udt_Environment *environment;
|
||||
OCIType *tdo;
|
||||
PyObject *schema;
|
||||
PyObject *name;
|
||||
PyObject *attributes;
|
||||
PyObject *attributesByName;
|
||||
OCITypeCode collectionTypeCode;
|
||||
OCITypeCode elementTypeCode;
|
||||
PyObject *elementType;
|
||||
int isCollection;
|
||||
} udt_ObjectType;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *name;
|
||||
OCITypeCode typeCode;
|
||||
udt_ObjectType *subType;
|
||||
} udt_ObjectAttribute;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of type variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_ObjectType *ObjectType_New(udt_Connection*, OCIParam*);
|
||||
static void ObjectType_Free(udt_ObjectType*);
|
||||
static PyObject *ObjectType_Repr(udt_ObjectType*);
|
||||
static udt_ObjectAttribute *ObjectAttribute_New(udt_Connection*, OCIParam*);
|
||||
static void ObjectAttribute_Free(udt_ObjectAttribute*);
|
||||
static PyObject *ObjectAttribute_Repr(udt_ObjectAttribute*);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of members for Python type "ObjectType"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMemberDef g_ObjectTypeMembers[] = {
|
||||
{ "schema", T_OBJECT, offsetof(udt_ObjectType, schema), READONLY },
|
||||
{ "name", T_OBJECT, offsetof(udt_ObjectType, name), READONLY },
|
||||
{ "attributes", T_OBJECT, offsetof(udt_ObjectType, attributes), READONLY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of members for Python type "ObjectAttribute"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMemberDef g_ObjectAttributeMembers[] = {
|
||||
{ "name", T_OBJECT, offsetof(udt_ObjectAttribute, name), READONLY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_ObjectTypeType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.ObjectType", // tp_name
|
||||
sizeof(udt_ObjectType), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) ObjectType_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) ObjectType_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, // tp_flags
|
||||
0, // tp_doc
|
||||
0, // tp_traverse
|
||||
0, // tp_clear
|
||||
0, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
0, // tp_methods
|
||||
g_ObjectTypeMembers, // tp_members
|
||||
0, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
0, // tp_descr_get
|
||||
0, // tp_descr_set
|
||||
0, // tp_dictoffset
|
||||
0, // tp_init
|
||||
0, // tp_alloc
|
||||
0, // tp_new
|
||||
0, // tp_free
|
||||
0, // tp_is_gc
|
||||
0 // tp_bases
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_ObjectAttributeType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.ObjectAttribute", // tp_name
|
||||
sizeof(udt_ObjectAttribute), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) ObjectAttribute_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) ObjectAttribute_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, // tp_flags
|
||||
0, // tp_doc
|
||||
0, // tp_traverse
|
||||
0, // tp_clear
|
||||
0, // tp_richcompare
|
||||
0, // tp_weaklistoffset
|
||||
0, // tp_iter
|
||||
0, // tp_iternext
|
||||
0, // tp_methods
|
||||
g_ObjectAttributeMembers, // tp_members
|
||||
0, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
0, // tp_descr_get
|
||||
0, // tp_descr_set
|
||||
0, // tp_dictoffset
|
||||
0, // tp_init
|
||||
0, // tp_alloc
|
||||
0, // tp_new
|
||||
0, // tp_free
|
||||
0, // tp_is_gc
|
||||
0 // tp_bases
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectType_Describe()
|
||||
// Describe the type and store information about it as needed.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectType_Describe(
|
||||
udt_ObjectType *self, // type to populate
|
||||
udt_Connection *connection, // connection for type information
|
||||
OCIDescribe *describeHandle) // describe handle
|
||||
{
|
||||
OCIParam *topLevelParam, *attributeListParam, *attributeParam;
|
||||
udt_ObjectAttribute *attribute;
|
||||
OCIParam *collectionParam;
|
||||
OCITypeCode typeCode;
|
||||
ub2 numAttributes;
|
||||
sword status;
|
||||
int i;
|
||||
|
||||
// describe the type
|
||||
status = OCIDescribeAny(connection->handle, self->environment->errorHandle,
|
||||
(dvoid*) self->tdo, 0, OCI_OTYPE_PTR, OCI_DEFAULT, OCI_PTYPE_TYPE,
|
||||
describeHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): describe type") < 0)
|
||||
return -1;
|
||||
|
||||
// get top level parameter descriptor
|
||||
status = OCIAttrGet(describeHandle, OCI_HTYPE_DESCRIBE, &topLevelParam, 0,
|
||||
OCI_ATTR_PARAM, self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get top level parameter descriptor") < 0)
|
||||
return -1;
|
||||
|
||||
// determine type of type
|
||||
status = OCIAttrGet(topLevelParam, OCI_DTYPE_PARAM, &typeCode, 0,
|
||||
OCI_ATTR_TYPECODE, self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get type code") < 0)
|
||||
return -1;
|
||||
|
||||
// if a collection, need to determine the sub type
|
||||
if (typeCode == OCI_TYPECODE_NAMEDCOLLECTION) {
|
||||
self->isCollection = 1;
|
||||
|
||||
// determine type of collection
|
||||
status = OCIAttrGet(topLevelParam, OCI_DTYPE_PARAM,
|
||||
&self->collectionTypeCode, 0, OCI_ATTR_COLLECTION_TYPECODE,
|
||||
self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get collection type code") < 0)
|
||||
return -1;
|
||||
|
||||
// acquire collection parameter descriptor
|
||||
status = OCIAttrGet(topLevelParam, OCI_DTYPE_PARAM, &collectionParam,
|
||||
0, OCI_ATTR_COLLECTION_ELEMENT,
|
||||
self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get collection descriptor") < 0)
|
||||
return -1;
|
||||
|
||||
// determine type of element
|
||||
status = OCIAttrGet(collectionParam, OCI_DTYPE_PARAM,
|
||||
&self->elementTypeCode, 0, OCI_ATTR_TYPECODE,
|
||||
self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get element type code") < 0)
|
||||
return -1;
|
||||
|
||||
// if element type is an object type get its type
|
||||
if (self->elementTypeCode == OCI_TYPECODE_OBJECT) {
|
||||
self->elementType = (PyObject*)
|
||||
ObjectType_New(connection, collectionParam);
|
||||
if (!self->elementType)
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// determine the number of attributes
|
||||
status = OCIAttrGet(topLevelParam, OCI_DTYPE_PARAM,
|
||||
(dvoid*) &numAttributes, 0, OCI_ATTR_NUM_TYPE_ATTRS,
|
||||
self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get number of attributes") < 0)
|
||||
return -1;
|
||||
|
||||
// allocate the attribute list and dictionary
|
||||
self->attributes = PyList_New(numAttributes);
|
||||
if (!self->attributes)
|
||||
return -1;
|
||||
self->attributesByName = PyDict_New();
|
||||
if (!self->attributesByName)
|
||||
return -1;
|
||||
|
||||
// acquire the list parameter descriptor
|
||||
status = OCIAttrGet(topLevelParam, OCI_DTYPE_PARAM,
|
||||
(dvoid*) &attributeListParam, 0, OCI_ATTR_LIST_TYPE_ATTRS,
|
||||
self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get list parameter descriptor") < 0)
|
||||
return -1;
|
||||
|
||||
// create attribute information for each attribute
|
||||
for (i = 0; i < numAttributes; i++) {
|
||||
status = OCIParamGet(attributeListParam, OCI_DTYPE_PARAM,
|
||||
self->environment->errorHandle, (dvoid**) &attributeParam,
|
||||
(ub4) i + 1);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Describe(): get attribute param descriptor") < 0)
|
||||
return -1;
|
||||
attribute = ObjectAttribute_New(connection, attributeParam);
|
||||
if (!attribute)
|
||||
return -1;
|
||||
PyList_SET_ITEM(self->attributes, i, (PyObject*) attribute);
|
||||
if (PyDict_SetItem(self->attributesByName, attribute->name,
|
||||
(PyObject*) attribute) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectType_Initialize()
|
||||
// Initialize the object type with the information that is required.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectType_Initialize(
|
||||
udt_ObjectType *self, // type to initialize
|
||||
udt_Connection *connection, // connection for type information
|
||||
OCIParam *param) // parameter descriptor
|
||||
{
|
||||
OCIDescribe *describeHandle;
|
||||
OCIRef *tdoReference;
|
||||
sword status;
|
||||
char *name;
|
||||
ub4 size;
|
||||
|
||||
// determine the schema of the type
|
||||
status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &name, &size,
|
||||
OCI_ATTR_SCHEMA_NAME, self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Initialize(): get schema name") < 0)
|
||||
return -1;
|
||||
self->schema = PyString_FromStringAndSize(name, size);
|
||||
if (!self->schema)
|
||||
return -1;
|
||||
|
||||
// determine the name of the type
|
||||
status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &name, &size,
|
||||
OCI_ATTR_TYPE_NAME, self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Initialize(): get name") < 0)
|
||||
return -1;
|
||||
self->name = PyString_FromStringAndSize(name, size);
|
||||
if (!self->name)
|
||||
return -1;
|
||||
|
||||
// retrieve TDO of the parameter
|
||||
status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &tdoReference, 0,
|
||||
OCI_ATTR_REF_TDO, self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Initialize(): get TDO reference") < 0)
|
||||
return -1;
|
||||
status = OCIObjectPin(self->environment->handle,
|
||||
self->environment->errorHandle, tdoReference, NULL, OCI_PIN_ANY,
|
||||
OCI_DURATION_SESSION, OCI_LOCK_NONE, (dvoid**) &self->tdo);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Initialize(): pin TDO reference") < 0)
|
||||
return -1;
|
||||
|
||||
// acquire a describe handle
|
||||
status = OCIHandleAlloc(self->environment->handle,
|
||||
(dvoid**) &describeHandle, OCI_HTYPE_DESCRIBE, 0, 0);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Initialize(): allocate describe handle") < 0)
|
||||
return -1;
|
||||
|
||||
// describe the type
|
||||
if (ObjectType_Describe(self, connection, describeHandle) < 0)
|
||||
return -1;
|
||||
|
||||
// free the describe handle
|
||||
status = OCIHandleFree(describeHandle, OCI_HTYPE_DESCRIBE);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"ObjectType_Initialize(): free describe handle") < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectType_New()
|
||||
// Allocate a new object type.
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_ObjectType *ObjectType_New(
|
||||
udt_Connection *connection, // connection for type information
|
||||
OCIParam *param) // parameter descriptor
|
||||
{
|
||||
udt_ObjectType *self;
|
||||
|
||||
self = PyObject_NEW(udt_ObjectType, &g_ObjectTypeType);
|
||||
if (!self)
|
||||
return NULL;
|
||||
Py_INCREF(connection->environment);
|
||||
self->environment = connection->environment;
|
||||
self->tdo = NULL;
|
||||
self->schema = NULL;
|
||||
self->name = NULL;
|
||||
self->attributes = NULL;
|
||||
self->attributesByName = NULL;
|
||||
self->elementType = NULL;
|
||||
self->isCollection = 0;
|
||||
if (ObjectType_Initialize(self, connection, param) < 0) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectType_Free()
|
||||
// Free the memory associated with an object type.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ObjectType_Free(
|
||||
udt_ObjectType *self) // object type to free
|
||||
{
|
||||
Py_DECREF(self->environment);
|
||||
Py_XDECREF(self->schema);
|
||||
Py_XDECREF(self->name);
|
||||
Py_XDECREF(self->attributes);
|
||||
Py_XDECREF(self->attributesByName);
|
||||
Py_XDECREF(self->elementType);
|
||||
if (self->tdo)
|
||||
OCIObjectUnpin(self->environment->handle,
|
||||
self->environment->errorHandle, self->tdo);
|
||||
PyObject_DEL(self);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectType_Repr()
|
||||
// Return a string representation of the object type.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ObjectType_Repr(
|
||||
udt_ObjectType *self) // object type to return the string for
|
||||
{
|
||||
PyObject *module, *name, *result;
|
||||
|
||||
if (GetModuleAndName(self->ob_type, &module, &name) < 0)
|
||||
return NULL;
|
||||
result = PyString_FromFormat("<%s.%s %s.%s>",
|
||||
PyString_AS_STRING(module), PyString_AS_STRING(name),
|
||||
PyString_AS_STRING(self->schema), PyString_AS_STRING(self->name));
|
||||
Py_DECREF(module);
|
||||
Py_DECREF(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectAttribute_Initialize()
|
||||
// Initialize the new object attribute.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectAttribute_Initialize(
|
||||
udt_ObjectAttribute *self, // object attribute to initialize
|
||||
udt_Connection *connection, // connection in use
|
||||
OCIParam *param) // parameter descriptor
|
||||
{
|
||||
sword status;
|
||||
char *name;
|
||||
ub4 size;
|
||||
|
||||
// determine the name of the attribute
|
||||
status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid*) &name, &size,
|
||||
OCI_ATTR_NAME, connection->environment->errorHandle);
|
||||
if (Environment_CheckForError(connection->environment, status,
|
||||
"ObjectAttribute_Initialize(): get name") < 0)
|
||||
return -1;
|
||||
self->name = PyString_FromStringAndSize(name, size);
|
||||
if (!self->name)
|
||||
return -1;
|
||||
|
||||
// determine the type of the attribute
|
||||
status = OCIAttrGet(param, OCI_DTYPE_PARAM, (dvoid*) &self->typeCode, 0,
|
||||
OCI_ATTR_TYPECODE, connection->environment->errorHandle);
|
||||
if (Environment_CheckForError(connection->environment, status,
|
||||
"ObjectAttribute_Initialize(): get type code") < 0)
|
||||
return -1;
|
||||
|
||||
// if the type of the attribute is object, recurse
|
||||
switch (self->typeCode) {
|
||||
case OCI_TYPECODE_NAMEDCOLLECTION:
|
||||
case OCI_TYPECODE_OBJECT:
|
||||
self->subType = ObjectType_New(connection, param);
|
||||
if (!self->subType)
|
||||
return -1;
|
||||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectAttribute_New()
|
||||
// Allocate a new object attribute.
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_ObjectAttribute *ObjectAttribute_New(
|
||||
udt_Connection *connection, // connection information
|
||||
OCIParam *param) // parameter descriptor
|
||||
{
|
||||
udt_ObjectAttribute *self;
|
||||
|
||||
self = PyObject_NEW(udt_ObjectAttribute, &g_ObjectAttributeType);
|
||||
if (!self)
|
||||
return NULL;
|
||||
self->name = NULL;
|
||||
self->subType = NULL;
|
||||
if (ObjectAttribute_Initialize(self, connection, param) < 0) {
|
||||
Py_DECREF(self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectAttribute_Free()
|
||||
// Free the memory associated with an object attribute.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ObjectAttribute_Free(
|
||||
udt_ObjectAttribute *self) // object attribute to free
|
||||
{
|
||||
Py_XDECREF(self->name);
|
||||
Py_XDECREF(self->subType);
|
||||
PyObject_DEL(self);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectAttribute_Repr()
|
||||
// Return a string representation of the object attribute.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ObjectAttribute_Repr(
|
||||
udt_ObjectAttribute *self) // attribute to return the string for
|
||||
{
|
||||
PyObject *module, *name, *result;
|
||||
|
||||
if (GetModuleAndName(self->ob_type, &module, &name) < 0)
|
||||
return NULL;
|
||||
result = PyString_FromFormat("<%s.%s %s>",
|
||||
PyString_AS_STRING(module), PyString_AS_STRING(name),
|
||||
PyString_AS_STRING(self->name));
|
||||
Py_DECREF(module);
|
||||
Py_DECREF(name);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar.c
|
||||
// Defines the routines for handling Oracle object variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "ObjectType.c"
|
||||
#include "ExternalObjectVar.c"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Object type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
dvoid **data;
|
||||
dvoid **objectIndicator;
|
||||
udt_Connection *connection;
|
||||
udt_ObjectType *objectType;
|
||||
} udt_ObjectVar;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of object variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectVar_Initialize(udt_ObjectVar*, udt_Cursor*);
|
||||
static void ObjectVar_Finalize(udt_ObjectVar*);
|
||||
static PyObject *ObjectVar_GetAttr(udt_ObjectVar*, PyObject*);
|
||||
static PyObject *ObjectVar_GetValue(udt_ObjectVar*, unsigned);
|
||||
static int ObjectVar_PreDefine(udt_ObjectVar*, OCIParam*);
|
||||
static int ObjectVar_PostDefine(udt_ObjectVar*);
|
||||
static int ObjectVar_IsNull(udt_ObjectVar*, unsigned);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_ObjectVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.OBJECTVAR", // tp_name
|
||||
sizeof(udt_ObjectVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) ObjectVar_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_Object = {
|
||||
(InitializeProc) ObjectVar_Initialize,
|
||||
(FinalizeProc) ObjectVar_Finalize,
|
||||
(PreDefineProc) ObjectVar_PreDefine,
|
||||
(PostDefineProc) ObjectVar_PostDefine,
|
||||
(IsNullProc) ObjectVar_IsNull,
|
||||
(SetValueProc) NULL,
|
||||
(GetValueProc) ObjectVar_GetValue,
|
||||
&g_ObjectVarType, // Python type
|
||||
SQLT_NTY, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(dvoid*), // element length
|
||||
0, // is variable length
|
||||
0, // can be copied
|
||||
0 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar_Initialize()
|
||||
// Initialize the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectVar_Initialize(
|
||||
udt_ObjectVar *self, // variable to initialize
|
||||
udt_Cursor *cursor) // cursor to use
|
||||
{
|
||||
int i;
|
||||
|
||||
Py_INCREF(cursor->connection);
|
||||
self->connection = cursor->connection;
|
||||
self->objectType = NULL;
|
||||
self->objectIndicator =
|
||||
PyMem_Malloc(self->allocatedElements * sizeof(dvoid*));
|
||||
if (!self->objectIndicator) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < self->allocatedElements; i++) {
|
||||
self->data[i] = NULL;
|
||||
self->objectIndicator[i] = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar_Finalize()
|
||||
// Prepare for variable destruction.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void ObjectVar_Finalize(
|
||||
udt_ObjectVar *self) // variable to free
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < self->allocatedElements; i++) {
|
||||
if (self->data[i])
|
||||
OCIObjectFree(self->environment->handle,
|
||||
self->environment->errorHandle, self->data[i],
|
||||
OCI_OBJECTFREE_FORCE);
|
||||
}
|
||||
Py_DECREF(self->connection);
|
||||
Py_XDECREF(self->objectType);
|
||||
if (self->objectIndicator)
|
||||
PyMem_Free(self->objectIndicator);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar_GetAttr()
|
||||
// Retrieve an attribute on the variable object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ObjectVar_GetAttr(
|
||||
udt_ObjectVar *self, // variable object
|
||||
PyObject *nameObject) // name of attribute
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = PyString_AS_STRING(nameObject);
|
||||
if (name[0] == 't' && strcmp(name, "type") == 0) {
|
||||
Py_INCREF(self->objectType);
|
||||
return (PyObject*) self->objectType;
|
||||
}
|
||||
return Variable_GetAttr((udt_Variable*) self, nameObject);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar_PreDefine()
|
||||
// Performs additional steps required for defining objects.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectVar_PreDefine(
|
||||
udt_ObjectVar *self, // variable to set up
|
||||
OCIParam *param) // parameter being defined
|
||||
{
|
||||
self->objectType = ObjectType_New(self->connection, param);
|
||||
if (!self->objectType)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar_PostDefine()
|
||||
// Performs additional steps required for defining objects.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectVar_PostDefine(
|
||||
udt_ObjectVar *self) // variable to set up
|
||||
{
|
||||
sword status;
|
||||
|
||||
status = OCIDefineObject(self->defineHandle,
|
||||
self->environment->errorHandle, self->objectType->tdo, self->data,
|
||||
0, self->objectIndicator, 0);
|
||||
return Environment_CheckForError(self->environment, status,
|
||||
"ObjectVar_PostDefine(): define object");
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar_IsNull()
|
||||
// Returns a boolean indicating if the variable is null or not.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int ObjectVar_IsNull(
|
||||
udt_ObjectVar *self, // variable to set up
|
||||
unsigned pos) // position to check
|
||||
{
|
||||
if (!self->objectIndicator[pos])
|
||||
return 1;
|
||||
return (*((OCIInd*) self->objectIndicator[pos]) == OCI_IND_NULL);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjectVar_GetValue()
|
||||
// Returns the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *ObjectVar_GetValue(
|
||||
udt_ObjectVar *self, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
PyObject *var;
|
||||
|
||||
// only allowed to get the value once (for now)
|
||||
if (!self->data[pos]) {
|
||||
PyErr_SetString(g_ProgrammingErrorException,
|
||||
"variable value can only be acquired once");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// for collections, return the list rather than the object
|
||||
if (self->objectType->isCollection)
|
||||
return ExternalObjectVar_ConvertCollection(self->environment,
|
||||
self->data[pos], (PyObject*) self, self->objectType);
|
||||
|
||||
// for objects, return a representation of the object
|
||||
var = ExternalObjectVar_New((PyObject*) self, self->objectType,
|
||||
self->data[pos], self->objectIndicator[pos], 1);
|
||||
if (!var)
|
||||
return NULL;
|
||||
self->data[pos] = NULL;
|
||||
self->objectIndicator[pos] = NULL;
|
||||
return var;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Metadata-Version: 1.0
|
||||
Name: cx_Oracle
|
||||
Version: 4.3.1
|
||||
Summary: Python interface to Oracle
|
||||
Home-page: http://starship.python.net/crew/atuining
|
||||
Author: Anthony Tuininga
|
||||
Author-email: anthony.tuininga@gmail.com
|
||||
License: See LICENSE.txt
|
||||
Description: Python interface to Oracle conforming to the Python DB API 2.0 specification.
|
||||
See http://www.python.org/topics/database/DatabaseAPI-2.0.html.
|
||||
Platform: UNKNOWN
|
|
@ -0,0 +1,57 @@
|
|||
Open Source Python/Oracle Utility - cx_Oracle
|
||||
|
||||
cx_Oracle is a Python extension module that allows access to Oracle and
|
||||
conforms to the Python database API 2.0 specifications with a few exceptions.
|
||||
|
||||
See http://www.python.org/topics/database/DatabaseAPI-2.0.html for more
|
||||
information on the Python database API specification.
|
||||
|
||||
For comments, contact Anthony Tuininga at anthony.tuininga@gmail.com or use the
|
||||
mailing list at http://lists.sourceforge.net/lists/listinfo/cx-oracle-users
|
||||
|
||||
|
||||
BINARY INSTALL:
|
||||
Place the file cx_Oracle.pyd or cx_Oracle.so anywhere on your Python path.
|
||||
|
||||
|
||||
SOURCE INSTALL:
|
||||
This module has been built with Oracle 8.1.7, 9.2.0 and 10.1.0 on Linux,
|
||||
Solaris, HP/UX, Tru64 Unix and Windows. It will likely build on other
|
||||
platforms and other Oracle versions but I haven't tried them. Use the provided
|
||||
setup.py to build and install the module which makes use of the distutils
|
||||
module. Note that on Windows, I have used mingw32 (http://www.mingw.org) and
|
||||
the module will not build with MSVC without modification. The commands
|
||||
required to build and install the module are as follows:
|
||||
|
||||
python setup.py build
|
||||
python setup.py install
|
||||
|
||||
|
||||
USAGE EXAMPLE:
|
||||
|
||||
import cx_Oracle
|
||||
|
||||
# connect via SQL*Net string or by each segment in a separate argument
|
||||
#connection = cx_Oracle.connect("user/password@TNS")
|
||||
connection = cx_Oracle.connect("user", "password", "TNS")
|
||||
|
||||
cursor = connection.cursor()
|
||||
cursor.arraysize = 50
|
||||
cursor.execute("""
|
||||
select Col1, Col2, Col3
|
||||
from SomeTable
|
||||
where Col4 = :arg_1
|
||||
and Col5 between :arg_2 and :arg_3""",
|
||||
arg_1 = "VALUE",
|
||||
arg_2 = 5,
|
||||
arg_3 = 15)
|
||||
for column_1, column_2, column_3 in cursor.fetchall():
|
||||
print "Values:", column_1, column_2, column_3
|
||||
|
||||
|
||||
EXCEPTIONS:
|
||||
The only exception to the DB API specification is the lack of a nextset()
|
||||
method which is not supported by Oracle.
|
||||
|
||||
Please see the included documentation for additional information.
|
||||
|
|
@ -0,0 +1,483 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// SessionPool.c
|
||||
// Handles session pooling (only available in Oracle 9i and up).
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// structure for the Python type "SessionPool"
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
OCISPool *handle;
|
||||
ub4 minSessions;
|
||||
ub4 maxSessions;
|
||||
ub4 sessionIncrement;
|
||||
ub4 cacheSize;
|
||||
PyObject *name;
|
||||
PyObject *username;
|
||||
PyObject *password;
|
||||
PyObject *dsn;
|
||||
udt_Environment *environment;
|
||||
PyTypeObject *connectionType;
|
||||
} udt_SessionPool;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// constants for the OCI attributes
|
||||
//-----------------------------------------------------------------------------
|
||||
static ub4 gc_OpenAttribute = OCI_ATTR_SPOOL_OPEN_COUNT;
|
||||
static ub4 gc_BusyAttribute = OCI_ATTR_SPOOL_BUSY_COUNT;
|
||||
static ub4 gc_TimeoutAttribute = OCI_ATTR_SPOOL_TIMEOUT;
|
||||
static ub4 gc_GetModeAttribute = OCI_ATTR_SPOOL_GETMODE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// functions for the Python type "SessionPool"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *SessionPool_New(PyTypeObject*, PyObject*, PyObject*);
|
||||
static int SessionPool_Init(udt_SessionPool*, PyObject*, PyObject*);
|
||||
static void SessionPool_Free(udt_SessionPool*);
|
||||
static PyObject *SessionPool_Acquire(udt_SessionPool*, PyObject*);
|
||||
static PyObject *SessionPool_Drop(udt_SessionPool*, PyObject*);
|
||||
static PyObject *SessionPool_Release(udt_SessionPool*, PyObject*);
|
||||
static PyObject *SessionPool_GetOCIAttr(udt_SessionPool*, ub4*);
|
||||
static int SessionPool_SetOCIAttr(udt_SessionPool*, PyObject*, ub4*);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of methods for Python type "SessionPool"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMethodDef g_SessionPoolMethods[] = {
|
||||
{ "acquire", (PyCFunction) SessionPool_Acquire, METH_NOARGS },
|
||||
{ "drop", (PyCFunction) SessionPool_Drop, METH_VARARGS },
|
||||
{ "release", (PyCFunction) SessionPool_Release, METH_VARARGS },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of members for Python type "SessionPool"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMemberDef g_SessionPoolMembers[] = {
|
||||
{ "username", T_OBJECT, offsetof(udt_SessionPool, username), READONLY },
|
||||
{ "password", T_OBJECT, offsetof(udt_SessionPool, password), READONLY },
|
||||
{ "dsn", T_OBJECT, offsetof(udt_SessionPool, dsn), READONLY },
|
||||
{ "tnsentry", T_OBJECT, offsetof(udt_SessionPool, dsn), READONLY },
|
||||
{ "name", T_OBJECT, offsetof(udt_SessionPool, name), READONLY },
|
||||
{ "max", T_INT, offsetof(udt_SessionPool, maxSessions), READONLY },
|
||||
{ "min", T_INT, offsetof(udt_SessionPool, minSessions), READONLY },
|
||||
{ "increment", T_INT, offsetof(udt_SessionPool, sessionIncrement),
|
||||
READONLY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of calculated members for Python type "SessionPool"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyGetSetDef g_SessionPoolCalcMembers[] = {
|
||||
{ "opened", (getter) SessionPool_GetOCIAttr, 0, 0, &gc_OpenAttribute },
|
||||
{ "busy", (getter) SessionPool_GetOCIAttr, 0, 0, &gc_BusyAttribute },
|
||||
{ "timeout", (getter) SessionPool_GetOCIAttr,
|
||||
(setter) SessionPool_SetOCIAttr, 0, &gc_TimeoutAttribute },
|
||||
{ "getmode", (getter) SessionPool_GetOCIAttr,
|
||||
(setter) SessionPool_SetOCIAttr, 0, &gc_GetModeAttribute },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// declaration of Python type "SessionPool"
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_SessionPoolType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"OracleSessionPool", // tp_name
|
||||
sizeof(udt_SessionPool), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) SessionPool_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
|
||||
g_SessionPoolMethods, // tp_methods
|
||||
g_SessionPoolMembers, // tp_members
|
||||
g_SessionPoolCalcMembers, // tp_getset
|
||||
0, // tp_base
|
||||
0, // tp_dict
|
||||
0, // tp_descr_get
|
||||
0, // tp_descr_set
|
||||
0, // tp_dictoffset
|
||||
(initproc) SessionPool_Init, // tp_init
|
||||
0, // tp_alloc
|
||||
(newfunc) SessionPool_New, // tp_new
|
||||
0, // tp_free
|
||||
0, // tp_is_gc
|
||||
0 // tp_bases
|
||||
};
|
||||
|
||||
|
||||
#include "Connection.c"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_New()
|
||||
// Create a new session pool object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *SessionPool_New(
|
||||
PyTypeObject *type, // type object
|
||||
PyObject *args, // arguments
|
||||
PyObject *keywordArgs) // keyword arguments
|
||||
{
|
||||
udt_SessionPool *newObject;
|
||||
|
||||
// create the object
|
||||
newObject = (udt_SessionPool*) type->tp_alloc(type, 0);
|
||||
if (!newObject)
|
||||
return NULL;
|
||||
newObject->environment = NULL;
|
||||
|
||||
return (PyObject*) newObject;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_Init()
|
||||
// Initialize the session pool object.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int SessionPool_Init(
|
||||
udt_SessionPool *self, // session pool object
|
||||
PyObject *args, // arguments
|
||||
PyObject *keywordArgs) // keyword arguments
|
||||
{
|
||||
unsigned usernameLength, passwordLength, dsnLength, poolNameLength;
|
||||
const char *username, *password, *dsn, *poolName;
|
||||
unsigned minSessions, maxSessions, sessionIncrement;
|
||||
PyTypeObject *connectionType;
|
||||
PyObject *threadedObj;
|
||||
int threaded;
|
||||
sword status;
|
||||
ub1 getMode;
|
||||
|
||||
// define keyword arguments
|
||||
static char *keywordList[] = { "user", "password", "dsn", "min", "max",
|
||||
"increment", "connectiontype", "threaded", "getmode", NULL };
|
||||
|
||||
// parse arguments and keywords
|
||||
threaded = 0;
|
||||
threadedObj = NULL;
|
||||
connectionType = &g_ConnectionType;
|
||||
getMode = OCI_SPOOL_ATTRVAL_NOWAIT;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywordArgs, "s#s#s#iii|OOb",
|
||||
keywordList, &username, &usernameLength, &password,
|
||||
&passwordLength, &dsn, &dsnLength, &minSessions,
|
||||
&maxSessions, &sessionIncrement, &connectionType, &threadedObj,
|
||||
&getMode))
|
||||
return -1;
|
||||
if (!PyType_Check(connectionType)) {
|
||||
PyErr_SetString(g_ProgrammingErrorException,
|
||||
"connectiontype must be a type");
|
||||
return -1;
|
||||
}
|
||||
if (!PyType_IsSubtype(connectionType, &g_ConnectionType)) {
|
||||
PyErr_SetString(g_ProgrammingErrorException,
|
||||
"connectiontype must be a subclass of Connection");
|
||||
return -1;
|
||||
}
|
||||
if (threadedObj) {
|
||||
threaded = PyObject_IsTrue(threadedObj);
|
||||
if (threaded < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// initialize the object's members
|
||||
Py_INCREF(connectionType);
|
||||
self->connectionType = connectionType;
|
||||
self->minSessions = minSessions;
|
||||
self->maxSessions = maxSessions;
|
||||
self->sessionIncrement = sessionIncrement;
|
||||
|
||||
// set up the environment
|
||||
self->environment = Environment_New(threaded);
|
||||
if (!self->environment)
|
||||
return -1;
|
||||
|
||||
// create the string for the username
|
||||
self->username = PyString_FromStringAndSize(username, usernameLength);
|
||||
if (!self->username)
|
||||
return -1;
|
||||
|
||||
// create the string for the password
|
||||
self->password = PyString_FromStringAndSize(password, passwordLength);
|
||||
if (!self->password)
|
||||
return -1;
|
||||
|
||||
// create the string for the TNS entry
|
||||
self->dsn = PyString_FromStringAndSize(dsn, dsnLength);
|
||||
if (!self->dsn)
|
||||
return -1;
|
||||
|
||||
// create the session pool handle
|
||||
status = OCIHandleAlloc(self->environment->handle, (dvoid**) &self->handle,
|
||||
OCI_HTYPE_SPOOL, 0, 0);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"SessionPool_New(): allocate handle") < 0)
|
||||
return -1;
|
||||
|
||||
// create the session pool
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = OCISessionPoolCreate(self->environment->handle,
|
||||
self->environment->errorHandle, self->handle,
|
||||
(OraText**) &poolName, &poolNameLength, (OraText*) dsn, dsnLength,
|
||||
minSessions, maxSessions, sessionIncrement, (OraText*) username,
|
||||
usernameLength, (OraText*) password, passwordLength,
|
||||
OCI_SPC_HOMOGENEOUS | OCI_SPC_STMTCACHE);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"SessionPool_New(): create pool") < 0)
|
||||
return -1;
|
||||
|
||||
// create the string for the pool name
|
||||
self->name = PyString_FromStringAndSize(poolName, poolNameLength);
|
||||
if (!self->name)
|
||||
return -1;
|
||||
|
||||
// set the mode on the pool
|
||||
status = OCIAttrSet(self->handle, OCI_HTYPE_SPOOL, (dvoid*) &getMode, 0,
|
||||
OCI_ATTR_SPOOL_GETMODE, self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"SessionPool_New(): set wait mode") < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_Free()
|
||||
// Deallocate the session pool.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void SessionPool_Free(
|
||||
udt_SessionPool *self) // session pool
|
||||
{
|
||||
if (self->handle) {
|
||||
OCISessionPoolDestroy(self->handle, self->environment->errorHandle,
|
||||
OCI_SPD_FORCE);
|
||||
OCIHandleFree(self->handle, OCI_HTYPE_SPOOL);
|
||||
}
|
||||
Py_XDECREF(self->name);
|
||||
Py_XDECREF(self->environment);
|
||||
Py_XDECREF(self->username);
|
||||
Py_XDECREF(self->password);
|
||||
Py_XDECREF(self->dsn);
|
||||
self->ob_type->tp_free((PyObject*) self);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_IsConnected()
|
||||
// Determines if the session pool object is connected to the database. If
|
||||
// not, a Python exception is raised.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int SessionPool_IsConnected(
|
||||
udt_SessionPool *self) // session pool
|
||||
{
|
||||
if (!self->handle) {
|
||||
PyErr_SetString(g_InterfaceErrorException, "not connected");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_Acquire()
|
||||
// Create a new connection within the session pool.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *SessionPool_Acquire(
|
||||
udt_SessionPool *self, // session pool
|
||||
PyObject *args) // arguments
|
||||
{
|
||||
PyObject *createArgs, *createKeywordArgs, *result;
|
||||
|
||||
// make sure session pool is connected
|
||||
if (SessionPool_IsConnected(self) < 0)
|
||||
return NULL;
|
||||
|
||||
// create arguments
|
||||
createArgs = PyTuple_New(0);
|
||||
if (!createArgs)
|
||||
return NULL;
|
||||
createKeywordArgs = PyDict_New();
|
||||
if (!createKeywordArgs) {
|
||||
Py_DECREF(createArgs);
|
||||
return NULL;
|
||||
}
|
||||
if (PyDict_SetItemString(createKeywordArgs, "pool",
|
||||
(PyObject*) self) < 0) {
|
||||
Py_DECREF(createArgs);
|
||||
Py_DECREF(createKeywordArgs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create the connection object
|
||||
result = PyObject_Call( (PyObject*) self->connectionType, createArgs,
|
||||
createKeywordArgs);
|
||||
Py_DECREF(createArgs);
|
||||
Py_DECREF(createKeywordArgs);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_InternalRelease()
|
||||
// Internal method used to release a connection back to the pool in order to
|
||||
// allow for the possibility of dropping the connection.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *SessionPool_InternalRelease(
|
||||
udt_SessionPool *self, // session pool
|
||||
PyObject *args, // arguments
|
||||
ub4 mode) // OCI mode to use
|
||||
{
|
||||
udt_Connection *connection;
|
||||
sword status;
|
||||
|
||||
// connection is expected
|
||||
if (!PyArg_ParseTuple(args, "O!", &g_ConnectionType, &connection))
|
||||
return NULL;
|
||||
|
||||
// make sure session pool is connected
|
||||
if (SessionPool_IsConnected(self) < 0)
|
||||
return NULL;
|
||||
if (connection->sessionPool != self) {
|
||||
PyErr_SetString(g_ProgrammingErrorException,
|
||||
"connection not acquired with this session pool");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// release the connection
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = OCITransRollback(connection->handle,
|
||||
connection->environment->errorHandle, OCI_DEFAULT);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (Environment_CheckForError(connection->environment, status,
|
||||
"SessionPool_Release(): rollback") < 0)
|
||||
return NULL;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
status = OCISessionRelease(connection->handle,
|
||||
connection->environment->errorHandle, NULL, 0, mode);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (Environment_CheckForError(connection->environment, status,
|
||||
"SessionPool_Release(): release session") < 0)
|
||||
return NULL;
|
||||
|
||||
// ensure that the connection behaves as closed
|
||||
Py_DECREF(connection->sessionPool);
|
||||
connection->sessionPool = NULL;
|
||||
connection->handle = NULL;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_Drop()
|
||||
// Release a connection back to the session pool, dropping it so that a new
|
||||
// connection will be created if needed.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *SessionPool_Drop(
|
||||
udt_SessionPool *self, // session pool
|
||||
PyObject *args) // arguments
|
||||
{
|
||||
return SessionPool_InternalRelease(self, args, OCI_SESSRLS_DROPSESS);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_Release()
|
||||
// Release a connection back to the session pool.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *SessionPool_Release(
|
||||
udt_SessionPool *self, // session pool
|
||||
PyObject *args) // arguments
|
||||
{
|
||||
return SessionPool_InternalRelease(self, args, OCI_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_GetOCIAttr()
|
||||
// Return the value for the OCI attribute.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *SessionPool_GetOCIAttr(
|
||||
udt_SessionPool *self, // session pool
|
||||
ub4 *attribute) // OCI attribute type
|
||||
{
|
||||
sword status;
|
||||
ub4 value;
|
||||
|
||||
// make sure session pool is connected
|
||||
if (SessionPool_IsConnected(self) < 0)
|
||||
return NULL;
|
||||
|
||||
// get the value from the OCI
|
||||
status = OCIAttrGet(self->handle, OCI_HTYPE_SPOOL, &value, 0, *attribute,
|
||||
self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"SessionPool_GetOCIAttr()") < 0)
|
||||
return NULL;
|
||||
if (*attribute == OCI_ATTR_SPOOL_GETMODE)
|
||||
return PyInt_FromLong((ub1) value);
|
||||
return PyInt_FromLong(value);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SessionPool_SetOCIAttr()
|
||||
// Set the value of the OCI attribute.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int SessionPool_SetOCIAttr(
|
||||
udt_SessionPool *self, // session pool
|
||||
PyObject *value, // value to set
|
||||
ub4 *attribute) // OCI attribute type
|
||||
{
|
||||
ub4 ociValue;
|
||||
sword status;
|
||||
|
||||
// make sure session pool is connected
|
||||
if (SessionPool_IsConnected(self) < 0)
|
||||
return -1;
|
||||
|
||||
// set the value in the OCI
|
||||
if (!PyInt_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an integer");
|
||||
return -1;
|
||||
}
|
||||
ociValue = PyInt_AS_LONG(value);
|
||||
status = OCIAttrSet(self->handle, OCI_HTYPE_SPOOL, &ociValue, 0,
|
||||
*attribute, self->environment->errorHandle);
|
||||
if (Environment_CheckForError(self->environment, status,
|
||||
"SessionPool_SetOCIAttr()") < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// StringVar.c
|
||||
// Defines the routines specific to the string type.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// String type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
char *data;
|
||||
ub1 charsetForm;
|
||||
ub2 charsetId;
|
||||
} udt_StringVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of string variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int StringVar_Initialize(udt_StringVar*, udt_Cursor*);
|
||||
static int StringVar_PreDefine(udt_StringVar*, OCIParam*);
|
||||
static int StringVar_SetValue(udt_StringVar*, unsigned, PyObject*);
|
||||
static PyObject *StringVar_GetValue(udt_StringVar*, unsigned);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_StringVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.STRING", // tp_name
|
||||
sizeof(udt_StringVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_FixedCharVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.FIXED_CHAR", // tp_name
|
||||
sizeof(udt_StringVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_RowidVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.ROWID", // tp_name
|
||||
sizeof(udt_StringVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
static PyTypeObject g_BinaryVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.BINARY", // tp_name
|
||||
sizeof(udt_StringVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_String = {
|
||||
(InitializeProc) StringVar_Initialize,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) StringVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) StringVar_SetValue,
|
||||
(GetValueProc) StringVar_GetValue,
|
||||
&g_StringVarType, // Python type
|
||||
SQLT_CHR, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
MAX_STRING_CHARS, // element length (default)
|
||||
1, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_NationalCharString = {
|
||||
(InitializeProc) StringVar_Initialize,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) StringVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) StringVar_SetValue,
|
||||
(GetValueProc) StringVar_GetValue,
|
||||
&g_StringVarType, // Python type
|
||||
SQLT_CHR, // Oracle type
|
||||
SQLCS_NCHAR, // charset form
|
||||
MAX_STRING_CHARS, // element length (default)
|
||||
1, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_FixedChar = {
|
||||
(InitializeProc) StringVar_Initialize,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) StringVar_PreDefine,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) StringVar_SetValue,
|
||||
(GetValueProc) StringVar_GetValue,
|
||||
&g_FixedCharVarType, // Python type
|
||||
SQLT_AFC, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
2000, // element length (default)
|
||||
1, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_Rowid = {
|
||||
(InitializeProc) StringVar_Initialize,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) StringVar_SetValue,
|
||||
(GetValueProc) StringVar_GetValue,
|
||||
&g_RowidVarType, // Python type
|
||||
SQLT_CHR, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
18, // element length (default)
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
static udt_VariableType vt_Binary = {
|
||||
(InitializeProc) StringVar_Initialize,
|
||||
(FinalizeProc) NULL,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) StringVar_SetValue,
|
||||
(GetValueProc) StringVar_GetValue,
|
||||
&g_BinaryVarType, // Python type
|
||||
SQLT_BIN, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
MAX_STRING_CHARS, // element length (default)
|
||||
1, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StringVar_Initialize()
|
||||
// Initialize the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int StringVar_Initialize(
|
||||
udt_StringVar *var, // variable to initialize
|
||||
udt_Cursor *cursor) // cursor to use
|
||||
{
|
||||
var->actualLength = (ub2*) PyMem_Malloc(var->allocatedElements *
|
||||
sizeof(ub2));
|
||||
if (!var->actualLength) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StringVar_PreDefine()
|
||||
// Set the character set information when values are fetched from this
|
||||
// variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int StringVar_PreDefine(
|
||||
udt_StringVar *var, // variable to initialize
|
||||
OCIParam *param) // parameter handle
|
||||
{
|
||||
sword status;
|
||||
|
||||
status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &var->charsetForm,
|
||||
0, OCI_ATTR_CHARSET_FORM, var->environment->errorHandle);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"StringVar_PreDefine(): getting charset form") < 0)
|
||||
return -1;
|
||||
status = OCIAttrGet(param, OCI_HTYPE_DESCRIBE, (dvoid*) &var->charsetId, 0,
|
||||
OCI_ATTR_CHARSET_ID, var->environment->errorHandle);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"StringVar_PreDefine(): getting charset id") < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StringVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int StringVar_SetValue(
|
||||
udt_StringVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
Py_ssize_t bufferSize;
|
||||
const void *buffer;
|
||||
|
||||
// get the buffer data and size for binding
|
||||
if (PyString_Check(value)) {
|
||||
buffer = PyString_AS_STRING(value);
|
||||
bufferSize = PyString_GET_SIZE(value);
|
||||
} else if (PyBuffer_Check(value)) {
|
||||
if (PyObject_AsReadBuffer(value, &buffer, &bufferSize) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting string or buffer data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ensure that the buffer is not too large
|
||||
if (bufferSize > var->maxLength) {
|
||||
if (bufferSize > var->environment->maxStringBytes) {
|
||||
PyErr_SetString(PyExc_ValueError, "string data too large");
|
||||
return -1;
|
||||
}
|
||||
if (Variable_Resize( (udt_Variable*) var, bufferSize) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// keep a copy of the string
|
||||
var->actualLength[pos] = (ub2) bufferSize;
|
||||
if (bufferSize)
|
||||
memcpy(var->data + var->maxLength * pos, buffer, bufferSize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StringVar_GetValue()
|
||||
// Returns the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *StringVar_GetValue(
|
||||
udt_StringVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
return PyString_FromStringAndSize(var->data + pos * var->maxLength,
|
||||
var->actualLength[pos]);
|
||||
}
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// TimestampVar.c
|
||||
// Defines the routines for handling timestamp variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Timestamp type
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
OCIDateTime **data;
|
||||
} udt_TimestampVar;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of date/time variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int TimestampVar_Initialize(udt_TimestampVar*, udt_Cursor*);
|
||||
static void TimestampVar_Finalize(udt_TimestampVar*);
|
||||
static int TimestampVar_SetValue(udt_TimestampVar*, unsigned, PyObject*);
|
||||
static PyObject *TimestampVar_GetValue(udt_TimestampVar*, unsigned);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Python type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyTypeObject g_TimestampVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.TIMESTAMP", // tp_name
|
||||
sizeof(udt_TimestampVar), // tp_basicsize
|
||||
0, // tp_itemsize
|
||||
(destructor) Variable_Free, // tp_dealloc
|
||||
0, // tp_print
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
(reprfunc) Variable_Repr, // tp_repr
|
||||
0, // tp_as_number
|
||||
0, // tp_as_sequence
|
||||
0, // tp_as_mapping
|
||||
0, // tp_hash
|
||||
0, // tp_call
|
||||
0, // tp_str
|
||||
(getattrofunc) Variable_GetAttr, // tp_getattro
|
||||
0, // tp_setattro
|
||||
0, // tp_as_buffer
|
||||
Py_TPFLAGS_DEFAULT, // tp_flags
|
||||
0 // tp_doc
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
static udt_VariableType vt_Timestamp = {
|
||||
(InitializeProc) TimestampVar_Initialize,
|
||||
(FinalizeProc) TimestampVar_Finalize,
|
||||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) TimestampVar_SetValue,
|
||||
(GetValueProc) TimestampVar_GetValue,
|
||||
&g_TimestampVarType, // Python type
|
||||
SQLT_TIMESTAMP, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(OCIDateTime*), // element length (default)
|
||||
0, // is variable length
|
||||
1, // can be copied
|
||||
1 // can be in array
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TimestampVar_Initialize()
|
||||
// Initialize the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int TimestampVar_Initialize(
|
||||
udt_TimestampVar *var, // variable to initialize
|
||||
udt_Cursor *cursor) // cursor variable associated with
|
||||
{
|
||||
sword status;
|
||||
ub4 i;
|
||||
|
||||
// initialize the LOB locators
|
||||
for (i = 0; i < var->allocatedElements; i++) {
|
||||
status = OCIDescriptorAlloc(var->environment->handle,
|
||||
(dvoid**) &var->data[i], OCI_DTYPE_TIMESTAMP, 0, 0);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"TimestampVar_Initialize()") < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TimestampVar_Finalize()
|
||||
// Prepare for variable destruction.
|
||||
//-----------------------------------------------------------------------------
|
||||
static void TimestampVar_Finalize(
|
||||
udt_TimestampVar *var) // variable to free
|
||||
{
|
||||
ub4 i;
|
||||
|
||||
for (i = 0; i < var->allocatedElements; i++) {
|
||||
if (var->data[i])
|
||||
OCIDescriptorFree(var->data[i], OCI_DTYPE_TIMESTAMP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef NATIVE_DATETIME
|
||||
//-----------------------------------------------------------------------------
|
||||
// TimestampVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int TimestampVar_SetValue(
|
||||
udt_TimestampVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
sword status;
|
||||
uword valid;
|
||||
|
||||
// make sure a timestamp is being bound
|
||||
if (!PyDateTime_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting timestamp data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// store a copy of the value
|
||||
status = OCIDateTimeConstruct(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[pos],
|
||||
(sb2) PyDateTime_GET_YEAR(value),
|
||||
PyDateTime_GET_MONTH(value),
|
||||
PyDateTime_GET_DAY(value),
|
||||
PyDateTime_DATE_GET_HOUR(value),
|
||||
PyDateTime_DATE_GET_MINUTE(value),
|
||||
PyDateTime_DATE_GET_SECOND(value),
|
||||
PyDateTime_DATE_GET_MICROSECOND(value) * 1000, NULL, 0);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"TimestampVar_SetValue(): create structure") < 0)
|
||||
return -1;
|
||||
status = OCIDateTimeCheck(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[pos], &valid);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"TimestampVar_SetValue()") < 0)
|
||||
return -1;
|
||||
if (valid != 0) {
|
||||
PyErr_SetString(g_DataErrorException, "invalid date");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TimestampVar_SetValue()
|
||||
// Set the value of the variable.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int TimestampVar_SetValue(
|
||||
udt_TimestampVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
udt_ExternalDateTimeVar *dateValue;
|
||||
sword status;
|
||||
uword valid;
|
||||
|
||||
// make sure a date is being bound
|
||||
if (value->ob_type != &g_ExternalDateTimeVarType) {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting date data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// store a copy of the value
|
||||
dateValue = (udt_ExternalDateTimeVar*) value;
|
||||
status = OCIDateTimeConstruct(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[pos],
|
||||
dateValue->year, dateValue->month, dateValue->day, dateValue->hour,
|
||||
dateValue->minute, dateValue->second, dateValue->fsecond * 1000,
|
||||
NULL, 0);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"TimestampVar_SetValue(): create structure") < 0)
|
||||
return -1;
|
||||
status = OCIDateTimeCheck(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[pos], &valid);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"TimestampVar_SetValue()") < 0)
|
||||
return -1;
|
||||
if (valid != 0) {
|
||||
PyErr_SetString(g_DataErrorException, "invalid date");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TimestampVar_GetValue()
|
||||
// Returns the value stored at the given array position.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *TimestampVar_GetValue(
|
||||
udt_TimestampVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
ub1 hour, minute, second, month, day;
|
||||
sword status;
|
||||
ub4 fsecond;
|
||||
sb2 year;
|
||||
|
||||
status = OCIDateTimeGetDate(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[pos], &year, &month,
|
||||
&day);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"TimestampVar_GetValue(): date portion") < 0)
|
||||
return NULL;
|
||||
status = OCIDateTimeGetTime(var->environment->handle,
|
||||
var->environment->errorHandle, var->data[pos], &hour, &minute,
|
||||
&second, &fsecond);
|
||||
if (Environment_CheckForError(var->environment, status,
|
||||
"TimestampVar_GetValue(): time portion") < 0)
|
||||
return NULL;
|
||||
#ifdef NATIVE_DATETIME
|
||||
return PyDateTime_FromDateAndTime(year, month, day, hour, minute, second,
|
||||
fsecond / 1000);
|
||||
#else
|
||||
return ExternalDateTimeVar_NewFromC(&g_ExternalDateTimeVarType, year,
|
||||
month, day, hour, minute, second, fsecond / 1000);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Transforms.c
|
||||
// Provides methods for transforming Oracle data to Python objects or for
|
||||
// setting Oracle data from Python objects.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef NATIVE_DATETIME
|
||||
static udt_VariableType vt_Date;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OracleDateToPythonDate()
|
||||
// Return a Python date object given an Oracle date.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *OracleDateToPythonDate(
|
||||
udt_VariableType *varType, // variable type
|
||||
OCIDate* value) // value to convert
|
||||
{
|
||||
ub1 hour, minute, second, month, day;
|
||||
sb2 year;
|
||||
|
||||
OCIDateGetDate(value, &year, &month, &day);
|
||||
OCIDateGetTime(value, &hour, &minute, &second);
|
||||
|
||||
#ifdef NATIVE_DATETIME
|
||||
if (varType == &vt_Date)
|
||||
return PyDate_FromDate(year, month, day);
|
||||
return PyDateTime_FromDateAndTime(year, month, day, hour, minute, second,
|
||||
0);
|
||||
#else
|
||||
return ExternalDateTimeVar_NewFromC(&g_ExternalDateTimeVarType, year,
|
||||
month, day, hour, minute, second, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OracleNumberToPythonFloat()
|
||||
// Return a Python date object given an Oracle date.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *OracleNumberToPythonFloat(
|
||||
udt_Environment *environment, // environment
|
||||
OCINumber* value) // value to convert
|
||||
{
|
||||
double doubleValue;
|
||||
sword status;
|
||||
|
||||
status = OCINumberToReal(environment->errorHandle,
|
||||
value, sizeof(double), (dvoid*) &doubleValue);
|
||||
if (Environment_CheckForError(environment, status,
|
||||
"OracleNumberToPythonFloat()") < 0)
|
||||
return NULL;
|
||||
return PyFloat_FromDouble(doubleValue);
|
||||
}
|
||||
|
|
@ -0,0 +1,472 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// cx_Oracle.c
|
||||
// Shared library for use by Python.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <Python.h>
|
||||
#include <structmember.h>
|
||||
#include <time.h>
|
||||
#include <oci.h>
|
||||
#include <orid.h>
|
||||
#include <xa.h>
|
||||
|
||||
// define whether or not we are building Oracle 9i
|
||||
#ifdef OCI_ATTR_MODULE
|
||||
#define ORACLE_10G
|
||||
#endif
|
||||
#if OCI_FNCODE_STMTRELEASE
|
||||
#define ORACLE_9I
|
||||
#endif
|
||||
|
||||
// define whether or not we are building with the native datetime module
|
||||
#if (PY_VERSION_HEX >= 0x02040000)
|
||||
#include <datetime.h>
|
||||
#define NATIVE_DATETIME
|
||||
#endif
|
||||
|
||||
// PY_LONG_LONG was called LONG_LONG before Python 2.3
|
||||
#ifndef PY_LONG_LONG
|
||||
#define PY_LONG_LONG LONG_LONG
|
||||
#endif
|
||||
|
||||
// define Py_ssize_t for versions before Python 2.5
|
||||
#if PY_VERSION_HEX < 0x02050000
|
||||
typedef int Py_ssize_t;
|
||||
#define PY_SSIZE_T_MAX INT_MAX
|
||||
#define PY_SSIZE_T_MIN INT_MIN
|
||||
#endif
|
||||
|
||||
// define macro for adding OCI constants
|
||||
#define ADD_OCI_CONSTANT(x) \
|
||||
if (PyModule_AddIntConstant(module, #x, OCI_ ##x) < 0) \
|
||||
return;
|
||||
|
||||
// define macro for adding type objects
|
||||
#define ADD_TYPE_OBJECT(name, type) \
|
||||
Py_INCREF(type); \
|
||||
if (PyModule_AddObject(module, name, (PyObject*) type) < 0) \
|
||||
return;
|
||||
|
||||
// define macro to get the build version as a string
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
#define BUILD_VERSION_STRING xstr(BUILD_VERSION)
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef WITH_THREAD
|
||||
static PyInterpreterState *g_InterpreterState;
|
||||
#endif
|
||||
static PyObject *g_WarningException = NULL;
|
||||
static PyObject *g_ErrorException = NULL;
|
||||
static PyObject *g_InterfaceErrorException = NULL;
|
||||
static PyObject *g_DatabaseErrorException = NULL;
|
||||
static PyObject *g_DataErrorException = NULL;
|
||||
static PyObject *g_OperationalErrorException = NULL;
|
||||
static PyObject *g_IntegrityErrorException = NULL;
|
||||
static PyObject *g_InternalErrorException = NULL;
|
||||
static PyObject *g_ProgrammingErrorException = NULL;
|
||||
static PyObject *g_NotSupportedErrorException = NULL;
|
||||
static PyTypeObject *g_DateTimeType = NULL;
|
||||
static PyTypeObject *g_DecimalType = NULL;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SetException()
|
||||
// Create an exception and set it in the provided dictionary.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int SetException(
|
||||
PyObject *module, // module object
|
||||
PyObject **exception, // exception to create
|
||||
char *name, // name of the exception
|
||||
PyObject *baseException) // exception to base exception on
|
||||
{
|
||||
char buffer[100];
|
||||
|
||||
sprintf(buffer, "cx_Oracle.%s", name);
|
||||
*exception = PyErr_NewException(buffer, baseException, NULL);
|
||||
if (!*exception)
|
||||
return -1;
|
||||
return PyModule_AddObject(module, name, *exception);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GetModuleAndName()
|
||||
// Return the module and name for the type.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int GetModuleAndName(
|
||||
PyTypeObject *type, // type to get module/name for
|
||||
PyObject **module, // name of module
|
||||
PyObject **name) // name of type
|
||||
{
|
||||
*module = PyObject_GetAttrString( (PyObject*) type, "__module__");
|
||||
if (!*module)
|
||||
return -1;
|
||||
*name = PyObject_GetAttrString( (PyObject*) type, "__name__");
|
||||
if (!*name) {
|
||||
Py_DECREF(*module);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include "Environment.c"
|
||||
#ifdef ORACLE_9I
|
||||
#include "SessionPool.c"
|
||||
#else
|
||||
#include "Connection.c"
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MakeDSN()
|
||||
// Make a data source name given the host port and SID.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject* MakeDSN(
|
||||
PyObject* self, // passthrough argument
|
||||
PyObject* args) // arguments to function
|
||||
{
|
||||
char *host, *sid;
|
||||
int port;
|
||||
|
||||
// parse arguments
|
||||
if (!PyArg_ParseTuple(args, "sis", &host, &port, &sid))
|
||||
return NULL;
|
||||
|
||||
// return the formatted string
|
||||
return PyString_FromFormat("(DESCRIPTION=(ADDRESS_LIST=(ADDRESS="
|
||||
"(PROTOCOL=TCP)(HOST=%s)(PORT=%d)))(CONNECT_DATA=(SID=%s)))",
|
||||
host, port, sid);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Time()
|
||||
// Returns a time value suitable for binding.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject* Time(
|
||||
PyObject* self, // passthrough argument
|
||||
PyObject* args) // arguments to function
|
||||
{
|
||||
PyErr_SetString(g_NotSupportedErrorException,
|
||||
"Oracle does not support time only variables");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TimeFromTicks()
|
||||
// Returns a time value suitable for binding.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject* TimeFromTicks(
|
||||
PyObject* self, // passthrough argument
|
||||
PyObject* args) // arguments to function
|
||||
{
|
||||
PyErr_SetString(g_NotSupportedErrorException,
|
||||
"Oracle does not support time only variables");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NATIVE_DATETIME
|
||||
//-----------------------------------------------------------------------------
|
||||
// Date()
|
||||
// Returns a date value suitable for binding.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject* Date(
|
||||
PyObject* self, // passthrough argument
|
||||
PyObject* args) // arguments to function
|
||||
{
|
||||
return ExternalDateTimeVar_New(&g_ExternalDateTimeVarType, args, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// DateFromTicks()
|
||||
// Returns a date value suitable for binding.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject* DateFromTicks(
|
||||
PyObject* self, // passthrough argument
|
||||
PyObject* args) // arguments to function
|
||||
{
|
||||
#ifdef NATIVE_DATETIME
|
||||
return PyDate_FromTimestamp(args);
|
||||
#else
|
||||
struct tm *time;
|
||||
time_t ticks;
|
||||
int ticksArg;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i", &ticksArg))
|
||||
return NULL;
|
||||
|
||||
ticks = ticksArg;
|
||||
time = localtime(&ticks);
|
||||
if (time == NULL)
|
||||
return PyErr_SetFromErrno(g_DataErrorException);
|
||||
return ExternalDateTimeVar_NewFromC(&g_ExternalDateTimeVarType,
|
||||
time->tm_year + 1900, time->tm_mon + 1, time->tm_mday, 0, 0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TimestampFromTicks()
|
||||
// Returns a date value suitable for binding.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject* TimestampFromTicks(
|
||||
PyObject* self, // passthrough argument
|
||||
PyObject* args) // arguments to function
|
||||
{
|
||||
#ifdef NATIVE_DATETIME
|
||||
return PyDateTime_FromTimestamp(args);
|
||||
#else
|
||||
struct tm *time;
|
||||
time_t ticks;
|
||||
int ticksArg;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i", &ticksArg))
|
||||
return NULL;
|
||||
|
||||
ticks = ticksArg;
|
||||
time = localtime(&ticks);
|
||||
if (time == NULL)
|
||||
return PyErr_SetFromErrno(g_DataErrorException);
|
||||
return ExternalDateTimeVar_NewFromC(&g_ExternalDateTimeVarType,
|
||||
time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
|
||||
time->tm_hour, time->tm_min, time->tm_sec, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of methods supported by this module
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyMethodDef g_ModuleMethods[] = {
|
||||
{ "makedsn", MakeDSN, METH_VARARGS },
|
||||
#ifndef NATIVE_DATETIME
|
||||
{ "Date", Date, METH_VARARGS },
|
||||
#endif
|
||||
{ "Time", Time, METH_VARARGS },
|
||||
{ "DateFromTicks", DateFromTicks, METH_VARARGS },
|
||||
{ "TimeFromTicks", TimeFromTicks, METH_VARARGS },
|
||||
{ "TimestampFromTicks", TimestampFromTicks, METH_VARARGS },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initcx_Oracle()
|
||||
// Initialization routine for the shared libary.
|
||||
//-----------------------------------------------------------------------------
|
||||
void initcx_Oracle(void)
|
||||
{
|
||||
PyThreadState *threadState;
|
||||
PyObject *module;
|
||||
|
||||
// initialize the interpreter state for callbacks
|
||||
#ifdef WITH_THREAD
|
||||
PyEval_InitThreads();
|
||||
threadState = PyThreadState_Swap(NULL);
|
||||
if (!threadState)
|
||||
return;
|
||||
g_InterpreterState = threadState->interp;
|
||||
PyThreadState_Swap(threadState);
|
||||
#endif
|
||||
|
||||
// manage the use of the datetime module; in Python 2.4 and up, the native
|
||||
// datetime type is used since a C API is exposed; in all other cases, the
|
||||
// internal datetime type is used and if the datetime module exists,
|
||||
// binding to that type is permitted
|
||||
#ifdef NATIVE_DATETIME
|
||||
PyDateTime_IMPORT;
|
||||
if (PyErr_Occurred())
|
||||
return;
|
||||
#else
|
||||
module = PyImport_ImportModule("datetime");
|
||||
if (module)
|
||||
g_DateTimeType = (PyTypeObject*) PyObject_GetAttrString(module,
|
||||
"datetime");
|
||||
PyErr_Clear();
|
||||
#endif
|
||||
|
||||
// attempt to import the decimal module
|
||||
module = PyImport_ImportModule("decimal");
|
||||
if (module)
|
||||
g_DecimalType = (PyTypeObject*) PyObject_GetAttrString(module,
|
||||
"Decimal");
|
||||
PyErr_Clear();
|
||||
|
||||
// prepare the types for use by the module
|
||||
if (PyType_Ready(&g_ConnectionType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_CursorType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_ErrorType) < 0)
|
||||
return;
|
||||
#ifndef NATIVE_DATETIME
|
||||
if (PyType_Ready(&g_ExternalDateTimeVarType) < 0)
|
||||
return;
|
||||
#endif
|
||||
#ifdef ORACLE_9I
|
||||
if (PyType_Ready(&g_SessionPoolType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_TimestampVarType) < 0)
|
||||
return;
|
||||
#endif
|
||||
if (PyType_Ready(&g_EnvironmentType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_ObjectTypeType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_ObjectAttributeType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_StringVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_FixedCharVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_RowidVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_BinaryVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_LongStringVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_LongBinaryVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_NumberVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_ExternalLobVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_DateTimeVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_CLOBVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_NCLOBVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_BLOBVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_BFILEVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_CursorVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_ObjectVarType) < 0)
|
||||
return;
|
||||
if (PyType_Ready(&g_ExternalObjectVarType) < 0)
|
||||
return;
|
||||
|
||||
// initialize module and retrieve the dictionary
|
||||
module = Py_InitModule("cx_Oracle", g_ModuleMethods);
|
||||
if (!module)
|
||||
return;
|
||||
|
||||
// create exception object and add it to the dictionary
|
||||
if (SetException(module, &g_WarningException,
|
||||
"Warning", PyExc_StandardError) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_ErrorException,
|
||||
"Error", PyExc_StandardError) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_InterfaceErrorException,
|
||||
"InterfaceError", g_ErrorException) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_DatabaseErrorException,
|
||||
"DatabaseError", g_ErrorException) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_DataErrorException,
|
||||
"DataError", g_DatabaseErrorException) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_OperationalErrorException,
|
||||
"OperationalError", g_DatabaseErrorException) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_IntegrityErrorException,
|
||||
"IntegrityError", g_DatabaseErrorException) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_InternalErrorException,
|
||||
"InternalError", g_DatabaseErrorException) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_ProgrammingErrorException,
|
||||
"ProgrammingError", g_DatabaseErrorException) < 0)
|
||||
return;
|
||||
if (SetException(module, &g_NotSupportedErrorException,
|
||||
"NotSupportedError", g_DatabaseErrorException) < 0)
|
||||
return;
|
||||
|
||||
// set up the types that are available
|
||||
ADD_TYPE_OBJECT("Binary", &PyBuffer_Type)
|
||||
ADD_TYPE_OBJECT("Connection", &g_ConnectionType)
|
||||
ADD_TYPE_OBJECT("Cursor", &g_CursorType)
|
||||
#ifdef NATIVE_DATETIME
|
||||
ADD_TYPE_OBJECT("Timestamp", PyDateTimeAPI->DateTimeType)
|
||||
ADD_TYPE_OBJECT("Date", PyDateTimeAPI->DateType)
|
||||
#else
|
||||
ADD_TYPE_OBJECT("Timestamp", &g_ExternalDateTimeVarType)
|
||||
#endif
|
||||
#ifdef ORACLE_9I
|
||||
ADD_TYPE_OBJECT("SessionPool", &g_SessionPoolType)
|
||||
#endif
|
||||
ADD_TYPE_OBJECT("_Error", &g_ErrorType)
|
||||
|
||||
// the name "connect" is required by the DB API
|
||||
ADD_TYPE_OBJECT("connect", &g_ConnectionType)
|
||||
|
||||
// create the basic data types for setting input sizes
|
||||
ADD_TYPE_OBJECT("BINARY", &g_BinaryVarType)
|
||||
ADD_TYPE_OBJECT("BFILE", &g_BFILEVarType)
|
||||
ADD_TYPE_OBJECT("BLOB", &g_BLOBVarType)
|
||||
ADD_TYPE_OBJECT("CLOB", &g_CLOBVarType)
|
||||
ADD_TYPE_OBJECT("CURSOR", &g_CursorVarType)
|
||||
ADD_TYPE_OBJECT("OBJECT", &g_ObjectVarType)
|
||||
#ifdef NATIVE_DATETIME
|
||||
ADD_TYPE_OBJECT("DATETIME", PyDateTimeAPI->DateTimeType)
|
||||
#else
|
||||
ADD_TYPE_OBJECT("DATETIME", &g_ExternalDateTimeVarType)
|
||||
#endif
|
||||
ADD_TYPE_OBJECT("FIXED_CHAR", &g_FixedCharVarType)
|
||||
ADD_TYPE_OBJECT("LOB", &g_ExternalLobVarType)
|
||||
ADD_TYPE_OBJECT("LONG_BINARY", &g_LongBinaryVarType)
|
||||
ADD_TYPE_OBJECT("LONG_STRING", &g_LongStringVarType)
|
||||
ADD_TYPE_OBJECT("NCLOB", &g_NCLOBVarType)
|
||||
ADD_TYPE_OBJECT("NUMBER", &g_NumberVarType)
|
||||
ADD_TYPE_OBJECT("ROWID", &g_RowidVarType)
|
||||
ADD_TYPE_OBJECT("STRING", &g_StringVarType)
|
||||
#ifdef ORACLE_9I
|
||||
ADD_TYPE_OBJECT("TIMESTAMP", &g_TimestampVarType)
|
||||
#endif
|
||||
|
||||
// create constants required by Python DB API 2.0
|
||||
if (PyModule_AddStringConstant(module, "apilevel", "2.0") < 0)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(module, "threadsafety", 2) < 0)
|
||||
return;
|
||||
if (PyModule_AddStringConstant(module, "paramstyle", "named") < 0)
|
||||
return;
|
||||
|
||||
// add version and build time for easier support
|
||||
if (PyModule_AddStringConstant(module, "version",
|
||||
BUILD_VERSION_STRING) < 0)
|
||||
return;
|
||||
if (PyModule_AddStringConstant(module, "buildtime",
|
||||
__DATE__ " " __TIME__) < 0)
|
||||
return;
|
||||
|
||||
// add constants for registering callbacks
|
||||
ADD_OCI_CONSTANT(SYSDBA)
|
||||
ADD_OCI_CONSTANT(SYSOPER)
|
||||
ADD_OCI_CONSTANT(FNCODE_BINDBYNAME)
|
||||
ADD_OCI_CONSTANT(FNCODE_BINDBYPOS)
|
||||
ADD_OCI_CONSTANT(FNCODE_DEFINEBYPOS)
|
||||
ADD_OCI_CONSTANT(FNCODE_STMTEXECUTE)
|
||||
ADD_OCI_CONSTANT(FNCODE_STMTFETCH)
|
||||
ADD_OCI_CONSTANT(FNCODE_STMTPREPARE)
|
||||
ADD_OCI_CONSTANT(UCBTYPE_ENTRY)
|
||||
ADD_OCI_CONSTANT(UCBTYPE_EXIT)
|
||||
ADD_OCI_CONSTANT(UCBTYPE_REPLACE)
|
||||
#ifdef ORACLE_9I
|
||||
ADD_OCI_CONSTANT(SPOOL_ATTRVAL_WAIT)
|
||||
ADD_OCI_CONSTANT(SPOOL_ATTRVAL_NOWAIT)
|
||||
ADD_OCI_CONSTANT(SPOOL_ATTRVAL_FORCEGET)
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="prev" href="node12.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>About this document ...</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="8. License"
|
||||
href="node12.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="node12.html">8. License</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION0011000000000000000000">
|
||||
About this document ...</a>
|
||||
</h1>
|
||||
<strong>cx_Oracle</strong>,
|
||||
April 18, 2007, Release 4.3.1
|
||||
<p> This document was generated using the <a
|
||||
href="http://saftsack.fs.uni-bayreuth.de/~latex2ht/">
|
||||
<strong>LaTeX</strong>2<tt>HTML</tt></a> translator.
|
||||
</p>
|
||||
|
||||
<p> <a
|
||||
href="http://saftsack.fs.uni-bayreuth.de/~latex2ht/">
|
||||
<strong>LaTeX</strong>2<tt>HTML</tt></a> is Copyright ©
|
||||
1993, 1994, 1995, 1996, 1997, <a
|
||||
href="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos
|
||||
Drakos</a>, Computer Based Learning Unit, University of
|
||||
Leeds, and Copyright © 1997, 1998, <a
|
||||
href="http://www.maths.mq.edu.au/~ross/">Ross
|
||||
Moore</a>, Mathematics Department, Macquarie University,
|
||||
Sydney.
|
||||
</p>
|
||||
|
||||
<p> The application of <a
|
||||
href="http://saftsack.fs.uni-bayreuth.de/~latex2ht/">
|
||||
<strong>LaTeX</strong>2<tt>HTML</tt></a> to the Python
|
||||
documentation has been heavily tailored by Fred L. Drake,
|
||||
Jr. Original navigation icons were contributed by Christopher
|
||||
Petrilli.
|
||||
</p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="8. License"
|
||||
href="node12.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="node12.html">8. License</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 1.0 KiB |
|
@ -0,0 +1,323 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="cursorobj.html" />
|
||||
<link rel="prev" href="module.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="cursorobj.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>2. Connection Objects</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="1.2 Exceptions"
|
||||
href="node5.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="3. cursor Objects"
|
||||
href="cursorobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="node5.html">1.2 Exceptions</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="cursorobj.html">3. Cursor Objects</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION004000000000000000000"></a><a name="connobj"></a>
|
||||
<br>
|
||||
2. Connection Objects
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<strong>NOTE</strong>: Any outstanding changes will be rolled back when the connection
|
||||
object is destroyed or closed.
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-58' xml:id='l2h-58'>action</tt></b></dt>
|
||||
<dd>
|
||||
This write-only attribute sets the action column in the v$session table and
|
||||
is only available in Oracle 10g.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-59' xml:id='l2h-59' class="function">begin</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
<dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt class="function">begin</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>formatId</var>, <var>transactionId</var>,
|
||||
<var>branchId</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd> Explicitly begin a new transaction. Without parameters, this explicitly
|
||||
begins a local transaction; otherwise, this explicitly begins a distributed
|
||||
(global) transaction with the given parameters. See the Oracle documentation
|
||||
for more details.
|
||||
|
||||
<p>
|
||||
Note that in order to make use of global (distributed) transactions, the
|
||||
twophase argument to the Connection constructor must be a true value. See the
|
||||
comments on the Connection constructor for more information (<a href="module.html#module">1</a>).
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-61' xml:id='l2h-61' class="function">cancel</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Cancel a long-running transaction. This is only effective on non-Windows
|
||||
platforms.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-62' xml:id='l2h-62'>clientinfo</tt></b></dt>
|
||||
<dd>
|
||||
This write-only attribute sets the client_info column in the v$session table
|
||||
and is only available in Oracle 10g.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-63' xml:id='l2h-63' class="function">close</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Close the connection now, rather than whenever __del__ is called. The
|
||||
connection will be unusable from this point forward; an Error exception will
|
||||
be raised if any operation is attempted with the connection. The same applies
|
||||
to any cursor objects trying to use the connection.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-64' xml:id='l2h-64' class="function">commit</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Commit any pending transactions to the database.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-65' xml:id='l2h-65' class="function">cursor</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Return a new Cursor object (<a href="cursorobj.html#cursorobj">3</a>) using the connection.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-66' xml:id='l2h-66'>dsn</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the TNS entry of the database to which a
|
||||
connection has been established.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-67' xml:id='l2h-67'>encoding</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the IANA character set name of the character
|
||||
set in use by the Oracle client.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-68' xml:id='l2h-68'>maxBytesPerCharacter</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the maximum number of bytes each character
|
||||
can use for the client character set.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-69' xml:id='l2h-69'>module</tt></b></dt>
|
||||
<dd>
|
||||
This write-only attribute sets the module column in the v$session table and
|
||||
is only available in Oracle 10g.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-70' xml:id='l2h-70'>nencoding</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the IANA character set name of the national
|
||||
character set in use by the Oracle client.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-71' xml:id='l2h-71'>password</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the password of the user which established
|
||||
the connection to the database.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-72' xml:id='l2h-72' class="function">prepare</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Prepare the distributed (global) transaction for commit.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-73' xml:id='l2h-73' class="function">register</tt></b>(</nobr></td>
|
||||
<td><var><var>code</var>, <var>when</var>, <var>function</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Register the function as an OCI callback. The code is one of the function
|
||||
codes defined in the Oracle documentation of which the most common ones are
|
||||
defined as constants in this module. The when parameter is one of
|
||||
UCBTYPE_ENTRY, UCBTYPE_EXIT or UCBTYPE_REPLACE. The function is a Python
|
||||
function which will accept the parameters that the OCI function accepts,
|
||||
modified as needed to return Python objects that are of some use. Note that
|
||||
this is a highly experimental method and can cause cx_Oracle to crash if not
|
||||
used properly. In particular, the OCI does not provide sizing information to
|
||||
the callback so attempts to access a variable beyond the allocated size will
|
||||
crash cx_Oracle. Use with caution.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-74' xml:id='l2h-74' class="function">rollback</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Rollback any pending transactions.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-75' xml:id='l2h-75'>tnsentry</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the TNS entry of the database to which a
|
||||
connection has been established.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-76' xml:id='l2h-76' class="function">unregister</tt></b>(</nobr></td>
|
||||
<td><var><var>code</var>, <var>when</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Unregister the function as an OCI callback. The code is one of the function
|
||||
codes defined in the Oracle documentation of which the most common ones are
|
||||
defined as constants in this module. The when parameter is one of
|
||||
UCBTYPE_ENTRY, UCBTYPE_EXIT or UCBTYPE_REPLACE.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-77' xml:id='l2h-77'>username</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the name of the user which established the
|
||||
connection to the database.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-78' xml:id='l2h-78'>version</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the version of the database to which a
|
||||
connection has been established.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="1.2 Exceptions"
|
||||
href="node5.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="3. cursor Objects"
|
||||
href="cursorobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="node5.html">1.2 Exceptions</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="cursorobj.html">3. Cursor Objects</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,109 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="module.html" />
|
||||
<link rel="prev" href="front.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="module.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>Contents</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="Front Matter"
|
||||
href="front.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="1. module Interface"
|
||||
href="module.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="front.html">Front Matter</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="module.html">1. Module Interface</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
<br><h2><a name="SECTION002000000000000000000">
|
||||
Contents</a>
|
||||
</h2>
|
||||
<!--Table of Contents-->
|
||||
|
||||
<ul class="TofC">
|
||||
<li><a href="module.html">1. Module Interface</a>
|
||||
<ul>
|
||||
<li><a href="node4.html">1.1 Constants</a>
|
||||
<li><a href="node5.html">1.2 Exceptions</a>
|
||||
</ul>
|
||||
<li><a href="connobj.html">2. Connection Objects</a>
|
||||
<li><a href="cursorobj.html">3. Cursor Objects</a>
|
||||
<li><a href="varobj.html">4. Variable Objects</a>
|
||||
<li><a href="sesspool.html">5. SessionPool Objects</a>
|
||||
<li><a href="lobobj.html">6. LOB Objects</a>
|
||||
<li><a href="dateobj.html">7. Date Objects</a>
|
||||
<li><a href="node12.html">8. License</a>
|
||||
</ul>
|
||||
<!--End of Table of Contents-->
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="Front Matter"
|
||||
href="front.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="1. module Interface"
|
||||
href="module.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="front.html">Front Matter</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="module.html">1. Module Interface</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 649 B |
|
@ -0,0 +1,459 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="varobj.html" />
|
||||
<link rel="prev" href="connobj.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="varobj.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>3. Cursor Objects</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="2. connection Objects"
|
||||
href="connobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="4. variable Objects"
|
||||
href="varobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="connobj.html">2. Connection Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="varobj.html">4. Variable Objects</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION005000000000000000000"></a><a name="cursorobj"></a>
|
||||
<br>
|
||||
3. Cursor Objects
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-79' xml:id='l2h-79'>arraysize</tt></b></dt>
|
||||
<dd>
|
||||
This read-write attribute specifies the number of rows to fetch at a time
|
||||
internally and is the default number of rows to fetch with the fetchmany()
|
||||
call. It defaults to 1 meaning to fetch a single row at a time. Note that
|
||||
this attribute can drastically affect the performance of a query since it
|
||||
directly affects the number of network round trips that need to be performed.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-80' xml:id='l2h-80'>bindarraysize</tt></b></dt>
|
||||
<dd>
|
||||
This read-write attribute specifies the number of rows to bind at a time and
|
||||
is used when creating variables via setinputsizes() or var(). It defaults to
|
||||
1 meaning to bind a single row at a time.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this attribute.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-81' xml:id='l2h-81' class="function">arrayvar</tt></b>(</nobr></td>
|
||||
<td><var><var>dataType</var>, <var>value</var>, </var><big>[</big><var><var>size</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Create an array variable associated with the cursor of the given type and
|
||||
size and return a variable object (<a href="varobj.html#varobj">4</a>). The value is either an
|
||||
integer specifying the number of elements to allocate or it is a list and
|
||||
the number of elements allocated is drawn from the size of the list. If the
|
||||
value is a list, the variable is also set with the contents of the list. If
|
||||
the size is not specified and the type is a string or binary, 4000 bytes
|
||||
(maximum allowable by Oracle) is allocated. This is needed for passing arrays
|
||||
to PL/SQL (in cases where the list might be empty and the type cannot be
|
||||
determined automatically) or returning arrays from PL/SQL.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-82' xml:id='l2h-82' class="function">bindnames</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Return the list of bind variable names bound to the statement. Note that the
|
||||
statement must have been prepared first.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-83' xml:id='l2h-83' class="function">callfunc</tt></b>(</nobr></td>
|
||||
<td><var><var>name</var>, <var>returnType</var>,
|
||||
</var><big>[</big><var><var>parameters=[]</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Call a function with the given name. The return type is specified in the
|
||||
same notation as is required by setinputsizes(). The sequence of parameters
|
||||
must contain one entry for each argument that the function expects.
|
||||
The result of the call is the return value of the function.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-84' xml:id='l2h-84' class="function">callproc</tt></b>(</nobr></td>
|
||||
<td><var><var>name</var>, </var><big>[</big><var><var>parameters=[]</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Call a procedure with the given name. The sequence of parameters must contain
|
||||
one entry for each argument that the procedure expects. The result of the
|
||||
call is a modified copy of the input sequence. Input parameters are left
|
||||
untouched; output and input/output parameters are replaced with possibly new
|
||||
values.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-85' xml:id='l2h-85' class="function">close</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Close the cursor now, rather than whenever __del__ is called. The cursor will
|
||||
be unusable from this point forward; an Error exception will be raised if any
|
||||
operation is attempted with the cursor.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-86' xml:id='l2h-86'>connection</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns a reference to the connection object on
|
||||
which the cursor was created.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition but it
|
||||
is mentioned in PEP 249 as an optional extension.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-87' xml:id='l2h-87'>description</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute is a sequence of 7-item sequences. Each of these
|
||||
sequences contains information describing one result column: (name, type,
|
||||
display_size, internal_size, precision, scale, null_ok). This attribute will
|
||||
be None for operations that do not return rows or if the cursor has not had
|
||||
an operation invoked via the execute() method yet.
|
||||
|
||||
<p>
|
||||
The type will be one of the type objects defined at the module level.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-88' xml:id='l2h-88' class="function">execute</tt></b>(</nobr></td>
|
||||
<td><var><var>statement</var>, </var><big>[</big><var><var>parameters</var></var><big>]</big><var>,
|
||||
<var>**keywordParameters</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Execute a statement against the database. Parameters may be passed as a
|
||||
dictionary or sequence or as keyword arguments. If the arguments are a
|
||||
dictionary, the values will be bound by name and if the arguments are a
|
||||
sequence the values will be bound by position.
|
||||
|
||||
<p>
|
||||
A reference to the statement will be retained by the cursor. If None or the
|
||||
same string object is passed in again, the cursor will execute that
|
||||
statement again without performing a prepare or rebinding and redefining.
|
||||
This is most effective for algorithms where the same statement is used, but
|
||||
different parameters are bound to it (many times).
|
||||
|
||||
<p>
|
||||
For maximum efficiency when reusing an statement, it is best to use the
|
||||
setinputsizes() method to specify the parameter types and sizes ahead of
|
||||
time; in particular, None is assumed to be a string of length 1 so any
|
||||
values that are later bound as numbers or dates will raise a TypeError
|
||||
exception.
|
||||
|
||||
<p>
|
||||
If the statement is a query, a list of variable objects (<a href="varobj.html#varobj">4</a>) will
|
||||
be returned corresponding to the list of variables into which data will be
|
||||
fetched with the fetchone(), fetchmany() and fetchall() methods; otherwise,
|
||||
None will be returned.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define the return value of this
|
||||
method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-89' xml:id='l2h-89' class="function">executemany</tt></b>(</nobr></td>
|
||||
<td><var><var>statement</var>, <var>parameters</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Prepare a statement for execution against a database and then execute it
|
||||
against all parameter mappings or sequences found in the sequence parameters.
|
||||
The statement is managed in the same way as the execute() method manages it.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-90' xml:id='l2h-90' class="function">executemanyprepared</tt></b>(</nobr></td>
|
||||
<td><var><var>numIters</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Execute the previously prepared and bound statement the given number of
|
||||
times. The variables that are bound must have already been set to their
|
||||
desired value before this call is made. This method was designed for the
|
||||
case where optimal performance is required as it comes at the expense of
|
||||
compatibility with the DB API.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-91' xml:id='l2h-91' class="function">fetchall</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Fetch all (remaining) rows of a query result, returning them as a list of
|
||||
tuples. An empty list is returned if no more rows are available. Note that
|
||||
the cursor's arraysize attribute can affect the performance of this
|
||||
operation, as internally reads from the database are done in batches
|
||||
corresponding to the arraysize.
|
||||
|
||||
<p>
|
||||
An exception is raised if the previous call to execute() did not produce any
|
||||
result set or no call was issued yet.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-92' xml:id='l2h-92' class="function">fetchmany</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>numRows=cursor.arraysize</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Fetch the next set of rows of a query result, returning a list of tuples. An
|
||||
empty list is returned if no more rows are available. Note that the cursor's
|
||||
arraysize attribute can affect the performance of this operation.
|
||||
|
||||
<p>
|
||||
The number of rows to fetch is specified by the parameter. If it is not
|
||||
given, the cursor's arrysize attribute determines the number of rows to be
|
||||
fetched. If the number of rows available to be fetched is fewer than the
|
||||
amount requested, fewer rows will be returned.
|
||||
|
||||
<p>
|
||||
An exception is raised if the previous call to execute() did not produce any
|
||||
result set or no call was issued yet.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-93' xml:id='l2h-93' class="function">fetchone</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Fetch the next row of a query result set, returning a single tuple or None
|
||||
when no more data is available.
|
||||
|
||||
<p>
|
||||
An exception is raised if the previous call to execute() did not produce any
|
||||
result set or no call was issued yet.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-94' xml:id='l2h-94' class="function">fetchraw</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>numRows=cursor.arraysize</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Fetch the next set of rows of a query result into the internal buffers of the
|
||||
defined variables for the cursor. The number of rows actually fetched is
|
||||
returned. This method was designed for the case where optimal performance is
|
||||
required as it comes at the expense of compatibility with the DB API.
|
||||
|
||||
<p>
|
||||
An exception is raised if the previous call to execute() did not produce any
|
||||
result set or no call was issued yet.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-95' xml:id='l2h-95' class="function">__iter__</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Returns the cursor itself to be used as an iterator.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition but it
|
||||
is mentioned in PEP 249 as an optional extension.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-96' xml:id='l2h-96' class="function">next</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Fetch the next row of a query result set, using the same semantics as
|
||||
the method fetchone().
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition but it
|
||||
is mentioned in PEP 249 as an optional extension.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-97' xml:id='l2h-97'>numbersAsStrings</tt></b></dt>
|
||||
<dd>
|
||||
This integer attribute defines whether or not numbers should be returned as
|
||||
strings rather than integers or floating point numbers. This is useful to get
|
||||
around the fact that Oracle floating point numbers have considerably greater
|
||||
precision than C floating point numbers and not require a change to the SQL
|
||||
being executed.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this attribute.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-98' xml:id='l2h-98' class="function">parse</tt></b>(</nobr></td>
|
||||
<td><var><var>statement</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
This can be used to parse a statement without actually executing it (this
|
||||
step is done automatically by Oracle when a statement is executed).
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-99' xml:id='l2h-99' class="function">prepare</tt></b>(</nobr></td>
|
||||
<td><var><var>statement</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
This can be used before a call to execute() to define the statement that will
|
||||
be executed. When this is done, the prepare phase will not be performed when
|
||||
the call to execute() is made with None or the same string object as the
|
||||
statement.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-100' xml:id='l2h-100'>rowcount</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute specifies the number of rows that have currently
|
||||
been fetched from the cursor (for select statements) or that have been
|
||||
affected by the operation (for insert, update and delete statements).
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-101' xml:id='l2h-101' class="function">setinputsizes</tt></b>(</nobr></td>
|
||||
<td><var><var>*args</var>, <var>**keywordArgs</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
This can be used before a call to execute() to predefine memory areas for the
|
||||
operation's parameters. Each parameter should be a type object corresponding
|
||||
to the input that will be used or it should be an integer specifying the
|
||||
maximum length of a string parameter. Use keyword arguments when binding by
|
||||
name and positional arguments when binding by position. The singleton None
|
||||
can be used as a parameter when using positional arguments to indicate that
|
||||
no space should be reserved for that position.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-102' xml:id='l2h-102' class="function">setoutputsize</tt></b>(</nobr></td>
|
||||
<td><var><var>size</var>, </var><big>[</big><var><var>column</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
This can be used before a call to execute() to predefine memory areas for the
|
||||
long columns that will be fetched. The column is specified as an index into
|
||||
the result sequence. Not specifying the column will set the default size for
|
||||
all large columns in the cursor.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-103' xml:id='l2h-103'>statement</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute provides the string object that was previously
|
||||
prepared with prepare() or executed with execute().
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this attribute.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-104' xml:id='l2h-104' class="function">var</tt></b>(</nobr></td>
|
||||
<td><var><var>dataType</var>, </var><big>[</big><var><var>size</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Create a variable associated with the cursor of the given type and size and
|
||||
return a variable object (<a href="varobj.html#varobj">4</a>). If the size is not specified and the
|
||||
type is a string or binary, 4000 bytes (maximum allowable by Oracle) is
|
||||
allocated; if the size is not specified and the type is a long string or long
|
||||
binary, 128KB is allocated. This method was designed for use with PL/SQL
|
||||
in/out variables where the length or type cannot be determined automatically
|
||||
from the Python object passed in.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this method.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="2. connection Objects"
|
||||
href="connobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="4. variable Objects"
|
||||
href="varobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="connobj.html">2. Connection Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="varobj.html">4. Variable Objects</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* The first part of this is the standard CSS generated by LaTeX2HTML,
|
||||
* with the "empty" declarations removed.
|
||||
*/
|
||||
|
||||
/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */
|
||||
.math { font-family: "Century Schoolbook", serif; }
|
||||
.math i { font-family: "Century Schoolbook", serif;
|
||||
font-weight: bold }
|
||||
.boldmath { font-family: "Century Schoolbook", serif;
|
||||
font-weight: bold }
|
||||
|
||||
/*
|
||||
* Implement both fixed-size and relative sizes.
|
||||
*
|
||||
* I think these can be safely removed, as it doesn't appear that
|
||||
* LaTeX2HTML ever generates these, even though these are carried
|
||||
* over from the LaTeX2HTML stylesheet.
|
||||
*/
|
||||
small.xtiny { font-size : xx-small; }
|
||||
small.tiny { font-size : x-small; }
|
||||
small.scriptsize { font-size : smaller; }
|
||||
small.footnotesize { font-size : small; }
|
||||
big.xlarge { font-size : large; }
|
||||
big.xxlarge { font-size : x-large; }
|
||||
big.huge { font-size : larger; }
|
||||
big.xhuge { font-size : xx-large; }
|
||||
|
||||
/*
|
||||
* Document-specific styles come next;
|
||||
* these are added for the Python documentation.
|
||||
*
|
||||
* Note that the size specifications for the H* elements are because
|
||||
* Netscape on Solaris otherwise doesn't get it right; they all end up
|
||||
* the normal text size.
|
||||
*/
|
||||
|
||||
body { color: #000000;
|
||||
background-color: #ffffff; }
|
||||
|
||||
a:link:active { color: #ff0000; }
|
||||
a:link:hover { background-color: #bbeeff; }
|
||||
a:visited:hover { background-color: #bbeeff; }
|
||||
a:visited { color: #551a8b; }
|
||||
a:link { color: #0000bb; }
|
||||
|
||||
h1, h2, h3, h4, h5, h6 { font-family: avantgarde, sans-serif;
|
||||
font-weight: bold; }
|
||||
h1 { font-size: 180%; }
|
||||
h2 { font-size: 150%; }
|
||||
h3, h4 { font-size: 120%; }
|
||||
|
||||
/* These are section titles used in navigation links, so make sure we
|
||||
* match the section header font here, even it not the weight.
|
||||
*/
|
||||
.sectref { font-family: avantgarde, sans-serif; }
|
||||
/* And the label before the titles in navigation: */
|
||||
.navlabel { font-size: 85%; }
|
||||
|
||||
|
||||
/* LaTeX2HTML insists on inserting <br> elements into headers which
|
||||
* are marked with \label. This little bit of CSS magic ensures that
|
||||
* these elements don't cause spurious whitespace to be added.
|
||||
*/
|
||||
h1>br, h2>br, h3>br,
|
||||
h4>br, h5>br, h6>br { display: none; }
|
||||
|
||||
code, tt { font-family: "lucida typewriter", lucidatypewriter,
|
||||
monospace; }
|
||||
var { font-family: times, serif;
|
||||
font-style: italic;
|
||||
font-weight: normal; }
|
||||
|
||||
.Unix { font-variant: small-caps; }
|
||||
|
||||
.typelabel { font-family: lucida, sans-serif; }
|
||||
|
||||
.navigation td { background-color: #99ccff;
|
||||
font-weight: bold;
|
||||
font-family: avantgarde, sans-serif;
|
||||
font-size: 110%; }
|
||||
|
||||
div.warning { background-color: #fffaf0;
|
||||
border: thin solid black;
|
||||
padding: 1em;
|
||||
margin-left: 2em;
|
||||
margin-right: 2em; }
|
||||
|
||||
div.warning .label { font-family: sans-serif;
|
||||
font-size: 110%;
|
||||
margin-right: 0.5em; }
|
||||
|
||||
div.note { background-color: #fffaf0;
|
||||
border: thin solid black;
|
||||
padding: 1em;
|
||||
margin-left: 2em;
|
||||
margin-right: 2em; }
|
||||
|
||||
div.note .label { margin-right: 0.5em;
|
||||
font-family: sans-serif; }
|
||||
|
||||
address { font-size: 80%; }
|
||||
.release-info { font-style: italic;
|
||||
font-size: 80%; }
|
||||
|
||||
.titlegraphic { vertical-align: top; }
|
||||
|
||||
.verbatim pre { color: #00008b;
|
||||
font-family: "lucida typewriter", lucidatypewriter,
|
||||
monospace;
|
||||
font-size: 90%; }
|
||||
.verbatim { margin-left: 2em; }
|
||||
.verbatim .footer { padding: 0.05in;
|
||||
font-size: 85%;
|
||||
background-color: #99ccff;
|
||||
margin-right: 0.5in; }
|
||||
|
||||
.grammar { background-color: #99ccff;
|
||||
margin-right: 0.5in;
|
||||
padding: 0.05in; }
|
||||
.grammar-footer { padding: 0.05in;
|
||||
font-size: 85%; }
|
||||
.grammartoken { font-family: "lucida typewriter", lucidatypewriter,
|
||||
monospace; }
|
||||
|
||||
.productions { background-color: #bbeeff; }
|
||||
.productions a:active { color: #ff0000; }
|
||||
.productions a:link:hover { background-color: #99ccff; }
|
||||
.productions a:visited:hover { background-color: #99ccff; }
|
||||
.productions a:visited { color: #551a8b; }
|
||||
.productions a:link { color: #0000bb; }
|
||||
.productions table { vertical-align: baseline;
|
||||
empty-cells: show; }
|
||||
.productions > table td,
|
||||
.productions > table th { padding: 2px; }
|
||||
.productions > table td:first-child,
|
||||
.productions > table td:last-child {
|
||||
font-family: "lucida typewriter",
|
||||
lucidatypewriter,
|
||||
monospace;
|
||||
}
|
||||
/* same as the second selector above, but expressed differently for Opera */
|
||||
.productions > table td:first-child + td + td {
|
||||
font-family: "lucida typewriter",
|
||||
lucidatypewriter,
|
||||
monospace;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.productions > table td:first-child + td {
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
.productions > table tr { vertical-align: baseline; }
|
||||
|
||||
.email { font-family: avantgarde, sans-serif; }
|
||||
.mailheader { font-family: avantgarde, sans-serif; }
|
||||
.mimetype { font-family: avantgarde, sans-serif; }
|
||||
.newsgroup { font-family: avantgarde, sans-serif; }
|
||||
.url { font-family: avantgarde, sans-serif; }
|
||||
.file { font-family: avantgarde, sans-serif; }
|
||||
.guilabel { font-family: avantgarde, sans-serif; }
|
||||
|
||||
.realtable { border-collapse: collapse;
|
||||
border-color: black;
|
||||
border-style: solid;
|
||||
border-width: 0px 0px 2px 0px;
|
||||
empty-cells: show;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: 0.4em;
|
||||
padding-right: 0.4em;
|
||||
}
|
||||
.realtable tbody { vertical-align: baseline; }
|
||||
.realtable tfoot { display: table-footer-group; }
|
||||
.realtable thead { background-color: #99ccff;
|
||||
border-width: 0px 0px 2px 1px;
|
||||
display: table-header-group;
|
||||
font-family: avantgarde, sans-serif;
|
||||
font-weight: bold;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.realtable thead :first-child {
|
||||
border-width: 0px 0px 2px 0px;
|
||||
}
|
||||
.realtable thead th { border-width: 0px 0px 2px 1px }
|
||||
.realtable td,
|
||||
.realtable th { border-color: black;
|
||||
border-style: solid;
|
||||
border-width: 0px 0px 1px 1px;
|
||||
padding-left: 0.4em;
|
||||
padding-right: 0.4em;
|
||||
}
|
||||
.realtable td:first-child,
|
||||
.realtable th:first-child {
|
||||
border-left-width: 0px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.center { text-align: center; }
|
||||
.left { text-align: left; }
|
||||
.right { text-align: right; }
|
||||
|
||||
.refcount-info { font-style: italic; }
|
||||
.refcount-info .value { font-weight: bold;
|
||||
color: #006600; }
|
||||
|
||||
/*
|
||||
* Some decoration for the "See also:" blocks, in part inspired by some of
|
||||
* the styling on Lars Marius Garshol's XSA pages.
|
||||
* (The blue in the navigation bars is #99CCFF.)
|
||||
*/
|
||||
.seealso { background-color: #fffaf0;
|
||||
border: thin solid black;
|
||||
padding: 0pt 1em 4pt 1em; }
|
||||
|
||||
.seealso > .heading { font-size: 110%;
|
||||
font-weight: bold; }
|
||||
|
||||
/*
|
||||
* Class 'availability' is used for module availability statements at
|
||||
* the top of modules.
|
||||
*/
|
||||
.availability .platform { font-weight: bold; }
|
||||
|
||||
|
||||
/*
|
||||
* Additional styles for the distutils package.
|
||||
*/
|
||||
.du-command { font-family: monospace; }
|
||||
.du-option { font-family: avantgarde, sans-serif; }
|
||||
.du-filevar { font-family: avantgarde, sans-serif;
|
||||
font-style: italic; }
|
||||
.du-xxx:before { content: "** ";
|
||||
font-weight: bold; }
|
||||
.du-xxx:after { content: " **";
|
||||
font-weight: bold; }
|
||||
|
||||
|
||||
/*
|
||||
* Some specialization for printed output.
|
||||
*/
|
||||
@media print {
|
||||
.online-navigation { display: none; }
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="front.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>cx_Oracle</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></td>
|
||||
<td class='online-navigation'><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></td>
|
||||
<td class='online-navigation'><a rel="next" title="Front Matter"
|
||||
href="front.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="front.html">Front Matter</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<p>
|
||||
|
||||
<div class="titlepage">
|
||||
<div class='center'>
|
||||
<h1>cx_Oracle</h1>
|
||||
<p><b><font size="+2">Anthony Tuininga</font></b></p>
|
||||
<p>
|
||||
<strong>Computronix</strong>
|
||||
<br>
|
||||
Email: <span class="email">anthony.tuininga@gmail.com</span>
|
||||
</p>
|
||||
<p><strong>Release 4.3.1</strong><br />
|
||||
<strong>April 18, 2007</strong></p>
|
||||
<p></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
||||
<p><br /></p><hr class='online-navigation' />
|
||||
<div class='online-navigation'>
|
||||
<!--Table of Child-Links-->
|
||||
<a name="CHILD_LINKS"></a>
|
||||
|
||||
<ul class="ChildLinks">
|
||||
<li><a href="front.html">Front Matter</a>
|
||||
<li><a href="contents.html">Contents</a>
|
||||
<li><a href="module.html">1. Module Interface</a>
|
||||
<ul>
|
||||
<li><a href="node4.html">1.1 Constants</a>
|
||||
<li><a href="node5.html">1.2 Exceptions</a>
|
||||
</ul>
|
||||
<li><a href="connobj.html">2. Connection Objects</a>
|
||||
<li><a href="cursorobj.html">3. Cursor Objects</a>
|
||||
<li><a href="varobj.html">4. Variable Objects</a>
|
||||
<li><a href="sesspool.html">5. SessionPool Objects</a>
|
||||
<li><a href="lobobj.html">6. LOB Objects</a>
|
||||
<li><a href="dateobj.html">7. Date Objects</a>
|
||||
<li><a href="node12.html">8. License</a>
|
||||
<li><a href="about.html">About this document ...</a>
|
||||
</ul>
|
||||
<!--End of Table of Child-Links-->
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></td>
|
||||
<td class='online-navigation'><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></td>
|
||||
<td class='online-navigation'><a rel="next" title="Front Matter"
|
||||
href="front.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="front.html">Front Matter</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,148 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="node12.html" />
|
||||
<link rel="prev" href="lobobj.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="node12.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>7. Date Objects</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="6. lob Objects"
|
||||
href="lobobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="8. License"
|
||||
href="node12.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="lobobj.html">6. LOB Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="node12.html">8. License</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION009000000000000000000"></a><a name="dateobj"></a>
|
||||
<br>
|
||||
7. Date Objects
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<strong>NOTE</strong>: This object is an extension the DB API. It is returned whenever
|
||||
Oracle date and timestamp (in Oracle 9i) columns are fetched and whenever the
|
||||
constructor methods (Date(), Time(), Timestamp()) are called.
|
||||
|
||||
<p>
|
||||
<strong>NOTE</strong>: As of Python 2.4 cx_Oracle returns the datetime objects from the
|
||||
standard library datetime module instead of these objects.
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-130' xml:id='l2h-130'>year</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the year.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-131' xml:id='l2h-131'>month</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the month.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-132' xml:id='l2h-132'>day</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the day.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-133' xml:id='l2h-133'>hour</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the hour.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-134' xml:id='l2h-134'>minute</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the minute.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-135' xml:id='l2h-135'>second</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the second.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-136' xml:id='l2h-136'>fsecond</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the fractional second.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="6. lob Objects"
|
||||
href="lobobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="8. License"
|
||||
href="node12.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="lobobj.html">6. LOB Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="node12.html">8. License</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,120 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="contents.html" />
|
||||
<link rel="prev" href="cx_Oracle.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="contents.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>Front Matter</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="Contents"
|
||||
href="contents.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="contents.html">Contents</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION001000000000000000000"></a><a name="front"></a>
|
||||
<br>
|
||||
Front Matter
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
Copyright © 2001-2007 Computronix.
|
||||
All rights reserved.
|
||||
|
||||
<p>
|
||||
See the end of this document for complete license and permissions
|
||||
information.
|
||||
|
||||
<p>
|
||||
|
||||
<h3>Abstract:</h3>
|
||||
<div class="ABSTRACT">
|
||||
|
||||
<p>
|
||||
cx_Oracle is a Python extension module that allows access to Oracle and
|
||||
conforms to the Python database API 2.0 specifications with a few exceptions.
|
||||
See <a class="url" href="http://www.python.org/topics/database/DatabaseAPI-2.0.html">http://www.python.org/topics/database/DatabaseAPI-2.0.html</a> for more
|
||||
information on the Python database API specification.
|
||||
|
||||
<p>
|
||||
</div>
|
||||
<p>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="Contents"
|
||||
href="contents.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="contents.html">Contents</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,119 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="front.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>cx_Oracle</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></td>
|
||||
<td class='online-navigation'><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></td>
|
||||
<td class='online-navigation'><a rel="next" title="Front Matter"
|
||||
href="front.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="front.html">Front Matter</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<p>
|
||||
|
||||
<div class="titlepage">
|
||||
<div class='center'>
|
||||
<h1>cx_Oracle</h1>
|
||||
<p><b><font size="+2">Anthony Tuininga</font></b></p>
|
||||
<p>
|
||||
<strong>Computronix</strong>
|
||||
<br>
|
||||
Email: <span class="email">anthony.tuininga@gmail.com</span>
|
||||
</p>
|
||||
<p><strong>Release 4.3.1</strong><br />
|
||||
<strong>April 18, 2007</strong></p>
|
||||
<p></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
||||
<p><br /></p><hr class='online-navigation' />
|
||||
<div class='online-navigation'>
|
||||
<!--Table of Child-Links-->
|
||||
<a name="CHILD_LINKS"></a>
|
||||
|
||||
<ul class="ChildLinks">
|
||||
<li><a href="front.html">Front Matter</a>
|
||||
<li><a href="contents.html">Contents</a>
|
||||
<li><a href="module.html">1. Module Interface</a>
|
||||
<ul>
|
||||
<li><a href="node4.html">1.1 Constants</a>
|
||||
<li><a href="node5.html">1.2 Exceptions</a>
|
||||
</ul>
|
||||
<li><a href="connobj.html">2. Connection Objects</a>
|
||||
<li><a href="cursorobj.html">3. Cursor Objects</a>
|
||||
<li><a href="varobj.html">4. Variable Objects</a>
|
||||
<li><a href="sesspool.html">5. SessionPool Objects</a>
|
||||
<li><a href="lobobj.html">6. LOB Objects</a>
|
||||
<li><a href="dateobj.html">7. Date Objects</a>
|
||||
<li><a href="node12.html">8. License</a>
|
||||
<li><a href="about.html">About this document ...</a>
|
||||
</ul>
|
||||
<!--End of Table of Child-Links-->
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></td>
|
||||
<td class='online-navigation'><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></td>
|
||||
<td class='online-navigation'><a rel="next" title="Front Matter"
|
||||
href="front.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="front.html">Front Matter</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 529 B |
|
@ -0,0 +1,169 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="dateobj.html" />
|
||||
<link rel="prev" href="sesspool.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="dateobj.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>6. LOB Objects</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="5. sessionpool Objects"
|
||||
href="sesspool.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="7. date Objects"
|
||||
href="dateobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="sesspool.html">5. SessionPool Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="dateobj.html">7. Date Objects</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION008000000000000000000"></a><a name="lobobj"></a>
|
||||
<br>
|
||||
6. LOB Objects
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<strong>NOTE</strong>: This object is an extension the DB API. It is returned whenever
|
||||
Oracle CLOB, BLOB and BFILE columns are fetched.
|
||||
|
||||
<p>
|
||||
<strong>NOTE</strong>: Internally, Oracle uses LOB locators which are allocated based
|
||||
on the cursor array size. Thus, it is important that the data in the LOB object
|
||||
be manipulated before another internal fetch takes place. The safest way to do
|
||||
this is to use the cursor as an iterator. In particular, do not use the
|
||||
fetchall() method. The exception "LOB variable no longer valid after
|
||||
subsequent fetch" will be raised if an attempt to access a LOB variable after
|
||||
a subsequent fetch is detected.
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-123' xml:id='l2h-123' class="function">fileexists</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Return a boolean indicating if the file referenced by the BFILE type LOB
|
||||
exists.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-124' xml:id='l2h-124' class="function">getfilename</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Return a two-tuple consisting of the directory alias and file name for a
|
||||
BFILE type LOB.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-125' xml:id='l2h-125' class="function">read</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>offset = 1</var>, </var><big>[</big><var><var>amount</var></var><big>]</big><var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Return a portion (or all) of the data in the LOB object.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-126' xml:id='l2h-126' class="function">setfilename</tt></b>(</nobr></td>
|
||||
<td><var><var>dirAlias</var>, <var>name</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Set the directory alias and name of the BFILE type LOB.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-127' xml:id='l2h-127' class="function">size</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Returns the size of the data in the LOB object.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-128' xml:id='l2h-128' class="function">trim</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>newSize = 0</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Trim the LOB to the new size.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-129' xml:id='l2h-129' class="function">write</tt></b>(</nobr></td>
|
||||
<td><var><var>data</var>, </var><big>[</big><var><var>offset = 1</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Write the data to the LOB object at the given offset. Note that if you want
|
||||
to make the LOB value smaller, you must use the trim() function.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="5. sessionpool Objects"
|
||||
href="sesspool.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="7. date Objects"
|
||||
href="dateobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="sesspool.html">5. SessionPool Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="dateobj.html">7. Date Objects</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,256 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="connobj.html" />
|
||||
<link rel="prev" href="contents.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="node4.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>1. Module Interface</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="Contents"
|
||||
href="contents.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="1.1 Constants"
|
||||
href="node4.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="contents.html">Contents</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="node4.html">1.1 Constants</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION003000000000000000000"></a><a name="module"></a>
|
||||
<br>
|
||||
1. Module Interface
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-1' xml:id='l2h-1' class="function">Binary</tt></b>(</nobr></td>
|
||||
<td><var><var>string</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Construct an object holding a binary (long) string value.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-2' xml:id='l2h-2' class="function">Connection</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>user</var>, <var>password</var>,
|
||||
<var>dsn</var>, <var>mode</var>, <var>handle</var>, <var>pool</var>, <var>threaded</var>,
|
||||
<var>twophase</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
<dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt class="function">connect</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>user</var>, <var>password</var>,
|
||||
<var>dsn</var>, <var>mode</var>, <var>handle</var>, <var>pool</var>, <var>threaded</var>,
|
||||
<var>twophase</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd> Constructor for creating a connection to the database. Return a Connection
|
||||
object (<a href="connobj.html#connobj">2</a>). All arguments are optional and can be specified as
|
||||
keyword parameters. The dsn (data source name) is the TNS entry (from the
|
||||
Oracle names server or tnsnames.ora file) or is a string like the one
|
||||
returned from makedsn(). If only one parameter is passed, a connect string is
|
||||
assumed which is to be of the format "user/password@dsn", the same format
|
||||
accepted by Oracle applications such as SQL*Plus. If the mode is specified,
|
||||
it must be one of SYSDBA or SYSOPER which are defined at the module level;
|
||||
otherwise it defaults to the normal mode of connecting. If the handle is
|
||||
specified, it must be of type OCISvcCtx* and is only of use when embedding
|
||||
Python in an application (like PowerBuilder) which has already made the
|
||||
connection. The pool is only valid in Oracle 9i and is a session pool object
|
||||
(<a href="sesspool.html#sesspool">5</a>) which is the equivalent of calling pool.acquire(). The
|
||||
threaded attribute is expected to be a boolean expression which indicates
|
||||
whether or not Oracle should use the mode OCI_THREADED to wrap accesses to
|
||||
connections with a mutex. Doing so in single threaded applications imposes
|
||||
a performance penalty of about 10-15% which is why the default is False.
|
||||
The twophase attribute is expected to be a boolean expression which indicates
|
||||
whether or not the attributes should be set on the connection object to allow
|
||||
for two phase commit. The default for this value is also False because of
|
||||
bugs in Oracle prior to Oracle 10g.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-4' xml:id='l2h-4' class="function">Cursor</tt></b>(</nobr></td>
|
||||
<td><var><var>connection</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Constructor for creating a cursor. Return a new Cursor object
|
||||
(<a href="cursorobj.html#cursorobj">3</a>) using the connection.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-5' xml:id='l2h-5' class="function">Date</tt></b>(</nobr></td>
|
||||
<td><var><var>year</var>, <var>month</var>, <var>day</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Construct an object holding a date value.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-6' xml:id='l2h-6' class="function">DateFromTicks</tt></b>(</nobr></td>
|
||||
<td><var><var>ticks</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Construct an object holding a date value from the given ticks value (number
|
||||
of seconds since the epoch; see the documentation of the standard Python
|
||||
time module for details).
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-7' xml:id='l2h-7' class="function">makedsn</tt></b>(</nobr></td>
|
||||
<td><var><var>host</var>, <var>port</var>, <var>sid</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Return a string suitable for use as the dsn for the connect() method. This
|
||||
string is identical to the strings that are defined by the Oracle names
|
||||
server or defined in the tnsnames.ora file.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-8' xml:id='l2h-8' class="function">SessionPool</tt></b>(</nobr></td>
|
||||
<td><var><var>user</var>, <var>password</var>, <var>database</var>,
|
||||
<var>min</var>, <var>max</var>, <var>increment</var>, </var><big>[</big><var><var>connectiontype</var>,
|
||||
<var>threaded</var>, <var>getmode=cx_Oracle.SPOOL_ATTRVAL_NOWAIT</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Create a session pool (see Oracle 9i documentation for more information)
|
||||
and return a session pool object (<a href="sesspool.html#sesspool">5</a>). This allows for very
|
||||
fast connections to the database and is of primary use in a server where
|
||||
the same connection is being made multiple times in rapid succession (a
|
||||
web server, for example). If the connection type is specified, all calls to
|
||||
acquire() will create connection objects of that type, rather than the base
|
||||
type defined at the module level. The threaded attribute is expected to be a
|
||||
boolean expression which indicates whether or not Oracle should use the mode
|
||||
OCI_THREADED to wrap accesses to connections with a mutex. Doing so in single
|
||||
threaded applications imposes a performance penalty of about 10-15% which is
|
||||
why the default is False.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This method is an extension to the DB API definition and is
|
||||
only available in Oracle 9i.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-9' xml:id='l2h-9' class="function">Time</tt></b>(</nobr></td>
|
||||
<td><var><var>hour</var>, <var>minute</var>, <var>second</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Construct an object holding a time value.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-10' xml:id='l2h-10' class="function">TimeFromTicks</tt></b>(</nobr></td>
|
||||
<td><var><var>ticks</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Construct an object holding a time value from the given ticks value (number
|
||||
of seconds since the epoch; see the documentation of the standard Python
|
||||
time module for details).
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-11' xml:id='l2h-11' class="function">Timestamp</tt></b>(</nobr></td>
|
||||
<td><var><var>year</var>, <var>month</var>, <var>day</var>,
|
||||
<var>hour</var>, <var>minute</var>, <var>second</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Construct an object holding a time stamp value.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-12' xml:id='l2h-12' class="function">TimestampFromTicks</tt></b>(</nobr></td>
|
||||
<td><var><var>ticks</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Construct an object holding a time stamp value from the given ticks value
|
||||
(number of seconds since the epoch; see the documentation of the standard
|
||||
Python time module for details).
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
|
||||
<p><br /></p><hr class='online-navigation' />
|
||||
<div class='online-navigation'>
|
||||
<!--Table of Child-Links-->
|
||||
<a name="CHILD_LINKS"><strong>Subsections</strong></a>
|
||||
|
||||
<ul class="ChildLinks">
|
||||
<li><a href="node4.html">1.1 Constants</a>
|
||||
<li><a href="node5.html">1.2 Exceptions</a>
|
||||
</ul>
|
||||
<!--End of Table of Child-Links-->
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="Contents"
|
||||
href="contents.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="1.1 Constants"
|
||||
href="node4.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="contents.html">Contents</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="node4.html">1.1 Constants</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 598 B |
After Width: | Height: | Size: 511 B |
|
@ -0,0 +1,146 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="about.html" />
|
||||
<link rel="prev" href="dateobj.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="about.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>8. License</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="7. date Objects"
|
||||
href="dateobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="About this document ..."
|
||||
href="about.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="dateobj.html">7. Date Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="about.html">About this document ...</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION0010000000000000000000">
|
||||
8. License</a>
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<div class="centerline" id="par1465" align="CENTER">
|
||||
<strong>LICENSE AGREEMENT FOR CX_ORACLE 4.3.1</strong></div>
|
||||
|
||||
<p>
|
||||
Copyright © 2001-2007, Computronix (Canada) Ltd., Edmonton, Alberta, Canada.
|
||||
All rights reserved.
|
||||
|
||||
<p>
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
<p>
|
||||
|
||||
<ol>
|
||||
<li>Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions, and the disclaimer that follows.
|
||||
|
||||
<p>
|
||||
</li>
|
||||
<li>Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
<p>
|
||||
</li>
|
||||
<li>Neither the name of Computronix nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
DISCLAIMER:
|
||||
THIS SOFTWARE IS PROVIDED BY COMPUTRONIX AND CONTRIBUTORS *AS IS*
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COMPUTRONIX
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
<p>
|
||||
Computronix (R) is a registered trademark of Computronix (Canada) Ltd.
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="7. date Objects"
|
||||
href="dateobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="About this document ..."
|
||||
href="about.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="dateobj.html">7. Date Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="about.html">About this document ...</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,427 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="node5.html" />
|
||||
<link rel="prev" href="module.html" />
|
||||
<link rel="parent" href="module.html" />
|
||||
<link rel="next" href="node5.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>1.1 Constants</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="1. module Interface"
|
||||
href="module.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="1. module Interface"
|
||||
href="module.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="1.2 Exceptions"
|
||||
href="node5.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="module.html">1. Module Interface</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="module.html">1. Module Interface</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="node5.html">1.2 Exceptions</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION003100000000000000000">
|
||||
1.1 Constants</a>
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-13' xml:id='l2h-13'>apilevel</tt></b></dt>
|
||||
<dd>
|
||||
String constant stating the supported DB API level. Currently '2.0'.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-14' xml:id='l2h-14'>buildtime</tt></b></dt>
|
||||
<dd>
|
||||
String constant stating the time when the binary was built.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-15' xml:id='l2h-15'>BINARY</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are binary
|
||||
(in Oracle this is RAW columns).
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-16' xml:id='l2h-16'>BFILE</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are BFILEs.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-17' xml:id='l2h-17'>BLOB</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are BLOBs.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-18' xml:id='l2h-18'>CLOB</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are CLOBs.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-19' xml:id='l2h-19'>CURSOR</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are cursors
|
||||
(in PL/SQL these are known as ref cursors).
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-20' xml:id='l2h-20'>DATETIME</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are dates.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-21' xml:id='l2h-21'>FIXED_CHAR</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are fixed
|
||||
length strings (in Oracle this is CHAR columns); these behave differently
|
||||
in Oracle than varchar2 so they are differentiated here even though the DB
|
||||
API does not differentiate them.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-22' xml:id='l2h-22'>FNCODE_BINDBYNAME</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on the OCIBindByName() function
|
||||
of the OCI.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-23' xml:id='l2h-23'>FNCODE_BINDBYPOS</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on the OCIBindByPos() function
|
||||
of the OCI.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-24' xml:id='l2h-24'>FNCODE_DEFINEBYPOS</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on the OCIDefineByPos() function
|
||||
of the OCI.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-25' xml:id='l2h-25'>FNCODE_STMTEXECUTE</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on the OCIStmtExecute() function
|
||||
of the OCI.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-26' xml:id='l2h-26'>FNCODE_STMTFETCH</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on the OCIStmtFetch() function
|
||||
of the OCI.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-27' xml:id='l2h-27'>FNCODE_STMTPREPARE</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on the OCIStmtPrepare() function
|
||||
of the OCI.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-28' xml:id='l2h-28'>LOB</tt></b></dt>
|
||||
<dd>
|
||||
This type object is the Python type of BLOB and CLOB data that is returned
|
||||
from cursors.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-29' xml:id='l2h-29'>LONG_BINARY</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are long
|
||||
binary (in Oracle these are LONG RAW columns).
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-30' xml:id='l2h-30'>LONG_STRING</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are long
|
||||
strings (in Oracle these are LONG columns).
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-31' xml:id='l2h-31'>NCLOB</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are NCLOBs.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-32' xml:id='l2h-32'>NUMBER</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are numbers.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-33' xml:id='l2h-33'>OBJECT</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are objects.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-34' xml:id='l2h-34'>paramstyle</tt></b></dt>
|
||||
<dd>
|
||||
String constant stating the type of parameter marker formatting expected by
|
||||
the interface. Currently 'named' as in 'where name = :name'.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-35' xml:id='l2h-35'>ROWID</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe the pseudo column "rowid".
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-36' xml:id='l2h-36'>SPOOL_ATTRVAL_FORCEGET</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to define the "get" mode on session pools and indicates
|
||||
that a new connection will be returned if there are no free sessions
|
||||
available in the pool.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-37' xml:id='l2h-37'>SPOOL_ATTRVAL_NOWAIT</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to define the "get" mode on session pools and indicates
|
||||
that an exception is raised if there are no free sessions available in the
|
||||
pool.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-38' xml:id='l2h-38'>SPOOL_ATTRVAL_WAIT</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to define the "get" mode on session pools and indicates
|
||||
that the acquisition of a connection waits until a session is freed if there
|
||||
are no free sessions available in the pool.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-39' xml:id='l2h-39'>STRING</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are strings
|
||||
(in Oracle this is VARCHAR2 columns).
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-40' xml:id='l2h-40'>SYSDBA</tt></b></dt>
|
||||
<dd>
|
||||
Value to be passed to the connect() method which indicates that SYSDBA
|
||||
access is to be acquired. See the Oracle documentation for more details.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-41' xml:id='l2h-41'>SYSOPER</tt></b></dt>
|
||||
<dd>
|
||||
Value to be passed to the connect() method which indicates that SYSOPER
|
||||
access is to be acquired. See the Oracle documentation for more details.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-42' xml:id='l2h-42'>threadsafety</tt></b></dt>
|
||||
<dd>
|
||||
Integer constant stating the level of thread safety that the interface
|
||||
supports. Currently 2, which means that threads may share the module and
|
||||
connections, but not cursors. Sharing means that a thread may use a resource
|
||||
without wrapping it using a mutex semaphore to implement resource locking.
|
||||
|
||||
<p>
|
||||
Note that in order to make use of multiple threads in a program which intends
|
||||
to connect and disconnect in different threads, the threaded argument to the
|
||||
Connection constructor must be a true value. See the comments on the
|
||||
Connection constructor for more information (<a href="module.html#module">1</a>).
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-43' xml:id='l2h-43'>TIMESTAMP</tt></b></dt>
|
||||
<dd>
|
||||
This type object is used to describe columns in a database that are
|
||||
timestamps.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition and
|
||||
is only available in Oracle 9i.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-44' xml:id='l2h-44'>UCBTYPE_ENTRY</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on entry to the function
|
||||
of the OCI. In other words, the callback will be called prior to the
|
||||
execution of the OCI function.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-45' xml:id='l2h-45'>UCBTYPE_EXIT</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks on exit from the function
|
||||
of the OCI. In other words, the callback will be called after the execution
|
||||
of the OCI function.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-46' xml:id='l2h-46'>UCBTYPE_REPLACE</tt></b></dt>
|
||||
<dd>
|
||||
This constant is used to register callbacks that completely replace the
|
||||
call to the OCI function.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-47' xml:id='l2h-47'>version</tt></b></dt>
|
||||
<dd>
|
||||
String constant stating the version of the module. Currently '4.3.1'.
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> This attribute is an extension to the DB API definition.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="1. module Interface"
|
||||
href="module.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="1. module Interface"
|
||||
href="module.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="1.2 Exceptions"
|
||||
href="node5.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="module.html">1. Module Interface</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="module.html">1. Module Interface</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="node5.html">1.2 Exceptions</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,166 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="prev" href="node4.html" />
|
||||
<link rel="parent" href="module.html" />
|
||||
<link rel="next" href="connobj.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>1.2 Exceptions</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="1.1 Constants"
|
||||
href="node4.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="1. module Interface"
|
||||
href="module.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="2. connection Objects"
|
||||
href="connobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="node4.html">1.1 Constants</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="module.html">1. Module Interface</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="connobj.html">2. Connection Objects</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION003200000000000000000">
|
||||
1.2 Exceptions</a>
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-48' xml:id='l2h-48'>Warning</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised for important warnings and defined by the DB API but not
|
||||
actually used by cx_Oracle.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-49' xml:id='l2h-49'>Error</tt></b></dt>
|
||||
<dd>
|
||||
Exception that is the base class of all other exceptions defined by
|
||||
cx_Oracle and is a subclass of the Python StandardError exception (defined in
|
||||
the module exceptions).
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-50' xml:id='l2h-50'>InterfaceError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised for errors that are related to the database interface rather
|
||||
than the database itself. It is a subclass of Error.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-51' xml:id='l2h-51'>DatabaseError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised for errors that are related to the database. It is a
|
||||
subclass of Error.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-52' xml:id='l2h-52'>DataError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised for errors that are due to problems with the processed data.
|
||||
It is a subclass of DatabaseError.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-53' xml:id='l2h-53'>OperationalError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised for errors that are related to the operation of the database
|
||||
but are not necessarily under the control of the progammer. It is a
|
||||
subclass of DatabaseError.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-54' xml:id='l2h-54'>IntegrityError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised when the relational integrity of the database is affected.
|
||||
It is a subclass of DatabaseError.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-55' xml:id='l2h-55'>InternalError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised when the database encounters an internal error.
|
||||
It is a subclass of DatabaseError.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-56' xml:id='l2h-56'>ProgrammingError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised for programming errors. It is a subclass of DatabaseError.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-57' xml:id='l2h-57'>NotSupportedError</tt></b></dt>
|
||||
<dd>
|
||||
Exception raised when a method or database API was used which is not
|
||||
supported by the database. It is a subclass of DatabaseError.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="1.1 Constants"
|
||||
href="node4.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="1. module Interface"
|
||||
href="module.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="2. connection Objects"
|
||||
href="connobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="node4.html">1.1 Constants</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="module.html">1. Module Interface</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="connobj.html">2. Connection Objects</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 511 B |
|
@ -0,0 +1,206 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="lobobj.html" />
|
||||
<link rel="prev" href="varobj.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="lobobj.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>5. SessionPool Objects</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="4. variable Objects"
|
||||
href="varobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="6. lob Objects"
|
||||
href="lobobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="varobj.html">4. Variable Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="lobobj.html">6. LOB Objects</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION007000000000000000000"></a><a name="sesspool"></a>
|
||||
<br>
|
||||
5. SessionPool Objects
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<strong>NOTE</strong>: This object is an extension the DB API and is only available in
|
||||
Oracle 9i.
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-109' xml:id='l2h-109' class="function">acquire</tt></b>(</nobr></td>
|
||||
<td><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Acquire a connection from the session pool and return a connection
|
||||
object (<a href="connobj.html#connobj">2</a>).
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-110' xml:id='l2h-110'>busy</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the number of sessions currently acquired.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-111' xml:id='l2h-111' class="function">drop</tt></b>(</nobr></td>
|
||||
<td><var><var>connection</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Drop the connection from the pool which is useful if the connection is no
|
||||
longer usable (such as when the session is killed).
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-112' xml:id='l2h-112'>dsn</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the TNS entry of the database to which a
|
||||
connection has been established.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-113' xml:id='l2h-113'>increment</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the number of sessions that will be
|
||||
established when additional sessions need to be created.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-114' xml:id='l2h-114'>max</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the maximum number of sessions that the
|
||||
session pool can control.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-115' xml:id='l2h-115'>min</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the number of sessions with which the
|
||||
session pool was created and the minimum number of sessions that will be
|
||||
controlled by the session pool.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-116' xml:id='l2h-116'>name</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the name assigned to the session pool by
|
||||
Oracle.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-117' xml:id='l2h-117'>opened</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the number of sessions currently opened by
|
||||
the session pool.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-118' xml:id='l2h-118'>password</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the password of the user which established
|
||||
the connection to the database.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-119' xml:id='l2h-119' class="function">release</tt></b>(</nobr></td>
|
||||
<td><var><var>connection</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Release the connection back to the pool. This will be done automatically as
|
||||
well if the connection object is garbage collected.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-120' xml:id='l2h-120'>timeout</tt></b></dt>
|
||||
<dd>
|
||||
This read-write attribute indicates the time (in seconds) after which idle
|
||||
sessions will be terminated in order to maintain an optimum number of open
|
||||
sessions.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-121' xml:id='l2h-121'>tnsentry</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the TNS entry of the database to which a
|
||||
connection has been established.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-122' xml:id='l2h-122'>username</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the name of the user which established the
|
||||
connection to the database.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="4. variable Objects"
|
||||
href="varobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="6. lob Objects"
|
||||
href="lobobj.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="varobj.html">4. Variable Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="lobobj.html">6. LOB Objects</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 577 B |
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="STYLESHEET" href="cx_Oracle.css" type='text/css' />
|
||||
<link rel="first" href="cx_Oracle.html" title='cx_Oracle' />
|
||||
<link rel='contents' href='contents.html' title="Contents" />
|
||||
<link rel='last' href='about.html' title='About this document...' />
|
||||
<link rel='help' href='about.html' title='About this document...' />
|
||||
<link rel="next" href="sesspool.html" />
|
||||
<link rel="prev" href="cursorobj.html" />
|
||||
<link rel="parent" href="cx_Oracle.html" />
|
||||
<link rel="next" href="sesspool.html" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name='aesop' content='information' />
|
||||
<title>4. Variable Objects</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navigation">
|
||||
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="3. cursor Objects"
|
||||
href="cursorobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="5. sessionpool Objects"
|
||||
href="sesspool.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="cursorobj.html">3. Cursor Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="sesspool.html">5. SessionPool Objects</a>
|
||||
</div>
|
||||
<hr /></div>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
<h1><a name="SECTION006000000000000000000"></a><a name="varobj"></a>
|
||||
<br>
|
||||
4. Variable Objects
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
<strong>NOTE:</strong> The DB API definition does not define this object.
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-105' xml:id='l2h-105'>allocelems</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the number of elements allocated in an
|
||||
array, or the number of scalar items that can be fetched into the variable.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-106' xml:id='l2h-106' class="function">getvalue</tt></b>(</nobr></td>
|
||||
<td><var></var><big>[</big><var><var>pos=0</var></var><big>]</big><var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Return the value at the given position in the variable.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><b><tt id='l2h-107' xml:id='l2h-107'>maxlength</tt></b></dt>
|
||||
<dd>
|
||||
This read-only attribute returns the maximum length of the variable.
|
||||
</dd></dl>
|
||||
|
||||
<p>
|
||||
<dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline">
|
||||
<td><nobr><b><tt id='l2h-108' xml:id='l2h-108' class="function">setvalue</tt></b>(</nobr></td>
|
||||
<td><var><var>pos</var>, <var>value</var></var>)</td></tr></table></dt>
|
||||
<dd>
|
||||
Set the value at the given position in the variable.
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
|
||||
<div class="navigation">
|
||||
<div class='online-navigation'>
|
||||
<p></p><hr />
|
||||
<table align="center" width="100%" cellpadding="0" cellspacing="2">
|
||||
<tr>
|
||||
<td class='online-navigation'><a rel="prev" title="3. cursor Objects"
|
||||
href="cursorobj.html"><img src='previous.png'
|
||||
border='0' height='32' alt='Previous Page' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="parent" title="cx_Oracle"
|
||||
href="cx_Oracle.html"><img src='up.png'
|
||||
border='0' height='32' alt='Up one Level' width='32' /></a></td>
|
||||
<td class='online-navigation'><a rel="next" title="5. sessionpool Objects"
|
||||
href="sesspool.html"><img src='next.png'
|
||||
border='0' height='32' alt='Next Page' width='32' /></a></td>
|
||||
<td align="center" width="100%">cx_Oracle</td>
|
||||
<td class='online-navigation'><a rel="contents" title="Table of Contents"
|
||||
href="contents.html"><img src='contents.png'
|
||||
border='0' height='32' alt='Contents' width='32' /></a></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
<td class='online-navigation'><img src='blank.png'
|
||||
border='0' height='32' alt='' width='32' /></td>
|
||||
</tr></table>
|
||||
<div class='online-navigation'>
|
||||
<b class="navlabel">Previous:</b>
|
||||
<a class="sectref" rel="prev" href="cursorobj.html">3. Cursor Objects</a>
|
||||
<b class="navlabel">Up:</b>
|
||||
<a class="sectref" rel="parent" href="cx_Oracle.html">cx_Oracle</a>
|
||||
<b class="navlabel">Next:</b>
|
||||
<a class="sectref" rel="next" href="sesspool.html">5. SessionPool Objects</a>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<span class="release-info">Release 4.3.1, documentation updated on April 18, 2007.</span>
|
||||
</div>
|
||||
<!--End of Navigation Panel-->
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
[bdist_rpm]
|
||||
doc_files = LICENSE.txt README.txt HISTORY.txt html test
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
"""Distutils script for cx_Oracle.
|
||||
|
||||
Windows platforms:
|
||||
python setup.py build --compiler=mingw32 install
|
||||
|
||||
Unix platforms
|
||||
python setup.py build install
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from distutils.core import setup
|
||||
from distutils.extension import Extension
|
||||
|
||||
# define build constants
|
||||
BUILD_VERSION = "4.3.1"
|
||||
|
||||
# define the list of files to be included as documentation for Windows
|
||||
dataFiles = None
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
baseName = "cx_Oracle-doc"
|
||||
dataFiles = [ (baseName, [ "LICENSE.TXT", "README.TXT", "HISTORY.txt"]) ]
|
||||
allFiles = []
|
||||
for fileName in open("MANIFEST").readlines():
|
||||
allFiles.append(fileName.strip())
|
||||
for dir in ("html", "test"):
|
||||
files = []
|
||||
for name in allFiles:
|
||||
if name.startswith(dir):
|
||||
files.append(name)
|
||||
dataFiles.append( ("%s/%s" % (baseName, dir), files) )
|
||||
|
||||
# define some variables
|
||||
oracleHome = os.environ["ORACLE_HOME"]
|
||||
if sys.platform == "win32":
|
||||
libDirs = None
|
||||
includeDirs = [os.path.join(oracleHome, "oci", "include"), \
|
||||
os.path.join(oracleHome, "rdbms", "demo")]
|
||||
libs = []
|
||||
elif sys.platform == "cygwin":
|
||||
includeDirs = ["/usr/include", "rdbms/demo", "rdbms/public", \
|
||||
"network/public", "oci/include"]
|
||||
libDirs = ["bin", "lib"]
|
||||
for i in range(len(includeDirs)):
|
||||
includeDirs[i] = os.path.join(oracleHome, includeDirs[i])
|
||||
for i in range(len(libDirs)):
|
||||
libDirs[i] = os.path.join(oracleHome, libDirs[i])
|
||||
libs = ["oci"]
|
||||
else:
|
||||
includeDirs = ["rdbms/demo", "rdbms/public", "network/public",
|
||||
"sdk/include"]
|
||||
if sys.platform == "darwin":
|
||||
includeDirs.append("plsql/public")
|
||||
for i in range(len(includeDirs)):
|
||||
includeDirs[i] = os.path.join(oracleHome, includeDirs[i])
|
||||
libPath = os.path.join(oracleHome, "lib")
|
||||
if sys.platform == "sunos5" and sys.maxint > 2147483647:
|
||||
libPath = os.path.join(oracleHome, "lib64")
|
||||
libDirs = [libPath, oracleHome]
|
||||
libs = ["clntsh"]
|
||||
|
||||
# NOTE: on HP-UX Itanium with Oracle 10g you need to add the library "ttsh10"
|
||||
# to the list of libraries along with "clntsh"; since I am unable to test, I'll
|
||||
# leave this as a comment until someone can verify when this is required
|
||||
# without making other cases where sys.platform == "hp-ux11" stop working
|
||||
|
||||
# setup extra link and compile args
|
||||
extraCompileArgs = ["-DBUILD_VERSION=%s" % BUILD_VERSION]
|
||||
extraLinkArgs = []
|
||||
if sys.platform == "aix4":
|
||||
extraCompileArgs.append("-qcpluscmt")
|
||||
elif sys.platform == "cygwin":
|
||||
extraCompileArgs.append("-mno-cygwin")
|
||||
elif sys.platform == "darwin":
|
||||
extraLinkArgs = None
|
||||
elif sys.platform == "win32":
|
||||
import win32api
|
||||
extraLinkArgs.append(win32api.GetModuleFileName(sys.dllhandle))
|
||||
extraLinkArgs.append(os.path.join(oracleHome, "bin", "oci.dll"))
|
||||
|
||||
# force the inclusion of an RPATH linker directive if desired; this will
|
||||
# eliminate the need for setting LD_LIBRARY_PATH but it also means that this
|
||||
# location will be the only location searched for the Oracle client library
|
||||
if "FORCE_RPATH" in os.environ:
|
||||
extraLinkArgs.append("-Wl,-rpath,%s/lib" % oracleHome)
|
||||
|
||||
# setup the extension
|
||||
extension = Extension(
|
||||
name = "cx_Oracle",
|
||||
include_dirs = includeDirs,
|
||||
libraries = libs,
|
||||
library_dirs = libDirs,
|
||||
extra_compile_args = extraCompileArgs,
|
||||
extra_link_args = extraLinkArgs,
|
||||
sources = ["cx_Oracle.c"])
|
||||
|
||||
# perform the setup
|
||||
setup(
|
||||
name = "cx_Oracle",
|
||||
version = BUILD_VERSION,
|
||||
description = "Python interface to Oracle",
|
||||
license = "See LICENSE.txt",
|
||||
data_files = dataFiles,
|
||||
long_description = \
|
||||
"Python interface to Oracle conforming to the Python DB API 2.0 "
|
||||
"specification.\n"
|
||||
"See http://www.python.org/topics/database/DatabaseAPI-2.0.html.",
|
||||
author = "Anthony Tuininga",
|
||||
author_email = "anthony.tuininga@gmail.com",
|
||||
url = "http://starship.python.net/crew/atuining",
|
||||
ext_modules = [extension])
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
"""Module for testing connections."""
|
||||
|
||||
import threading
|
||||
|
||||
class TestConnection(TestCase):
|
||||
|
||||
def __ConnectAndDrop(self):
|
||||
"""Connect to the database, perform a query and drop the connection."""
|
||||
connection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry, threaded = True)
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("select count(*) from TestNumbers")
|
||||
count, = cursor.fetchone()
|
||||
self.failUnlessEqual(count, 10)
|
||||
|
||||
def setUp(self):
|
||||
self.username = USERNAME
|
||||
self.password = PASSWORD
|
||||
self.tnsentry = TNSENTRY
|
||||
|
||||
def verifyArgs(self, connection):
|
||||
self.failUnlessEqual(connection.username, self.username,
|
||||
"user name differs")
|
||||
self.failUnlessEqual(connection.password, self.password,
|
||||
"password differs")
|
||||
self.failUnlessEqual(connection.tnsentry, self.tnsentry,
|
||||
"tnsentry differs")
|
||||
|
||||
def testAllArgs(self):
|
||||
"connection to database with user, password, TNS separate"
|
||||
connection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry)
|
||||
self.verifyArgs(connection)
|
||||
|
||||
def testBadConnectString(self):
|
||||
"connection to database with bad connect string"
|
||||
self.failUnlessRaises(cx_Oracle.DatabaseError, cx_Oracle.connect,
|
||||
self.username)
|
||||
self.failUnlessRaises(cx_Oracle.DatabaseError, cx_Oracle.connect,
|
||||
self.username + "@" + self.tnsentry)
|
||||
self.failUnlessRaises(cx_Oracle.DatabaseError, cx_Oracle.connect,
|
||||
self.username + "@" + self.tnsentry + "/" + self.password)
|
||||
|
||||
def testBadPassword(self):
|
||||
"connection to database with bad password"
|
||||
self.failUnlessRaises(cx_Oracle.DatabaseError, cx_Oracle.connect,
|
||||
self.username, self.password + "X", self.tnsentry)
|
||||
|
||||
def testExceptionOnClose(self):
|
||||
"confirm an exception is raised after closing a connection"
|
||||
connection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry)
|
||||
connection.close()
|
||||
self.failUnlessRaises(cx_Oracle.InterfaceError, connection.rollback)
|
||||
|
||||
def testMakeDSN(self):
|
||||
"test making a data source name from host, port and sid"
|
||||
formatString = "(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)" + \
|
||||
"(HOST=%s)(PORT=%d)))(CONNECT_DATA=(SID=%s)))"
|
||||
args = ("hostname", 1521, "TEST")
|
||||
result = cx_Oracle.makedsn(*args)
|
||||
self.failUnlessEqual(result, formatString % args)
|
||||
|
||||
def testSingleArg(self):
|
||||
"connection to database with user, password, TNS together"
|
||||
connection = cx_Oracle.connect("%s/%s@%s" % \
|
||||
(self.username, self.password, self.tnsentry))
|
||||
self.verifyArgs(connection)
|
||||
|
||||
def testVersion(self):
|
||||
"connection version is a string"
|
||||
connection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry)
|
||||
self.failUnless(isinstance(connection.version, str))
|
||||
|
||||
def testRollbackOnClose(self):
|
||||
"connection rolls back before close"
|
||||
connection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry)
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("truncate table TestExecuteMany")
|
||||
otherConnection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry)
|
||||
otherCursor = otherConnection.cursor()
|
||||
otherCursor.execute("insert into TestExecuteMany values (1)")
|
||||
otherConnection.close()
|
||||
cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = cursor.fetchone()
|
||||
self.failUnlessEqual(count, 0)
|
||||
|
||||
def testRollbackOnDel(self):
|
||||
"connection rolls back before destruction"
|
||||
connection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry)
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("truncate table TestExecuteMany")
|
||||
otherConnection = cx_Oracle.connect(self.username, self.password,
|
||||
self.tnsentry)
|
||||
otherCursor = otherConnection.cursor()
|
||||
otherCursor.execute("insert into TestExecuteMany values (1)")
|
||||
del otherCursor
|
||||
del otherConnection
|
||||
cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = cursor.fetchone()
|
||||
self.failUnlessEqual(count, 0)
|
||||
|
||||
def testThreading(self):
|
||||
"connection to database with multiple threads"
|
||||
threads = []
|
||||
for i in range(20):
|
||||
thread = threading.Thread(None, self.__ConnectAndDrop)
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
"""Module for testing cursor objects."""
|
||||
|
||||
import cx_Oracle
|
||||
|
||||
class TestCursor(BaseTestCase):
|
||||
|
||||
def testExecuteNoArgs(self):
|
||||
"""test executing a statement without any arguments"""
|
||||
result = self.cursor.execute("begin null; end;")
|
||||
self.failUnlessEqual(result, None)
|
||||
|
||||
def testExecuteNoStatementWithArgs(self):
|
||||
"""test executing a None statement with bind variables"""
|
||||
self.failUnlessRaises(cx_Oracle.ProgrammingError, self.cursor.execute,
|
||||
None, x = 5)
|
||||
|
||||
def testExecuteEmptyKeywordArgs(self):
|
||||
"""test executing a statement with args and empty keyword args"""
|
||||
simpleVar = self.cursor.var(cx_Oracle.NUMBER)
|
||||
args = [simpleVar]
|
||||
kwArgs = {}
|
||||
result = self.cursor.execute("begin :1 := 25; end;", args, **kwArgs)
|
||||
self.failUnlessEqual(result, None)
|
||||
self.failUnlessEqual(simpleVar.getvalue(), 25)
|
||||
|
||||
def testExecuteKeywordArgs(self):
|
||||
"""test executing a statement with keyword arguments"""
|
||||
simpleVar = self.cursor.var(cx_Oracle.NUMBER)
|
||||
result = self.cursor.execute("begin :p_Value := 5; end;",
|
||||
p_Value = simpleVar)
|
||||
self.failUnlessEqual(result, None)
|
||||
self.failUnlessEqual(simpleVar.getvalue(), 5)
|
||||
|
||||
def testExecuteDictionaryArg(self):
|
||||
"""test executing a statement with a dictionary argument"""
|
||||
simpleVar = self.cursor.var(cx_Oracle.NUMBER)
|
||||
dictArg = { "p_Value" : simpleVar }
|
||||
result = self.cursor.execute("begin :p_Value := 10; end;", dictArg)
|
||||
self.failUnlessEqual(result, None)
|
||||
self.failUnlessEqual(simpleVar.getvalue(), 10)
|
||||
|
||||
def testExecuteMultipleMethod(self):
|
||||
"""test executing a statement with both a dict arg and keyword args"""
|
||||
simpleVar = self.cursor.var(cx_Oracle.NUMBER)
|
||||
dictArg = { "p_Value" : simpleVar }
|
||||
self.failUnlessRaises(cx_Oracle.InterfaceError, self.cursor.execute,
|
||||
"begin :p_Value := 15; end;", dictArg, p_Value = simpleVar)
|
||||
|
||||
def testExecuteAndModifyArraySize(self):
|
||||
"""test executing a statement and then changing the array size"""
|
||||
self.cursor.execute("select IntCol from TestNumbers")
|
||||
self.cursor.arraysize = 20
|
||||
self.failUnlessEqual(len(self.cursor.fetchall()), 10)
|
||||
|
||||
def testCallProc(self):
|
||||
"""test executing a stored procedure"""
|
||||
var = self.cursor.var(cx_Oracle.NUMBER)
|
||||
results = self.cursor.callproc("proc_Test", ("hi", 5, var))
|
||||
self.failUnlessEqual(results, ["hi", 10, 2.0])
|
||||
|
||||
def testCallProcNoArgs(self):
|
||||
"""test executing a stored procedure without any arguments"""
|
||||
results = self.cursor.callproc("proc_TestNoArgs")
|
||||
self.failUnlessEqual(results, [])
|
||||
|
||||
def testCallFunc(self):
|
||||
"""test executing a stored function"""
|
||||
results = self.cursor.callfunc("func_Test", cx_Oracle.NUMBER,
|
||||
("hi", 5))
|
||||
self.failUnlessEqual(results, 7)
|
||||
|
||||
def testCallFuncNoArgs(self):
|
||||
"""test executing a stored function without any arguments"""
|
||||
results = self.cursor.callfunc("func_TestNoArgs", cx_Oracle.NUMBER)
|
||||
self.failUnlessEqual(results, 712)
|
||||
|
||||
def testExecuteManyByName(self):
|
||||
"""test executing a statement multiple times (named args)"""
|
||||
self.cursor.execute("truncate table TestExecuteMany")
|
||||
rows = [ { "value" : n } for n in range(250) ]
|
||||
self.cursor.arraysize = 100
|
||||
statement = "insert into TestExecuteMany values (:value)"
|
||||
self.cursor.executemany(statement, rows)
|
||||
self.connection.commit()
|
||||
self.cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = self.cursor.fetchone()
|
||||
self.failUnlessEqual(count, len(rows))
|
||||
|
||||
def testExecuteManyByPosition(self):
|
||||
"""test executing a statement multiple times (positional args)"""
|
||||
self.cursor.execute("truncate table TestExecuteMany")
|
||||
rows = [ [n] for n in range(230) ]
|
||||
self.cursor.arraysize = 100
|
||||
statement = "insert into TestExecuteMany values (:1)"
|
||||
self.cursor.executemany(statement, rows)
|
||||
self.connection.commit()
|
||||
self.cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = self.cursor.fetchone()
|
||||
self.failUnlessEqual(count, len(rows))
|
||||
|
||||
def testExecuteManyWithPrepare(self):
|
||||
"""test executing a statement multiple times (with prepare)"""
|
||||
self.cursor.execute("truncate table TestExecuteMany")
|
||||
rows = [ [n] for n in range(225) ]
|
||||
self.cursor.arraysize = 100
|
||||
statement = "insert into TestExecuteMany values (:1)"
|
||||
self.cursor.prepare(statement)
|
||||
self.cursor.executemany(None, rows)
|
||||
self.connection.commit()
|
||||
self.cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = self.cursor.fetchone()
|
||||
self.failUnlessEqual(count, len(rows))
|
||||
|
||||
def testExecuteManyWithRebind(self):
|
||||
"""test executing a statement multiple times (with rebind)"""
|
||||
self.cursor.execute("truncate table TestExecuteMany")
|
||||
rows = [ [n] for n in range(235) ]
|
||||
self.cursor.arraysize = 100
|
||||
statement = "insert into TestExecuteMany values (:1)"
|
||||
self.cursor.executemany(statement, rows[:50])
|
||||
self.cursor.executemany(statement, rows[50:])
|
||||
self.connection.commit()
|
||||
self.cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = self.cursor.fetchone()
|
||||
self.failUnlessEqual(count, len(rows))
|
||||
|
||||
def testExecuteManyWithExecption(self):
|
||||
"""test executing a statement multiple times (with exception)"""
|
||||
self.cursor.execute("truncate table TestExecuteMany")
|
||||
rows = [ { "p_Value" : n } for n in (1, 2, 3, 2, 5) ]
|
||||
statement = "insert into TestExecuteMany values (:p_Value)"
|
||||
self.failUnlessRaises(cx_Oracle.DatabaseError, self.cursor.executemany,
|
||||
statement, rows)
|
||||
self.failUnlessEqual(self.cursor.rowcount, 3)
|
||||
|
||||
def testPrepare(self):
|
||||
"""test preparing a statement and executing it multiple times"""
|
||||
self.failUnlessEqual(self.cursor.statement, None)
|
||||
statement = "begin :p_Value := :p_Value + 5; end;"
|
||||
self.cursor.prepare(statement)
|
||||
var = self.cursor.var(cx_Oracle.NUMBER)
|
||||
self.failUnlessEqual(self.cursor.statement, statement)
|
||||
var.setvalue(0, 2)
|
||||
self.cursor.execute(None, p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(), 7)
|
||||
self.cursor.execute(None, p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(), 12)
|
||||
self.cursor.execute("begin :p_Value2 := 3; end;", p_Value2 = var)
|
||||
self.failUnlessEqual(var.getvalue(), 3)
|
||||
|
||||
def testExceptionOnClose(self):
|
||||
"confirm an exception is raised after closing a cursor"
|
||||
self.cursor.close()
|
||||
self.failUnlessRaises(cx_Oracle.InterfaceError, self.cursor.execute,
|
||||
"select 1 from dual")
|
||||
|
||||
def testIterators(self):
|
||||
"""test iterators"""
|
||||
self.cursor.execute("""
|
||||
select IntCol
|
||||
from TestNumbers
|
||||
where IntCol between 1 and 3
|
||||
order by IntCol""")
|
||||
rows = []
|
||||
for row in self.cursor:
|
||||
rows.append(row[0])
|
||||
self.failUnlessEqual(rows, [1, 2, 3])
|
||||
|
||||
def testIteratorsInterrupted(self):
|
||||
"""test iterators (with intermediate execute)"""
|
||||
self.cursor.execute("truncate table TestExecuteMany")
|
||||
self.cursor.execute("""
|
||||
select IntCol
|
||||
from TestNumbers
|
||||
where IntCol between 1 and 3
|
||||
order by IntCol""")
|
||||
testIter = iter(self.cursor)
|
||||
value, = testIter.next()
|
||||
self.cursor.execute("insert into TestExecuteMany values (1)")
|
||||
self.failUnlessRaises(cx_Oracle.InterfaceError, testIter.next)
|
||||
|
||||
def testBindNames(self):
|
||||
"""test that bindnames() works correctly."""
|
||||
self.failUnlessRaises(cx_Oracle.ProgrammingError,
|
||||
self.cursor.bindnames)
|
||||
self.cursor.prepare("begin null; end;")
|
||||
self.failUnlessEqual(self.cursor.bindnames(), [])
|
||||
self.cursor.prepare("begin :retval := :inval + 5; end;")
|
||||
self.failUnlessEqual(self.cursor.bindnames(), ["RETVAL", "INVAL"])
|
||||
self.cursor.prepare("begin :retval := :a * :a + :b * :b; end;")
|
||||
self.failUnlessEqual(self.cursor.bindnames(), ["RETVAL", "A", "B"])
|
||||
self.cursor.prepare("begin :a := :b + :c + :d + :e + :f + :g + " + \
|
||||
":h + :i + :j + :k + :l; end;")
|
||||
self.failUnlessEqual(self.cursor.bindnames(),
|
||||
["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"])
|
||||
|
||||
def testBadPrepare(self):
|
||||
"""test that subsequent executes succeed after bad prepare"""
|
||||
self.failUnlessRaises(cx_Oracle.DatabaseError,
|
||||
self.cursor.execute,
|
||||
"begin raise_application_error(-20000, 'this); end;")
|
||||
self.cursor.execute("begin null; end;")
|
||||
|
||||
def testBadExecute(self):
|
||||
"""test that subsequent fetches fail after bad execute"""
|
||||
self.failUnlessRaises(cx_Oracle.DatabaseError,
|
||||
self.cursor.execute, "select y from dual")
|
||||
self.failUnlessRaises(cx_Oracle.InterfaceError,
|
||||
self.cursor.fetchall)
|
||||
|
||||
def testSetInputSizesMultipleMethod(self):
|
||||
"""test setting input sizes with both positional and keyword args"""
|
||||
self.failUnlessRaises(cx_Oracle.InterfaceError,
|
||||
self.cursor.setinputsizes, 5, x = 5)
|
||||
|
||||
def testSetInputSizesByPosition(self):
|
||||
"""test setting input sizes with positional args"""
|
||||
var = self.cursor.var(cx_Oracle.STRING, 100)
|
||||
self.cursor.setinputsizes(None, 5, None, 10, None, cx_Oracle.NUMBER)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:1 := :2 || to_char(:3) || :4 || to_char(:5) || to_char(:6);
|
||||
end;""", [var, 'test_', 5, '_second_', 3, 7])
|
||||
self.failUnlessEqual(var.getvalue(), "test_5_second_37")
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
"""Module for testing cursor variables."""
|
||||
|
||||
import sys
|
||||
|
||||
class TestCursorVar(BaseTestCase):
|
||||
|
||||
def testBindCursor(self):
|
||||
"test binding in a cursor"
|
||||
cursor = self.connection.cursor()
|
||||
self.failUnlessEqual(cursor.description, None)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
open :p_Cursor for select 1 NumberCol from dual;
|
||||
end;""",
|
||||
p_Cursor = cursor)
|
||||
self.failUnlessEqual(cursor.description,
|
||||
[ ('NUMBERCOL', cx_Oracle.NUMBER, 127, 2, 0, 0, 1) ])
|
||||
self.failUnlessEqual(cursor.fetchall(), [(1.0,)])
|
||||
|
||||
def testBindCursorInPackage(self):
|
||||
"test binding in a cursor from a package"
|
||||
cursor = self.connection.cursor()
|
||||
self.failUnlessEqual(cursor.description, None)
|
||||
self.cursor.callproc("pkg_TestOutCursors.TestOutCursor", (2, cursor))
|
||||
self.failUnlessEqual(cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('STRINGCOL', cx_Oracle.STRING, 20, 20, 0, 0, 0) ])
|
||||
self.failUnlessEqual(cursor.fetchall(),
|
||||
[ (1, 'String 1'), (2, 'String 2') ])
|
||||
|
||||
def testFetchCursor(self):
|
||||
"test fetching a cursor"
|
||||
self.cursor.execute("""
|
||||
select
|
||||
IntCol,
|
||||
cursor(select IntCol + 1 from dual) CursorValue
|
||||
from TestNumbers
|
||||
order by IntCol""")
|
||||
if len(str(sys.maxint)) == 10:
|
||||
size = 4
|
||||
else:
|
||||
size = 8
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('CURSORVALUE', cx_Oracle.CURSOR, -1, size, 0, 0, 1) ])
|
||||
for i in range(1, 11):
|
||||
number, cursor = self.cursor.fetchone()
|
||||
self.failUnlessEqual(number, i)
|
||||
self.failUnlessEqual(cursor.fetchall(), [(i + 1,)])
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
"""Module for testing date/time variables."""
|
||||
|
||||
import sys
|
||||
import time
|
||||
|
||||
class TestDateTimeVar(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
BaseTestCase.setUp(self)
|
||||
self.rawData = []
|
||||
self.dataByKey = {}
|
||||
for i in range(1, 11):
|
||||
timeTuple = (2002, 12, 9, 0, 0, 0, 0, 0, -1)
|
||||
timeInTicks = time.mktime(timeTuple) + i * 86400 + i * 8640
|
||||
dateCol = cx_Oracle.TimestampFromTicks(int(timeInTicks))
|
||||
if i % 2:
|
||||
timeInTicks = time.mktime(timeTuple) + i * 86400 * 2 + \
|
||||
i * 12960
|
||||
nullableCol = cx_Oracle.TimestampFromTicks(int(timeInTicks))
|
||||
else:
|
||||
nullableCol = None
|
||||
tuple = (i, dateCol, nullableCol)
|
||||
self.rawData.append(tuple)
|
||||
self.dataByKey[i] = tuple
|
||||
|
||||
def testBindDate(self):
|
||||
"test binding in a date"
|
||||
self.cursor.execute("""
|
||||
select * from TestDates
|
||||
where DateCol = :p_Value""",
|
||||
p_Value = cx_Oracle.Timestamp(2002, 12, 13, 9, 36, 0))
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[4]])
|
||||
|
||||
if sys.version_info[:2] != (2, 2):
|
||||
def testBindDateTime(self):
|
||||
"test binding in a Python 2.3 and higher date time"
|
||||
import datetime
|
||||
self.cursor.execute("""
|
||||
select * from TestDates
|
||||
where DateCol = :value""",
|
||||
value = datetime.datetime(2002, 12, 13, 9, 36, 0))
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[4]])
|
||||
|
||||
def testBindDateAfterString(self):
|
||||
"test binding in a date after setting input sizes to a string"
|
||||
self.cursor.setinputsizes(p_Value = 15)
|
||||
self.cursor.execute("""
|
||||
select * from TestDates
|
||||
where DateCol = :p_Value""",
|
||||
p_Value = cx_Oracle.Timestamp(2002, 12, 14, 12, 0, 0))
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[5]])
|
||||
|
||||
def testBindNull(self):
|
||||
"test binding in a null"
|
||||
self.cursor.setinputsizes(p_Value = cx_Oracle.DATETIME)
|
||||
self.cursor.execute("""
|
||||
select * from TestDates
|
||||
where DateCol = :p_Value""",
|
||||
p_Value = None)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testBindDateArrayDirect(self):
|
||||
"test binding in a date array"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
array = [r[1] for r in self.rawData]
|
||||
statement = """
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestDateArrays.TestInArrays(
|
||||
:p_StartValue, :p_BaseDate, :p_Array);
|
||||
end;"""
|
||||
self.cursor.execute(statement,
|
||||
p_ReturnValue = returnValue,
|
||||
p_StartValue = 5,
|
||||
p_BaseDate = cx_Oracle.Date(2002, 12, 12),
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 35.5)
|
||||
array = array + array[:5]
|
||||
self.cursor.execute(statement,
|
||||
p_StartValue = 7,
|
||||
p_BaseDate = cx_Oracle.Date(2002, 12, 13),
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 24.0)
|
||||
|
||||
def testBindDateArrayBySizes(self):
|
||||
"test binding in a date array (with setinputsizes)"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
self.cursor.setinputsizes(p_Array = [cx_Oracle.DATETIME, 10])
|
||||
array = [r[1] for r in self.rawData]
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestDateArrays.TestInArrays(
|
||||
:p_StartValue, :p_BaseDate, :p_Array);
|
||||
end;""",
|
||||
p_ReturnValue = returnValue,
|
||||
p_StartValue = 6,
|
||||
p_BaseDate = cx_Oracle.Date(2002, 12, 13),
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 26.5)
|
||||
|
||||
def testBindDateArrayByVar(self):
|
||||
"test binding in a date array (with arrayvar)"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
array = self.cursor.arrayvar(cx_Oracle.DATETIME, 10, 20)
|
||||
array.setvalue(0, [r[1] for r in self.rawData])
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestDateArrays.TestInArrays(
|
||||
:p_StartValue, :p_BaseDate, :p_Array);
|
||||
end;""",
|
||||
p_ReturnValue = returnValue,
|
||||
p_StartValue = 7,
|
||||
p_BaseDate = cx_Oracle.Date(2002, 12, 14),
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 17.5)
|
||||
|
||||
def testBindInOutDateArrayByVar(self):
|
||||
"test binding in/out a date array (with arrayvar)"
|
||||
array = self.cursor.arrayvar(cx_Oracle.DATETIME, 10, 100)
|
||||
originalData = [r[1] for r in self.rawData]
|
||||
array.setvalue(0, originalData)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
pkg_TestDateArrays.TestInOutArrays(:p_NumElems, :p_Array);
|
||||
end;""",
|
||||
p_NumElems = 5,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(array.getvalue(),
|
||||
[ cx_Oracle.Timestamp(2002, 12, 17, 2, 24, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 18, 4, 48, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 19, 7, 12, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 20, 9, 36, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 21, 12, 0, 0) ] + \
|
||||
originalData[5:])
|
||||
|
||||
def testBindOutDateArrayByVar(self):
|
||||
"test binding out a date array (with arrayvar)"
|
||||
array = self.cursor.arrayvar(cx_Oracle.DATETIME, 6, 100)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
pkg_TestDateArrays.TestOutArrays(:p_NumElems, :p_Array);
|
||||
end;""",
|
||||
p_NumElems = 6,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(array.getvalue(),
|
||||
[ cx_Oracle.Timestamp(2002, 12, 13, 4, 48, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 14, 9, 36, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 15, 14, 24, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 16, 19, 12, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 18, 0, 0, 0),
|
||||
cx_Oracle.Timestamp(2002, 12, 19, 4, 48, 0) ])
|
||||
|
||||
def testBindOutSetInputSizes(self):
|
||||
"test binding out with set input sizes defined"
|
||||
vars = self.cursor.setinputsizes(p_Value = cx_Oracle.DATETIME)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := to_date(20021209, 'YYYYMMDD');
|
||||
end;""")
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 9))
|
||||
|
||||
def testBindInOutSetInputSizes(self):
|
||||
"test binding in/out with set input sizes defined"
|
||||
vars = self.cursor.setinputsizes(p_Value = cx_Oracle.DATETIME)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := :p_Value + 5.25;
|
||||
end;""",
|
||||
p_Value = cx_Oracle.Timestamp(2002, 12, 12, 10, 0, 0))
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 17, 16, 0, 0))
|
||||
|
||||
def testBindOutVar(self):
|
||||
"test binding out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.DATETIME)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := to_date('20021231 12:31:00',
|
||||
'YYYYMMDD HH24:MI:SS');
|
||||
end;""",
|
||||
p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 31, 12, 31, 0))
|
||||
|
||||
def testBindInOutVarDirectSet(self):
|
||||
"test binding in/out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.DATETIME)
|
||||
var.setvalue(0, cx_Oracle.Timestamp(2002, 12, 9, 6, 0, 0))
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := :p_Value + 5.25;
|
||||
end;""",
|
||||
p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 14, 12, 0, 0))
|
||||
|
||||
def testCursorDescription(self):
|
||||
"test cursor description is accurate"
|
||||
self.cursor.execute("select * from TestDates")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('DATECOL', cx_Oracle.DATETIME, 23, 7, 0, 0, 0),
|
||||
('NULLABLECOL', cx_Oracle.DATETIME, 23, 7, 0, 0, 1) ])
|
||||
|
||||
def testFetchAll(self):
|
||||
"test that fetching all of the data returns the correct results"
|
||||
self.cursor.execute("select * From TestDates order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchall(), self.rawData)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testFetchMany(self):
|
||||
"test that fetching data in chunks returns the correct results"
|
||||
self.cursor.execute("select * From TestDates order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[0:3])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(2), self.rawData[3:5])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(4), self.rawData[5:9])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[9:])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), [])
|
||||
|
||||
def testFetchOne(self):
|
||||
"test that fetching a single row returns the correct results"
|
||||
self.cursor.execute("""
|
||||
select *
|
||||
from TestDates
|
||||
where IntCol in (3, 4)
|
||||
order by IntCol""")
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[3])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[4])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), None)
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
"""Module for testing LOB (CLOB and BLOB) variables."""
|
||||
|
||||
class TestLobVar(BaseTestCase):
|
||||
|
||||
def __PerformTest(self, type, inputType):
|
||||
longString = ""
|
||||
directType = getattr(cx_Oracle, type)
|
||||
self.cursor.execute("truncate table Test%ss" % type)
|
||||
for i in range(0, 11):
|
||||
if i > 0:
|
||||
char = chr(ord('A') + i - 1)
|
||||
longString += char * 25000
|
||||
elif inputType != directType:
|
||||
continue
|
||||
self.cursor.setinputsizes(longString = inputType)
|
||||
self.cursor.execute("""
|
||||
insert into Test%ss (
|
||||
IntCol,
|
||||
%sCol
|
||||
) values (
|
||||
:integerValue,
|
||||
:longString
|
||||
)""" % (type, type),
|
||||
integerValue = i,
|
||||
longString = longString)
|
||||
self.connection.commit()
|
||||
self.cursor.execute("""
|
||||
select *
|
||||
from Test%ss
|
||||
order by IntCol""" % type)
|
||||
longString = ""
|
||||
for row in self.cursor:
|
||||
integerValue, lob = row
|
||||
if integerValue == 0:
|
||||
self.failUnlessEqual(lob.size(), 0)
|
||||
self.failUnlessEqual(lob.read(), "")
|
||||
else:
|
||||
char = chr(ord('A') + integerValue - 1)
|
||||
prevChar = chr(ord('A') + integerValue - 2)
|
||||
longString += char * 25000
|
||||
self.failUnlessEqual(lob.size(), len(longString))
|
||||
self.failUnlessEqual(lob.read(), longString)
|
||||
self.failUnlessEqual(str(lob), longString)
|
||||
self.failUnlessEqual(lob.read(len(longString)), char)
|
||||
if integerValue > 1:
|
||||
offset = (integerValue - 1) * 25000 - 4
|
||||
string = prevChar * 5 + char * 5
|
||||
self.failUnlessEqual(lob.read(offset, 10), string)
|
||||
|
||||
def __TestTrim(self, type):
|
||||
self.cursor.execute("truncate table Test%ss" % type)
|
||||
self.cursor.setinputsizes(longString = getattr(cx_Oracle, type))
|
||||
self.cursor.execute("""
|
||||
insert into Test%ss (
|
||||
IntCol,
|
||||
%sCol
|
||||
) values (
|
||||
:integerValue,
|
||||
:longString
|
||||
)""" % (type, type),
|
||||
integerValue = 1,
|
||||
longString = "X" * 75000)
|
||||
self.cursor.execute("""
|
||||
select %sCol
|
||||
from Test%ss
|
||||
where IntCol = 1""" % (type, type))
|
||||
lob, = self.cursor.fetchone()
|
||||
self.failUnlessEqual(lob.size(), 75000)
|
||||
lob.trim(25000)
|
||||
self.failUnlessEqual(lob.size(), 25000)
|
||||
lob.trim()
|
||||
self.failUnlessEqual(lob.size(), 0)
|
||||
|
||||
def testBLOBsIndirect(self):
|
||||
"test binding and fetching BLOB data (indirectly)"
|
||||
self.__PerformTest("BLOB", cx_Oracle.LONG_BINARY)
|
||||
|
||||
def testCLOBsIndirect(self):
|
||||
"test binding and fetching CLOB data (indirectly)"
|
||||
self.__PerformTest("CLOB", cx_Oracle.LONG_STRING)
|
||||
|
||||
def testBLOBsDirect(self):
|
||||
"test binding and fetching BLOB data (directly)"
|
||||
self.__PerformTest("BLOB", cx_Oracle.BLOB)
|
||||
|
||||
def testCLOBsDirect(self):
|
||||
"test binding and fetching CLOB data (directly)"
|
||||
self.__PerformTest("CLOB", cx_Oracle.CLOB)
|
||||
|
||||
def testCLOBCursorDescription(self):
|
||||
"test cursor description is accurate for CLOBs"
|
||||
self.cursor.execute("select * from TestCLOBs")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('CLOBCOL', cx_Oracle.CLOB, -1, 4000, 0, 0, 0) ])
|
||||
|
||||
def testBLOBCursorDescription(self):
|
||||
"test cursor description is accurate for BLOBs"
|
||||
self.cursor.execute("select * from TestBLOBs")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('BLOBCOL', cx_Oracle.BLOB, -1, 4000, 0, 0, 0) ])
|
||||
|
||||
def testBLOBTrim(self):
|
||||
"test trimming a BLOB"
|
||||
self.__TestTrim("BLOB")
|
||||
|
||||
def testCLOBTrim(self):
|
||||
"test trimming a CLOB"
|
||||
self.__TestTrim("CLOB")
|
||||
|
||||
def testMultipleFetch(self):
|
||||
"test retrieving data from a CLOB after multiple fetches"
|
||||
self.cursor.arraysize = 1
|
||||
self.cursor.execute("select CLOBCol from TestCLOBS")
|
||||
rows = self.cursor.fetchall()
|
||||
self.failUnlessRaises(cx_Oracle.ProgrammingError, rows[1][0].read)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print "Testing cx_Oracle version", cx_Oracle.version
|
||||
unittest.main()
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
"""Module for testing long and long raw variables."""
|
||||
|
||||
class TestLongVar(BaseTestCase):
|
||||
|
||||
def __PerformTest(self, a_Type, a_InputType):
|
||||
self.cursor.execute("truncate table Test%ss" % a_Type)
|
||||
longString = ""
|
||||
for i in range(1, 11):
|
||||
char = chr(ord('A') + i - 1)
|
||||
longString += char * 25000
|
||||
self.cursor.setinputsizes(p_LongString = a_InputType)
|
||||
self.cursor.execute("""
|
||||
insert into Test%ss (
|
||||
IntCol,
|
||||
%sCol
|
||||
) values (
|
||||
:p_IntegerValue,
|
||||
:p_LongString
|
||||
)""" % (a_Type, a_Type),
|
||||
p_IntegerValue = i,
|
||||
p_LongString = longString)
|
||||
self.connection.commit()
|
||||
self.cursor.setoutputsize(250000, 2)
|
||||
self.cursor.execute("""
|
||||
select *
|
||||
from Test%ss
|
||||
order by IntCol""" % a_Type)
|
||||
longString = ""
|
||||
while 1:
|
||||
row = self.cursor.fetchone()
|
||||
if row is None:
|
||||
break
|
||||
integerValue, fetchedValue = row
|
||||
char = chr(ord('A') + integerValue - 1)
|
||||
longString += char * 25000
|
||||
self.failUnlessEqual(len(fetchedValue), integerValue * 25000)
|
||||
self.failUnlessEqual(fetchedValue, longString)
|
||||
|
||||
def testLongs(self):
|
||||
"test binding and fetching long data"
|
||||
self.__PerformTest("Long", cx_Oracle.LONG_STRING)
|
||||
|
||||
def testLongRaws(self):
|
||||
"test binding and fetching long raw data"
|
||||
self.__PerformTest("LongRaw", cx_Oracle.LONG_BINARY)
|
||||
|
||||
def testLongCursorDescription(self):
|
||||
"test cursor description is accurate for longs"
|
||||
self.cursor.execute("select * from TestLongs")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('LONGCOL', cx_Oracle.LONG_STRING, -1, 0, 0, 0, 0) ])
|
||||
|
||||
def testLongRawCursorDescription(self):
|
||||
"test cursor description is accurate for long raws"
|
||||
self.cursor.execute("select * from TestLongRaws")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('LONGRAWCOL', cx_Oracle.LONG_BINARY, -1, 0, 0, 0, 0) ])
|
||||
|
||||
def testSetOutputSizesAll(self):
|
||||
"test setoutputsizes is valid (all)"
|
||||
self.cursor.setoutputsize(25000)
|
||||
longVar = self.cursor.execute("select * from TestLongRaws")[1]
|
||||
self.failUnlessEqual(longVar.maxlength,
|
||||
25004 * self.connection.maxBytesPerCharacter)
|
||||
|
||||
def testSetOutputSizesWrongColumn(self):
|
||||
"test setoutputsizes is valid (wrong column)"
|
||||
self.cursor.setoutputsize(25000, 1)
|
||||
longVar = self.cursor.execute("select * from TestLongRaws")[1]
|
||||
self.failUnlessEqual(longVar.maxlength,
|
||||
131072 * self.connection.maxBytesPerCharacter)
|
||||
|
||||
def testSetOutputSizesRightColumn(self):
|
||||
"test setoutputsizes is valid (right column)"
|
||||
self.cursor.setoutputsize(35000, 2)
|
||||
longVar = self.cursor.execute("select * from TestLongRaws")[1]
|
||||
self.failUnlessEqual(longVar.maxlength,
|
||||
35004 * self.connection.maxBytesPerCharacter)
|
||||
|
||||
def testArraySizeTooLarge(self):
|
||||
"test array size too large generates an exception"
|
||||
self.cursor.arraysize = 65536
|
||||
self.failUnlessRaises(ValueError, self.cursor.execute,
|
||||
"select * from TestLongRaws")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print "Testing cx_Oracle version", cx_Oracle.version
|
||||
unittest.main()
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
"""Module for testing number variables."""
|
||||
|
||||
import cx_Oracle
|
||||
import sys
|
||||
|
||||
class TestNumberVar(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
BaseTestCase.setUp(self)
|
||||
self.rawData = []
|
||||
self.dataByKey = {}
|
||||
for i in range(1, 11):
|
||||
numberCol = i + i * 0.25
|
||||
floatCol = i + i * 0.75
|
||||
unconstrainedCol = i ** 3 + i * 0.5
|
||||
if i % 2:
|
||||
nullableCol = 143L ** i
|
||||
else:
|
||||
nullableCol = None
|
||||
dataTuple = (i, numberCol, floatCol, unconstrainedCol, nullableCol)
|
||||
self.rawData.append(dataTuple)
|
||||
self.dataByKey[i] = dataTuple
|
||||
|
||||
if sys.version_info[:2] > (2, 3):
|
||||
def testBindDecimal(self):
|
||||
"test binding in a decimal.Decimal"
|
||||
import decimal
|
||||
self.cursor.execute("""
|
||||
select * from TestNumbers
|
||||
where NumberCol - :value1 - :value2 = trunc(NumberCol)""",
|
||||
value1 = decimal.Decimal("0.20"),
|
||||
value2 = decimal.Decimal("0.05"))
|
||||
self.failUnlessEqual(self.cursor.fetchall(),
|
||||
[self.dataByKey[1], self.dataByKey[5], self.dataByKey[9]])
|
||||
|
||||
def testBindFloat(self):
|
||||
"test binding in a float"
|
||||
self.cursor.execute("""
|
||||
select * from TestNumbers
|
||||
where NumberCol - :value = trunc(NumberCol)""",
|
||||
value = 0.25)
|
||||
self.failUnlessEqual(self.cursor.fetchall(),
|
||||
[self.dataByKey[1], self.dataByKey[5], self.dataByKey[9]])
|
||||
|
||||
def testBindInteger(self):
|
||||
"test binding in an integer"
|
||||
self.cursor.execute("""
|
||||
select * from TestNumbers
|
||||
where IntCol = :value""",
|
||||
value = 2)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[2]])
|
||||
|
||||
def testBindSmallLong(self):
|
||||
"test binding in a small long integer"
|
||||
self.cursor.execute("""
|
||||
select * from TestNumbers
|
||||
where IntCol = :value""",
|
||||
value = 3L)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[3]])
|
||||
|
||||
def testBindLargeLong(self):
|
||||
"test binding in a large long integer"
|
||||
valueVar = self.cursor.var(cx_Oracle.NUMBER)
|
||||
valueVar.setvalue(0, 6088343244)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:value := :value + 5;
|
||||
end;""",
|
||||
value = valueVar)
|
||||
value = valueVar.getvalue()
|
||||
self.failUnlessEqual(value, 6088343249)
|
||||
|
||||
def testBindIntegerAfterString(self):
|
||||
"test binding in an number after setting input sizes to a string"
|
||||
self.cursor.setinputsizes(value = 15)
|
||||
self.cursor.execute("""
|
||||
select * from TestNumbers
|
||||
where IntCol = :value""",
|
||||
value = 3)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[3]])
|
||||
|
||||
def testBindNull(self):
|
||||
"test binding in a null"
|
||||
self.cursor.execute("""
|
||||
select * from TestNumbers
|
||||
where IntCol = :value""",
|
||||
value = None)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testBindNumberArrayDirect(self):
|
||||
"test binding in a number array"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
array = [r[1] for r in self.rawData]
|
||||
statement = """
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestNumberArrays.TestInArrays(
|
||||
:p_StartValue, :p_Array);
|
||||
end;"""
|
||||
self.cursor.execute(statement,
|
||||
p_ReturnValue = returnValue,
|
||||
p_StartValue = 5,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 73.75)
|
||||
array = range(15)
|
||||
self.cursor.execute(statement,
|
||||
p_StartValue = 10,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 115.0)
|
||||
|
||||
def testBindNumberArrayBySizes(self):
|
||||
"test binding in a number array (with setinputsizes)"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
self.cursor.setinputsizes(p_Array = [cx_Oracle.NUMBER, 10])
|
||||
array = [r[1] for r in self.rawData]
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestNumberArrays.TestInArrays(
|
||||
:p_StartValue, :p_Array);
|
||||
end;""",
|
||||
p_ReturnValue = returnValue,
|
||||
p_StartValue = 6,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 74.75)
|
||||
|
||||
def testBindNumberArrayByVar(self):
|
||||
"test binding in a number array (with arrayvar)"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
array = self.cursor.arrayvar(cx_Oracle.NUMBER,
|
||||
[r[1] for r in self.rawData])
|
||||
array.setvalue(0, [r[1] for r in self.rawData])
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestNumberArrays.TestInArrays(
|
||||
:p_IntegerValue, :p_Array);
|
||||
end;""",
|
||||
p_ReturnValue = returnValue,
|
||||
p_IntegerValue = 7,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 75.75)
|
||||
|
||||
def testBindZeroLengthNumberArrayByVar(self):
|
||||
"test binding in a zero length number array (with arrayvar)"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
array = self.cursor.arrayvar(cx_Oracle.NUMBER, 0)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestNumberArrays.TestInArrays(
|
||||
:p_IntegerValue, :p_Array);
|
||||
end;""",
|
||||
p_ReturnValue = returnValue,
|
||||
p_IntegerValue = 8,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 8.0)
|
||||
self.failUnlessEqual(array.getvalue(), [])
|
||||
|
||||
def testBindInOutNumberArrayByVar(self):
|
||||
"test binding in/out a number array (with arrayvar)"
|
||||
array = self.cursor.arrayvar(cx_Oracle.NUMBER, 10)
|
||||
originalData = [r[1] for r in self.rawData]
|
||||
expectedData = [originalData[i - 1] * 10 for i in range(1, 6)] + \
|
||||
originalData[5:]
|
||||
array.setvalue(0, originalData)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
pkg_TestNumberArrays.TestInOutArrays(:p_NumElems, :p_Array);
|
||||
end;""",
|
||||
p_NumElems = 5,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(array.getvalue(), expectedData)
|
||||
|
||||
def testBindOutNumberArrayByVar(self):
|
||||
"test binding out a Number array (with arrayvar)"
|
||||
array = self.cursor.arrayvar(cx_Oracle.NUMBER, 6)
|
||||
expectedData = [i * 100 for i in range(1, 7)]
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
pkg_TestNumberArrays.TestOutArrays(:p_NumElems, :p_Array);
|
||||
end;""",
|
||||
p_NumElems = 6,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(array.getvalue(), expectedData)
|
||||
|
||||
def testBindOutSetInputSizes(self):
|
||||
"test binding out with set input sizes defined"
|
||||
vars = self.cursor.setinputsizes(value = cx_Oracle.NUMBER)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:value := 5;
|
||||
end;""")
|
||||
self.failUnlessEqual(vars["value"].getvalue(), 5)
|
||||
|
||||
def testBindInOutSetInputSizes(self):
|
||||
"test binding in/out with set input sizes defined"
|
||||
vars = self.cursor.setinputsizes(value = cx_Oracle.NUMBER)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:value := :value + 5;
|
||||
end;""",
|
||||
value = 1.25)
|
||||
self.failUnlessEqual(vars["value"].getvalue(), 6.25)
|
||||
|
||||
def testBindOutVar(self):
|
||||
"test binding out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.NUMBER)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:value := 5;
|
||||
end;""",
|
||||
value = var)
|
||||
self.failUnlessEqual(var.getvalue(), 5)
|
||||
|
||||
def testBindInOutVarDirectSet(self):
|
||||
"test binding in/out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.NUMBER)
|
||||
var.setvalue(0, 2.25)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:value := :value + 5;
|
||||
end;""",
|
||||
value = var)
|
||||
self.failUnlessEqual(var.getvalue(), 7.25)
|
||||
|
||||
def testCursorDescription(self):
|
||||
"test cursor description is accurate"
|
||||
self.cursor.execute("select * from TestNumbers")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('NUMBERCOL', cx_Oracle.NUMBER, 13, 22, 9, 2, 0),
|
||||
('FLOATCOL', cx_Oracle.NUMBER, 127, 22, 126, -127, 0),
|
||||
('UNCONSTRAINEDCOL', cx_Oracle.NUMBER, 127, 22, 0, -127, 0),
|
||||
('NULLABLECOL', cx_Oracle.NUMBER, 39, 22, 38, 0, 1) ])
|
||||
|
||||
def testFetchAll(self):
|
||||
"test that fetching all of the data returns the correct results"
|
||||
self.cursor.execute("select * From TestNumbers order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchall(), self.rawData)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testFetchMany(self):
|
||||
"test that fetching data in chunks returns the correct results"
|
||||
self.cursor.execute("select * From TestNumbers order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[0:3])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(2), self.rawData[3:5])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(4), self.rawData[5:9])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[9:])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), [])
|
||||
|
||||
def testFetchOne(self):
|
||||
"test that fetching a single row returns the correct results"
|
||||
self.cursor.execute("""
|
||||
select *
|
||||
from TestNumbers
|
||||
where IntCol in (3, 4)
|
||||
order by IntCol""")
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[3])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[4])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), None)
|
||||
|
||||
def testReturnAsLong(self):
|
||||
"test that fetching a long integer returns such in Python"
|
||||
self.cursor.execute("""
|
||||
select NullableCol
|
||||
from TestNumbers
|
||||
where IntCol = 9""")
|
||||
col, = self.cursor.fetchone()
|
||||
self.failUnless(isinstance(col, long), "long integer not returned")
|
||||
|
||||
def testReturnAsFloat(self):
|
||||
"test that fetching a floating point number returns such in Python"
|
||||
self.cursor.execute("select 1.25 from dual")
|
||||
result, = self.cursor.fetchone()
|
||||
self.failUnlessEqual(result, 1.25)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
"""Module for testing object variables."""
|
||||
|
||||
import sys
|
||||
|
||||
class TestObjectVar(BaseTestCase):
|
||||
|
||||
def __TestData(self, expectedIntValue, expectedObjectValue,
|
||||
expectedArrayValue):
|
||||
intValue, objectValue, arrayValue = self.cursor.fetchone()
|
||||
if objectValue is not None:
|
||||
attributeValues = []
|
||||
for attribute in objectValue.type.attributes:
|
||||
value = getattr(objectValue, attribute.name)
|
||||
attributeValues.append(value)
|
||||
objectValue = tuple(attributeValues)
|
||||
self.failUnlessEqual(intValue, expectedIntValue)
|
||||
self.failUnlessEqual(objectValue, expectedObjectValue)
|
||||
self.failUnlessEqual(arrayValue, expectedArrayValue)
|
||||
|
||||
def testFetchData(self):
|
||||
"test fetching objects"
|
||||
self.cursor.execute("""
|
||||
select
|
||||
IntCol,
|
||||
ObjectCol,
|
||||
ArrayCol
|
||||
from TestObjects
|
||||
order by IntCol""")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('OBJECTCOL', cx_Oracle.OBJECT, -1, 2000, 0, 0, 1),
|
||||
('ARRAYCOL', cx_Oracle.OBJECT, -1, 2000, 0, 0, 1) ])
|
||||
self.__TestData(1, (1, 'First row',
|
||||
cx_Oracle.Timestamp(2007, 3, 6, 0, 0, 0)), [5, 10, None, 20])
|
||||
self.__TestData(2, None, [3, None, 9, 12, 15])
|
||||
self.__TestData(3, (3, 'Third row',
|
||||
cx_Oracle.Timestamp(2007, 6, 21, 0, 0, 0)), None)
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
"""Module for testing session pools."""
|
||||
|
||||
import threading
|
||||
|
||||
class TestConnection(TestCase):
|
||||
|
||||
def __ConnectAndDrop(self):
|
||||
"""Connect to the database, perform a query and drop the connection."""
|
||||
connection = self.pool.acquire()
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("select count(*) from TestNumbers")
|
||||
count, = cursor.fetchone()
|
||||
self.failUnlessEqual(count, 10)
|
||||
|
||||
def testPool(self):
|
||||
"""test that the pool is created and has the right attributes"""
|
||||
pool = cx_Oracle.SessionPool(USERNAME, PASSWORD, TNSENTRY, 2, 8, 3)
|
||||
self.failUnlessEqual(pool.username, USERNAME, "user name differs")
|
||||
self.failUnlessEqual(pool.password, PASSWORD, "password differs")
|
||||
self.failUnlessEqual(pool.tnsentry, TNSENTRY, "tnsentry differs")
|
||||
self.failUnlessEqual(pool.max, 8, "max differs")
|
||||
self.failUnlessEqual(pool.min, 2, "min differs")
|
||||
self.failUnlessEqual(pool.increment, 3, "increment differs")
|
||||
self.failUnlessEqual(pool.opened, 2, "opened differs")
|
||||
self.failUnlessEqual(pool.busy, 0, "busy not 0 at start")
|
||||
connection_1 = pool.acquire()
|
||||
self.failUnlessEqual(pool.busy, 1, "busy not 1 after acquire")
|
||||
self.failUnlessEqual(pool.opened, 2, "opened not unchanged (1)")
|
||||
connection_2 = pool.acquire()
|
||||
self.failUnlessEqual(pool.busy, 2, "busy not 2 after acquire")
|
||||
self.failUnlessEqual(pool.opened, 2, "opened not unchanged (2)")
|
||||
connection_3 = pool.acquire()
|
||||
self.failUnlessEqual(pool.busy, 3, "busy not 3 after acquire")
|
||||
self.failUnlessEqual(pool.opened, 5, "opened not changed (3)")
|
||||
pool.release(connection_3)
|
||||
self.failUnlessEqual(pool.busy, 2, "busy not 2 after release")
|
||||
del connection_2
|
||||
self.failUnlessEqual(pool.busy, 1, "busy not 1 after del")
|
||||
|
||||
def testRollbackOnDel(self):
|
||||
"connection rolls back before being destroyed"
|
||||
pool = cx_Oracle.SessionPool(USERNAME, PASSWORD, TNSENTRY, 1, 8, 3)
|
||||
connection = pool.acquire()
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("truncate table TestExecuteMany")
|
||||
cursor.execute("insert into TestExecuteMany values (1)")
|
||||
pool = cx_Oracle.SessionPool(USERNAME, PASSWORD, TNSENTRY, 1, 8, 3)
|
||||
connection = pool.acquire()
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = cursor.fetchone()
|
||||
self.failUnlessEqual(count, 0)
|
||||
|
||||
def testRollbackOnRelease(self):
|
||||
"connection rolls back before released back to the pool"
|
||||
pool = cx_Oracle.SessionPool(USERNAME, PASSWORD, TNSENTRY, 1, 8, 3)
|
||||
connection = pool.acquire()
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("truncate table TestExecuteMany")
|
||||
cursor.execute("insert into TestExecuteMany values (1)")
|
||||
pool.release(connection)
|
||||
pool = cx_Oracle.SessionPool(USERNAME, PASSWORD, TNSENTRY, 1, 8, 3)
|
||||
connection = pool.acquire()
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("select count(*) from TestExecuteMany")
|
||||
count, = cursor.fetchone()
|
||||
self.failUnlessEqual(count, 0)
|
||||
|
||||
def testThreading(self):
|
||||
"""test session pool to database with multiple threads"""
|
||||
self.pool = cx_Oracle.SessionPool(USERNAME, PASSWORD, TNSENTRY, 5, 20,
|
||||
2, threaded = True)
|
||||
threads = []
|
||||
for i in range(20):
|
||||
thread = threading.Thread(None, self.__ConnectAndDrop)
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
|
@ -0,0 +1,411 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
* SetupTest.sql
|
||||
* Creates a user named "cx_Oracle" and populates its schema with the tables
|
||||
* and packages necessary for performing the test suite.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
|
||||
alter session set nls_numeric_characters='.,';
|
||||
|
||||
create user cx_Oracle identified by dev
|
||||
quota unlimited on users
|
||||
default tablespace users;
|
||||
|
||||
grant
|
||||
create session,
|
||||
create table,
|
||||
create procedure,
|
||||
create type
|
||||
to cx_Oracle;
|
||||
|
||||
-- create types
|
||||
create type cx_Oracle.udt_Object as object (
|
||||
NumberValue number,
|
||||
StringValue varchar2(60),
|
||||
DateValue date
|
||||
);
|
||||
/
|
||||
|
||||
create type cx_Oracle.udt_Array as varray(10) of number;
|
||||
/
|
||||
|
||||
-- create tables
|
||||
create table cx_Oracle.TestNumbers (
|
||||
IntCol number(9) not null,
|
||||
NumberCol number(9, 2) not null,
|
||||
FloatCol float not null,
|
||||
UnconstrainedCol number not null,
|
||||
NullableCol number(38)
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestStrings (
|
||||
IntCol number(9) not null,
|
||||
StringCol varchar2(20) not null,
|
||||
RawCol raw(30) not null,
|
||||
FixedCharCol char(40) not null,
|
||||
NullableCol varchar2(50)
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestDates (
|
||||
IntCol number(9) not null,
|
||||
DateCol date not null,
|
||||
NullableCol date
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestCLOBs (
|
||||
IntCol number(9) not null,
|
||||
CLOBCol clob not null
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestBLOBs (
|
||||
IntCol number(9) not null,
|
||||
BLOBCol blob not null
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestLongs (
|
||||
IntCol number(9) not null,
|
||||
LongCol long not null
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestLongRaws (
|
||||
IntCol number(9) not null,
|
||||
LongRawCol long raw not null
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestExecuteMany (
|
||||
IntCol number(9) not null
|
||||
) tablespace users;
|
||||
|
||||
create table cx_Oracle.TestObjects (
|
||||
IntCol number(9) not null,
|
||||
ObjectCol cx_Oracle.udt_Object,
|
||||
ArrayCol cx_Oracle.udt_Array
|
||||
);
|
||||
|
||||
alter table cx_Oracle.testexecutemany
|
||||
add constraint testexecutemany_pk
|
||||
primary key (
|
||||
intcol
|
||||
) using index tablespace users;
|
||||
|
||||
-- populate tables
|
||||
begin
|
||||
for i in 1..10 loop
|
||||
insert into cx_Oracle.TestNumbers
|
||||
values (i, i + i * 0.25, i + i * .75, i * i * i + i *.5,
|
||||
decode(mod(i, 2), 0, null, power(143, i)));
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
declare
|
||||
|
||||
t_RawValue raw(30);
|
||||
|
||||
function ConvertHexDigit(a_Value number) return varchar2 is
|
||||
begin
|
||||
if a_Value between 0 and 9 then
|
||||
return to_char(a_Value);
|
||||
end if;
|
||||
return chr(ascii('A') + a_Value - 10);
|
||||
end;
|
||||
|
||||
function ConvertToHex(a_Value varchar2) return varchar2 is
|
||||
t_HexValue varchar2(60);
|
||||
t_Digit number;
|
||||
begin
|
||||
for i in 1..length(a_Value) loop
|
||||
t_Digit := ascii(substr(a_Value, i, 1));
|
||||
t_HexValue := t_HexValue ||
|
||||
ConvertHexDigit(trunc(t_Digit / 16)) ||
|
||||
ConvertHexDigit(mod(t_Digit, 16));
|
||||
end loop;
|
||||
return t_HexValue;
|
||||
end;
|
||||
|
||||
begin
|
||||
for i in 1..10 loop
|
||||
t_RawValue := hextoraw(ConvertToHex('Raw ' || to_char(i)));
|
||||
insert into cx_Oracle.TestStrings
|
||||
values (i, 'String ' || to_char(i), t_RawValue,
|
||||
'Fixed Char ' || to_char(i),
|
||||
decode(mod(i, 2), 0, null, 'Nullable ' || to_char(i)));
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
begin
|
||||
for i in 1..10 loop
|
||||
insert into cx_Oracle.TestDates
|
||||
values (i, to_date(20021209, 'YYYYMMDD') + i + i * .1,
|
||||
decode(mod(i, 2), 0, null,
|
||||
to_date(20021209, 'YYYYMMDD') + i + i + i * .15));
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
insert into cx_Oracle.TestObjects values (1,
|
||||
cx_Oracle.udt_Object(1, 'First row',
|
||||
to_date(20070306, 'YYYYMMDD')),
|
||||
cx_Oracle.udt_Array(5, 10, null, 20));
|
||||
|
||||
insert into cx_Oracle.TestObjects values (2, null,
|
||||
cx_Oracle.udt_Array(3, null, 9, 12, 15));
|
||||
|
||||
insert into cx_Oracle.TestObjects values (3,
|
||||
cx_Oracle.udt_Object(3, 'Third row',
|
||||
to_date(20070621, 'YYYYMMDD')), null);
|
||||
|
||||
commit;
|
||||
|
||||
-- create procedures for testing callproc()
|
||||
create procedure cx_Oracle.proc_Test (
|
||||
a_InValue varchar2,
|
||||
a_InOutValue in out number,
|
||||
a_OutValue out number
|
||||
) as
|
||||
begin
|
||||
a_InOutValue := a_InOutValue * length(a_InValue);
|
||||
a_OutValue := length(a_InValue);
|
||||
end;
|
||||
/
|
||||
|
||||
create procedure cx_Oracle.proc_TestNoArgs as
|
||||
begin
|
||||
null;
|
||||
end;
|
||||
/
|
||||
|
||||
-- create functions for testing callfunc()
|
||||
create function cx_Oracle.func_Test (
|
||||
a_String varchar2,
|
||||
a_ExtraAmount number
|
||||
) return number as
|
||||
begin
|
||||
return length(a_String) + a_ExtraAmount;
|
||||
end;
|
||||
/
|
||||
|
||||
create function cx_Oracle.func_TestNoArgs
|
||||
return number as
|
||||
begin
|
||||
return 712;
|
||||
end;
|
||||
/
|
||||
|
||||
-- create packages
|
||||
create or replace package cx_Oracle.pkg_TestStringArrays as
|
||||
|
||||
type udt_StringList is table of varchar2(100) index by binary_integer;
|
||||
|
||||
function TestInArrays (
|
||||
a_StartingLength number,
|
||||
a_Array udt_StringList
|
||||
) return number;
|
||||
|
||||
procedure TestInOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array in out nocopy udt_StringList
|
||||
);
|
||||
|
||||
procedure TestOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array out nocopy udt_StringList
|
||||
);
|
||||
|
||||
end;
|
||||
/
|
||||
|
||||
create or replace package body cx_Oracle.pkg_TestStringArrays as
|
||||
|
||||
function TestInArrays (
|
||||
a_StartingLength number,
|
||||
a_Array udt_StringList
|
||||
) return number is
|
||||
t_Length number;
|
||||
begin
|
||||
t_Length := a_StartingLength;
|
||||
for i in 1..a_Array.count loop
|
||||
t_Length := t_Length + length(a_Array(i));
|
||||
end loop;
|
||||
return t_Length;
|
||||
end;
|
||||
|
||||
procedure TestInOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array in out udt_StringList
|
||||
) is
|
||||
begin
|
||||
for i in 1..a_NumElems loop
|
||||
a_Array(i) := 'Converted element # ' ||
|
||||
to_char(i) || ' originally had length ' ||
|
||||
to_char(length(a_Array(i)));
|
||||
end loop;
|
||||
end;
|
||||
|
||||
procedure TestOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array out udt_StringList
|
||||
) is
|
||||
begin
|
||||
for i in 1..a_NumElems loop
|
||||
a_Array(i) := 'Test out element # ' || to_char(i);
|
||||
end loop;
|
||||
end;
|
||||
|
||||
end;
|
||||
/
|
||||
|
||||
create or replace package cx_Oracle.pkg_TestNumberArrays as
|
||||
|
||||
type udt_NumberList is table of number index by binary_integer;
|
||||
|
||||
function TestInArrays (
|
||||
a_StartingValue number,
|
||||
a_Array udt_NumberList
|
||||
) return number;
|
||||
|
||||
procedure TestInOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array in out nocopy udt_NumberList
|
||||
);
|
||||
|
||||
procedure TestOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array out nocopy udt_NumberList
|
||||
);
|
||||
|
||||
end;
|
||||
/
|
||||
|
||||
create or replace package body cx_Oracle.pkg_TestNumberArrays as
|
||||
|
||||
function TestInArrays (
|
||||
a_StartingValue number,
|
||||
a_Array udt_NumberList
|
||||
) return number is
|
||||
t_Value number;
|
||||
begin
|
||||
t_Value := a_StartingValue;
|
||||
for i in 1..a_Array.count loop
|
||||
t_Value := t_Value + a_Array(i);
|
||||
end loop;
|
||||
return t_Value;
|
||||
end;
|
||||
|
||||
procedure TestInOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array in out udt_NumberList
|
||||
) is
|
||||
begin
|
||||
for i in 1..a_NumElems loop
|
||||
a_Array(i) := a_Array(i) * 10;
|
||||
end loop;
|
||||
end;
|
||||
|
||||
procedure TestOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array out udt_NumberList
|
||||
) is
|
||||
begin
|
||||
for i in 1..a_NumElems loop
|
||||
a_Array(i) := i * 100;
|
||||
end loop;
|
||||
end;
|
||||
|
||||
end;
|
||||
/
|
||||
|
||||
create or replace package cx_Oracle.pkg_TestDateArrays as
|
||||
|
||||
type udt_DateList is table of date index by binary_integer;
|
||||
|
||||
function TestInArrays (
|
||||
a_StartingValue number,
|
||||
a_BaseDate date,
|
||||
a_Array udt_DateList
|
||||
) return number;
|
||||
|
||||
procedure TestInOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array in out nocopy udt_DateList
|
||||
);
|
||||
|
||||
procedure TestOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array out nocopy udt_DateList
|
||||
);
|
||||
|
||||
end;
|
||||
/
|
||||
|
||||
create or replace package body cx_Oracle.pkg_TestDateArrays as
|
||||
|
||||
function TestInArrays (
|
||||
a_StartingValue number,
|
||||
a_BaseDate date,
|
||||
a_Array udt_DateList
|
||||
) return number is
|
||||
t_Value number;
|
||||
begin
|
||||
t_Value := a_StartingValue;
|
||||
for i in 1..a_Array.count loop
|
||||
t_Value := t_Value + a_Array(i) - a_BaseDate;
|
||||
end loop;
|
||||
return t_Value;
|
||||
end;
|
||||
|
||||
procedure TestInOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array in out udt_DateList
|
||||
) is
|
||||
begin
|
||||
for i in 1..a_NumElems loop
|
||||
a_Array(i) := a_Array(i) + 7;
|
||||
end loop;
|
||||
end;
|
||||
|
||||
procedure TestOutArrays (
|
||||
a_NumElems number,
|
||||
a_Array out udt_DateList
|
||||
) is
|
||||
begin
|
||||
for i in 1..a_NumElems loop
|
||||
a_Array(i) := to_date(20021212, 'YYYYMMDD') + i * 1.2;
|
||||
end loop;
|
||||
end;
|
||||
|
||||
end;
|
||||
/
|
||||
|
||||
create or replace package cx_Oracle.pkg_TestOutCursors as
|
||||
|
||||
type udt_RefCursor is ref cursor;
|
||||
|
||||
procedure TestOutCursor (
|
||||
a_MaxIntValue number,
|
||||
a_Cursor out udt_RefCursor
|
||||
);
|
||||
|
||||
end;
|
||||
/
|
||||
|
||||
create or replace package body cx_Oracle.pkg_TestOutCursors as
|
||||
|
||||
procedure TestOutCursor (
|
||||
a_MaxIntValue number,
|
||||
a_Cursor out udt_RefCursor
|
||||
) is
|
||||
begin
|
||||
open a_Cursor for
|
||||
select
|
||||
IntCol,
|
||||
StringCol
|
||||
from TestStrings
|
||||
where IntCol <= a_MaxIntValue
|
||||
order by IntCol;
|
||||
end;
|
||||
|
||||
end;
|
||||
/
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
* SetupTest_9i.sql
|
||||
* Additional setup for Oracle 9i databases only.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
|
||||
alter session set nls_numeric_characters='.,';
|
||||
|
||||
create table cx_Oracle.TestTimestamps (
|
||||
IntCol number(9) not null,
|
||||
TimestampCol timestamp not null,
|
||||
NullableCol timestamp
|
||||
) tablespace users;
|
||||
|
||||
begin
|
||||
for i in 1..10 loop
|
||||
insert into cx_Oracle.TestTimestamps
|
||||
values (i, to_timestamp('20021209', 'YYYYMMDD') +
|
||||
to_dsinterval(to_char(i) || ' 00:00:' || to_char(i * 2) || '.' ||
|
||||
to_char(i * 50)),
|
||||
decode(mod(i, 2), 0, to_timestamp(null, 'YYYYMMDD'),
|
||||
to_timestamp('20021209', 'YYYYMMDD') +
|
||||
to_dsinterval(to_char(i + 1) || ' 00:00:' ||
|
||||
to_char(i * 3) || '.' || to_char(i * 125))));
|
||||
end loop;
|
||||
end;
|
||||
/
|
||||
|
||||
commit;
|
||||
|
|
@ -0,0 +1,290 @@
|
|||
"""Module for testing string variables."""
|
||||
|
||||
class TestStringVar(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
BaseTestCase.setUp(self)
|
||||
self.rawData = []
|
||||
self.dataByKey = {}
|
||||
for i in range(1, 11):
|
||||
stringCol = "String %d" % i
|
||||
fixedCharCol = ("Fixed Char %d" % i).ljust(40)
|
||||
rawCol = "Raw %d" % i
|
||||
if i % 2:
|
||||
nullableCol = "Nullable %d" % i
|
||||
else:
|
||||
nullableCol = None
|
||||
dataTuple = (i, stringCol, rawCol, fixedCharCol, nullableCol)
|
||||
self.rawData.append(dataTuple)
|
||||
self.dataByKey[i] = dataTuple
|
||||
|
||||
def testBindString(self):
|
||||
"test binding in a string"
|
||||
self.cursor.execute("""
|
||||
select * from TestStrings
|
||||
where StringCol = :p_Value""",
|
||||
p_Value = "String 5")
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[5]])
|
||||
|
||||
def testBindDifferentVar(self):
|
||||
"test binding a different variable on second execution"
|
||||
retval_1 = self.cursor.var(cx_Oracle.STRING, 30)
|
||||
retval_2 = self.cursor.var(cx_Oracle.STRING, 30)
|
||||
self.cursor.execute("begin :retval := 'Called'; end;",
|
||||
retval = retval_1)
|
||||
self.failUnlessEqual(retval_1.getvalue(), "Called")
|
||||
self.cursor.execute("begin :retval := 'Called'; end;",
|
||||
retval = retval_2)
|
||||
self.failUnlessEqual(retval_2.getvalue(), "Called")
|
||||
|
||||
def testBindStringAfterNumber(self):
|
||||
"test binding in a string after setting input sizes to a number"
|
||||
self.cursor.setinputsizes(p_Value = cx_Oracle.NUMBER)
|
||||
self.cursor.execute("""
|
||||
select * from TestStrings
|
||||
where StringCol = :p_Value""",
|
||||
p_Value = "String 6")
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[6]])
|
||||
|
||||
def testBindStringArrayDirect(self):
|
||||
"test binding in a string array"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
array = [r[1] for r in self.rawData]
|
||||
statement = """
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestStringArrays.TestInArrays(
|
||||
:p_IntegerValue, :p_Array);
|
||||
end;"""
|
||||
self.cursor.execute(statement,
|
||||
p_ReturnValue = returnValue,
|
||||
p_IntegerValue = 5,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 86)
|
||||
array = [ "String - %d" % i for i in range(15) ]
|
||||
self.cursor.execute(statement,
|
||||
p_IntegerValue = 8,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 163)
|
||||
|
||||
def testBindStringArrayBySizes(self):
|
||||
"test binding in a string array (with setinputsizes)"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
self.cursor.setinputsizes(p_Array = [cx_Oracle.STRING, 10])
|
||||
array = [r[1] for r in self.rawData]
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestStringArrays.TestInArrays(
|
||||
:p_IntegerValue, :p_Array);
|
||||
end;""",
|
||||
p_ReturnValue = returnValue,
|
||||
p_IntegerValue = 6,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 87)
|
||||
|
||||
def testBindStringArrayByVar(self):
|
||||
"test binding in a string array (with arrayvar)"
|
||||
returnValue = self.cursor.var(cx_Oracle.NUMBER)
|
||||
array = self.cursor.arrayvar(cx_Oracle.STRING, 10, 20)
|
||||
array.setvalue(0, [r[1] for r in self.rawData])
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_ReturnValue := pkg_TestStringArrays.TestInArrays(
|
||||
:p_IntegerValue, :p_Array);
|
||||
end;""",
|
||||
p_ReturnValue = returnValue,
|
||||
p_IntegerValue = 7,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(returnValue.getvalue(), 88)
|
||||
|
||||
def testBindInOutStringArrayByVar(self):
|
||||
"test binding in/out a string array (with arrayvar)"
|
||||
array = self.cursor.arrayvar(cx_Oracle.STRING, 10, 100)
|
||||
originalData = [r[1] for r in self.rawData]
|
||||
expectedData = ["Converted element # %d originally had length %d" % \
|
||||
(i, len(originalData[i - 1])) for i in range(1, 6)] + \
|
||||
originalData[5:]
|
||||
array.setvalue(0, originalData)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
pkg_TestStringArrays.TestInOutArrays(:p_NumElems, :p_Array);
|
||||
end;""",
|
||||
p_NumElems = 5,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(array.getvalue(), expectedData)
|
||||
|
||||
def testBindOutStringArrayByVar(self):
|
||||
"test binding out a string array (with arrayvar)"
|
||||
array = self.cursor.arrayvar(cx_Oracle.STRING, 6, 100)
|
||||
expectedData = ["Test out element # %d" % i for i in range(1, 7)]
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
pkg_TestStringArrays.TestOutArrays(:p_NumElems, :p_Array);
|
||||
end;""",
|
||||
p_NumElems = 6,
|
||||
p_Array = array)
|
||||
self.failUnlessEqual(array.getvalue(), expectedData)
|
||||
|
||||
def testBindRaw(self):
|
||||
"test binding in a raw"
|
||||
self.cursor.setinputsizes(p_Value = cx_Oracle.BINARY)
|
||||
self.cursor.execute("""
|
||||
select * from TestStrings
|
||||
where RawCol = :p_Value""",
|
||||
p_Value = "Raw 4")
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[4]])
|
||||
|
||||
def testBindAndFetchRowid(self):
|
||||
"test binding (and fetching) a rowid"
|
||||
self.cursor.execute("""
|
||||
select rowid
|
||||
from TestStrings
|
||||
where IntCol = 3""")
|
||||
rowid, = self.cursor.fetchone()
|
||||
self.cursor.execute("""
|
||||
select *
|
||||
from TestStrings
|
||||
where rowid = :p_Value""",
|
||||
p_Value = rowid)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[3]])
|
||||
|
||||
def testBindNull(self):
|
||||
"test binding in a null"
|
||||
self.cursor.execute("""
|
||||
select * from TestStrings
|
||||
where StringCol = :p_Value""",
|
||||
p_Value = None)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testBindOutSetInputSizesByType(self):
|
||||
"test binding out with set input sizes defined (by type)"
|
||||
vars = self.cursor.setinputsizes(p_Value = cx_Oracle.STRING)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := 'TSI';
|
||||
end;""")
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(), "TSI")
|
||||
|
||||
def testBindOutSetInputSizesByInteger(self):
|
||||
"test binding out with set input sizes defined (by integer)"
|
||||
vars = self.cursor.setinputsizes(p_Value = 30)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := 'TSI (I)';
|
||||
end;""")
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(), "TSI (I)")
|
||||
|
||||
def testBindInOutSetInputSizesByType(self):
|
||||
"test binding in/out with set input sizes defined (by type)"
|
||||
vars = self.cursor.setinputsizes(p_Value = cx_Oracle.STRING)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := :p_Value || ' TSI';
|
||||
end;""",
|
||||
p_Value = "InVal")
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(), "InVal TSI")
|
||||
|
||||
def testBindInOutSetInputSizesByInteger(self):
|
||||
"test binding in/out with set input sizes defined (by integer)"
|
||||
vars = self.cursor.setinputsizes(p_Value = 30)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := :p_Value || ' TSI (I)';
|
||||
end;""",
|
||||
p_Value = "InVal")
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(), "InVal TSI (I)")
|
||||
|
||||
def testBindOutVar(self):
|
||||
"test binding out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.STRING)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := 'TSI (VAR)';
|
||||
end;""",
|
||||
p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(), "TSI (VAR)")
|
||||
|
||||
def testBindInOutVarDirectSet(self):
|
||||
"test binding in/out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.STRING)
|
||||
var.setvalue(0, "InVal")
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := :p_Value || ' TSI (VAR)';
|
||||
end;""",
|
||||
p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(), "InVal TSI (VAR)")
|
||||
|
||||
def testBindLongString(self):
|
||||
"test that binding a long string succeeds"
|
||||
self.cursor.execute("""
|
||||
declare
|
||||
t_Temp varchar2(10000);
|
||||
begin
|
||||
t_Temp := :bigString;
|
||||
end;""",
|
||||
bigString = "X" * 10000)
|
||||
|
||||
def testBindLongStringAfterSettingSize(self):
|
||||
"test that setinputsizes() returns a long variable"
|
||||
var = self.cursor.setinputsizes(test = 90000)["test"]
|
||||
self.failUnlessEqual(type(var), cx_Oracle.LONG_STRING)
|
||||
inString = "1234567890" * 9000
|
||||
var.setvalue(0, inString)
|
||||
outString = var.getvalue()
|
||||
self.failUnlessEqual(inString, outString,
|
||||
"output does not match: in was %d, out was %d" % \
|
||||
(len(inString), len(outString)))
|
||||
|
||||
def testStringMaximumReached(self):
|
||||
"test that an error is raised when maximum string length exceeded"
|
||||
var = self.cursor.setinputsizes(test = 100)["test"]
|
||||
inString = "1234567890" * 400
|
||||
var.setvalue(0, inString)
|
||||
outString = var.getvalue()
|
||||
self.failUnlessEqual(inString, outString,
|
||||
"output does not match: in was %d, out was %d" % \
|
||||
(len(inString), len(outString)))
|
||||
badStringSize = 4000 * self.connection.maxBytesPerCharacter + 1
|
||||
inString = "X" * badStringSize
|
||||
self.failUnlessRaises(ValueError, var.setvalue, 0, inString)
|
||||
|
||||
def testCursorDescription(self):
|
||||
"test cursor description is accurate"
|
||||
self.cursor.execute("select * from TestStrings")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('STRINGCOL', cx_Oracle.STRING, 20, 20, 0, 0, 0),
|
||||
('RAWCOL', cx_Oracle.BINARY, 30, 30, 0, 0, 0),
|
||||
('FIXEDCHARCOL', cx_Oracle.FIXED_CHAR, 40, 40, 0, 0, 0),
|
||||
('NULLABLECOL', cx_Oracle.STRING, 50, 50, 0, 0, 1) ])
|
||||
|
||||
def testFetchAll(self):
|
||||
"test that fetching all of the data returns the correct results"
|
||||
self.cursor.execute("select * From TestStrings order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchall(), self.rawData)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testFetchMany(self):
|
||||
"test that fetching data in chunks returns the correct results"
|
||||
self.cursor.execute("select * From TestStrings order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[0:3])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(2), self.rawData[3:5])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(4), self.rawData[5:9])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[9:])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), [])
|
||||
|
||||
def testFetchOne(self):
|
||||
"test that fetching a single row returns the correct results"
|
||||
self.cursor.execute("""
|
||||
select *
|
||||
from TestStrings
|
||||
where IntCol in (3, 4)
|
||||
order by IntCol""")
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[3])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[4])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), None)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print "Testing cx_Oracle version", cx_Oracle.version
|
||||
unittest.main()
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
"""Define test environment."""
|
||||
|
||||
import cx_Oracle
|
||||
import os
|
||||
import unittest
|
||||
|
||||
def GetValue(name, label):
|
||||
value = os.environ.get("CX_ORACLE_" + name)
|
||||
if value is None:
|
||||
value = raw_input(label + ": ")
|
||||
return value
|
||||
|
||||
USERNAME = GetValue("USERNAME", "user name")
|
||||
PASSWORD = GetValue("PASSWORD", "password")
|
||||
TNSENTRY = GetValue("TNSENTRY", "TNS entry")
|
||||
ARRAY_SIZE = int(GetValue("ARRAY_SIZE", "array size"))
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
"""Module for testing timestamp variables."""
|
||||
|
||||
import time
|
||||
|
||||
class TestTimestampVar(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
BaseTestCase.setUp(self)
|
||||
self.rawData = []
|
||||
self.dataByKey = {}
|
||||
for i in range(1, 11):
|
||||
timeTuple = (2002, 12, 9, 0, 0, 0, 0, 0, -1)
|
||||
timeInTicks = time.mktime(timeTuple) + i * 86400
|
||||
dateValue = cx_Oracle.TimestampFromTicks(int(timeInTicks))
|
||||
strValue = str(i * 50)
|
||||
fsecond = int(strValue + "0" * (6 - len(strValue)))
|
||||
dateCol = cx_Oracle.Timestamp(dateValue.year, dateValue.month,
|
||||
dateValue.day, dateValue.hour, dateValue.minute,
|
||||
i * 2, fsecond)
|
||||
if i % 2:
|
||||
timeInTicks = time.mktime(timeTuple) + i * 86400 + 86400
|
||||
dateValue = cx_Oracle.TimestampFromTicks(int(timeInTicks))
|
||||
strValue = str(i * 125)
|
||||
fsecond = int(strValue + "0" * (6 - len(strValue)))
|
||||
nullableCol = cx_Oracle.Timestamp(dateValue.year,
|
||||
dateValue.month, dateValue.day, dateValue.hour,
|
||||
dateValue.minute, i * 3, fsecond)
|
||||
else:
|
||||
nullableCol = None
|
||||
tuple = (i, dateCol, nullableCol)
|
||||
self.rawData.append(tuple)
|
||||
self.dataByKey[i] = tuple
|
||||
|
||||
def testBindTimestamp(self):
|
||||
"test binding in a timestamp"
|
||||
self.cursor.setinputsizes(value = cx_Oracle.TIMESTAMP)
|
||||
self.cursor.execute("""
|
||||
select * from TestTimestamps
|
||||
where TimestampCol = :value""",
|
||||
value = cx_Oracle.Timestamp(2002, 12, 14, 0, 0, 10, 250000))
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [self.dataByKey[5]])
|
||||
|
||||
def testBindNull(self):
|
||||
"test binding in a null"
|
||||
self.cursor.setinputsizes(p_Value = cx_Oracle.TIMESTAMP)
|
||||
self.cursor.execute("""
|
||||
select * from TestTimestamps
|
||||
where TimestampCol = :p_Value""",
|
||||
p_Value = None)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testBindOutSetInputSizes(self):
|
||||
"test binding out with set input sizes defined"
|
||||
vars = self.cursor.setinputsizes(p_Value = cx_Oracle.TIMESTAMP)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := to_timestamp('20021209', 'YYYYMMDD');
|
||||
end;""")
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 9))
|
||||
|
||||
def testBindInOutSetInputSizes(self):
|
||||
"test binding in/out with set input sizes defined"
|
||||
vars = self.cursor.setinputsizes(p_Value = cx_Oracle.TIMESTAMP)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := :p_Value + 5.25;
|
||||
end;""",
|
||||
p_Value = cx_Oracle.Timestamp(2002, 12, 12, 10, 0, 0))
|
||||
self.failUnlessEqual(vars["p_Value"].getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 17, 16, 0, 0))
|
||||
|
||||
def testBindOutVar(self):
|
||||
"test binding out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.TIMESTAMP)
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := to_date('20021231 12:31:00',
|
||||
'YYYYMMDD HH24:MI:SS');
|
||||
end;""",
|
||||
p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 31, 12, 31, 0))
|
||||
|
||||
def testBindInOutVarDirectSet(self):
|
||||
"test binding in/out with cursor.var() method"
|
||||
var = self.cursor.var(cx_Oracle.TIMESTAMP)
|
||||
var.setvalue(0, cx_Oracle.Timestamp(2002, 12, 9, 6, 0, 0))
|
||||
self.cursor.execute("""
|
||||
begin
|
||||
:p_Value := :p_Value + 5.25;
|
||||
end;""",
|
||||
p_Value = var)
|
||||
self.failUnlessEqual(var.getvalue(),
|
||||
cx_Oracle.Timestamp(2002, 12, 14, 12, 0, 0))
|
||||
|
||||
def testCursorDescription(self):
|
||||
"test cursor description is accurate"
|
||||
self.cursor.execute("select * from TestTimestamps")
|
||||
self.failUnlessEqual(self.cursor.description,
|
||||
[ ('INTCOL', cx_Oracle.NUMBER, 10, 22, 9, 0, 0),
|
||||
('TIMESTAMPCOL', cx_Oracle.TIMESTAMP, -1, 11, 0, 0, 0),
|
||||
('NULLABLECOL', cx_Oracle.TIMESTAMP, -1, 11, 0, 0, 1) ])
|
||||
|
||||
def testFetchAll(self):
|
||||
"test that fetching all of the data returns the correct results"
|
||||
self.cursor.execute("select * From TestTimestamps order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchall(), self.rawData)
|
||||
self.failUnlessEqual(self.cursor.fetchall(), [])
|
||||
|
||||
def testFetchMany(self):
|
||||
"test that fetching data in chunks returns the correct results"
|
||||
self.cursor.execute("select * From TestTimestamps order by IntCol")
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[0:3])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(2), self.rawData[3:5])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(4), self.rawData[5:9])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), self.rawData[9:])
|
||||
self.failUnlessEqual(self.cursor.fetchmany(3), [])
|
||||
|
||||
def testFetchOne(self):
|
||||
"test that fetching a single row returns the correct results"
|
||||
self.cursor.execute("""
|
||||
select *
|
||||
from TestTimestamps
|
||||
where IntCol in (3, 4)
|
||||
order by IntCol""")
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[3])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), self.dataByKey[4])
|
||||
self.failUnlessEqual(self.cursor.fetchone(), None)
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
"""Runs all defined unit tests."""
|
||||
|
||||
import cx_Oracle
|
||||
import imp
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
print "Running tests for cx_Oracle version", cx_Oracle.version
|
||||
|
||||
import TestEnv
|
||||
|
||||
moduleNames = [
|
||||
"Connection",
|
||||
"Cursor",
|
||||
"CursorVar",
|
||||
"DateTimeVar",
|
||||
"LobVar",
|
||||
"LongVar",
|
||||
"NumberVar",
|
||||
"ObjectVar",
|
||||
"StringVar"
|
||||
]
|
||||
|
||||
if hasattr(cx_Oracle, "TIMESTAMP"):
|
||||
moduleNames.append("TimestampVar")
|
||||
if hasattr(cx_Oracle, "SessionPool"):
|
||||
moduleNames.append("SessionPool")
|
||||
|
||||
class BaseTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.connection = cx_Oracle.connect(TestEnv.USERNAME,
|
||||
TestEnv.PASSWORD, TestEnv.TNSENTRY)
|
||||
self.cursor = self.connection.cursor()
|
||||
self.cursor.arraysize = TestEnv.ARRAY_SIZE
|
||||
|
||||
def tearDown(self):
|
||||
del self.cursor
|
||||
del self.connection
|
||||
|
||||
|
||||
loader = unittest.TestLoader()
|
||||
runner = unittest.TextTestRunner(verbosity = 2)
|
||||
failures = []
|
||||
for name in moduleNames:
|
||||
fileName = name + ".py"
|
||||
print
|
||||
print "Running tests in", fileName
|
||||
module = imp.new_module(name)
|
||||
setattr(module, "USERNAME", TestEnv.USERNAME)
|
||||
setattr(module, "PASSWORD", TestEnv.PASSWORD)
|
||||
setattr(module, "TNSENTRY", TestEnv.TNSENTRY)
|
||||
setattr(module, "ARRAY_SIZE", TestEnv.ARRAY_SIZE)
|
||||
setattr(module, "TestCase", unittest.TestCase)
|
||||
setattr(module, "BaseTestCase", BaseTestCase)
|
||||
setattr(module, "cx_Oracle", cx_Oracle)
|
||||
execfile(fileName, module.__dict__)
|
||||
tests = loader.loadTestsFromModule(module)
|
||||
result = runner.run(tests)
|
||||
if not result.wasSuccessful():
|
||||
failures.append(name)
|
||||
if failures:
|
||||
print "***** Some tests in the following modules failed. *****"
|
||||
for name in failures:
|
||||
print " %s" % name
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
"""Driver specific portion of the DB API test suite provided by Stuart Bishop
|
||||
available at http://stuartbishop.net/Software/DBAPI20TestSuite/"""
|
||||
|
||||
import cx_Oracle
|
||||
import dbapi20
|
||||
import unittest
|
||||
|
||||
import TestEnv
|
||||
|
||||
class TestSuite(dbapi20.DatabaseAPI20Test):
|
||||
|
||||
connect_args = (TestEnv.USERNAME, TestEnv.PASSWORD, TestEnv.TNSENTRY)
|
||||
driver = cx_Oracle
|
||||
|
||||
# not implemented; use a string instead
|
||||
def test_Binary(self):
|
||||
pass
|
||||
|
||||
# not implemented; see cx_Oracle specific test suite instead
|
||||
def test_callproc(self):
|
||||
pass
|
||||
|
||||
# not implemented; Oracle does not support the concept
|
||||
def test_nextset(self):
|
||||
pass
|
||||
|
||||
# not implemented; see cx_Oracle specific test suite instead
|
||||
def test_setinputsizes(self):
|
||||
pass
|
||||
|
||||
# not implemented; see cx_Oracle specific test suite instead
|
||||
def test_setoutputsize(self):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print "Testing cx_Oracle version", cx_Oracle.version
|
||||
unittest.main()
|
||||
|