Fixed support for native doubles and floats in Oracle 10g; added new type
NATIVE_FLOAT to allow specification of a variable of that specific type where desired. Thanks to D.R. Boxhoorn for pointing out the fact that this was not working properly when the arraysize was anything other than 1.
This commit is contained in:
parent
5025b4eb22
commit
21f1839d1a
99
NumberVar.c
99
NumberVar.c
|
@ -10,7 +10,7 @@ static const char gc_NumberFormat[63] =
|
|||
"999999999999999999999999999999999999999999999999999999999999999";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Number type
|
||||
// Number types
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
|
@ -18,6 +18,14 @@ typedef struct {
|
|||
} udt_NumberVar;
|
||||
|
||||
|
||||
#ifdef SQLT_BFLOAT
|
||||
typedef struct {
|
||||
Variable_HEAD
|
||||
double *data;
|
||||
} udt_NativeFloatVar;
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Declaration of number variable functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -25,8 +33,8 @@ 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);
|
||||
static int NativeFloatVar_SetValue(udt_NativeFloatVar*, unsigned, PyObject*);
|
||||
static PyObject *NativeFloatVar_GetValue(udt_NativeFloatVar*, unsigned);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -59,6 +67,34 @@ static PyTypeObject g_NumberVarType = {
|
|||
};
|
||||
|
||||
|
||||
#ifdef SQLT_BFLOAT
|
||||
static PyTypeObject g_NativeFloatVarType = {
|
||||
PyObject_HEAD_INIT(NULL)
|
||||
0, // ob_size
|
||||
"cx_Oracle.NATIVE_FLOAT", // tp_name
|
||||
sizeof(udt_NativeFloatVar), // 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
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// variable type declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -87,9 +123,9 @@ static udt_VariableType vt_NativeFloat = {
|
|||
(PreDefineProc) NULL,
|
||||
(PostDefineProc) NULL,
|
||||
(IsNullProc) NULL,
|
||||
(SetValueProc) NumberVar_SetValueAsDouble,
|
||||
(GetValueProc) NumberVar_GetValueAsDouble,
|
||||
&g_NumberVarType, // Python type
|
||||
(SetValueProc) NativeFloatVar_SetValue,
|
||||
(GetValueProc) NativeFloatVar_GetValue,
|
||||
&g_NativeFloatVarType, // Python type
|
||||
SQLT_BDOUBLE, // Oracle type
|
||||
SQLCS_IMPLICIT, // charset form
|
||||
sizeof(double), // element length
|
||||
|
@ -415,30 +451,6 @@ static int NumberVar_SetValue(
|
|||
}
|
||||
|
||||
|
||||
#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.
|
||||
|
@ -492,17 +504,32 @@ static PyObject *NumberVar_GetValue(
|
|||
|
||||
#ifdef SQLT_BFLOAT
|
||||
//-----------------------------------------------------------------------------
|
||||
// NumberVar_GetValueAsDouble()
|
||||
// NativeFloatVar_GetValue()
|
||||
// Returns the value stored at the given array position as a float.
|
||||
//-----------------------------------------------------------------------------
|
||||
static PyObject *NumberVar_GetValueAsDouble(
|
||||
udt_NumberVar *var, // variable to determine value for
|
||||
static PyObject *NativeFloatVar_GetValue(
|
||||
udt_NativeFloatVar *var, // variable to determine value for
|
||||
unsigned pos) // array position
|
||||
{
|
||||
double *doublePtr;
|
||||
return PyFloat_FromDouble(var->data[pos]);
|
||||
}
|
||||
|
||||
doublePtr = (double*) &var->data[pos];
|
||||
return PyFloat_FromDouble(*doublePtr);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// NativeFloatVar_SetValue()
|
||||
// Set the value of the variable which should be a native double.
|
||||
//-----------------------------------------------------------------------------
|
||||
static int NativeFloatVar_SetValue(
|
||||
udt_NativeFloatVar *var, // variable to set value for
|
||||
unsigned pos, // array position to set
|
||||
PyObject *value) // value to set
|
||||
{
|
||||
if (!PyFloat_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expecting float");
|
||||
return -1;
|
||||
}
|
||||
var->data[pos] = PyFloat_AS_DOUBLE(value);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -282,6 +282,9 @@ static int Variable_Check(
|
|||
object->ob_type == &g_BinaryVarType
|
||||
#ifdef ORACLE_9I
|
||||
|| object->ob_type == &g_TimestampVarType
|
||||
#endif
|
||||
#ifdef SQLT_BFLOAT
|
||||
|| object->ob_type == &g_NativeFloatVarType
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
@ -350,6 +353,10 @@ static udt_VariableType *Variable_TypeByPythonType(
|
|||
#endif
|
||||
if (type == (PyObject*) &g_CursorVarType)
|
||||
return &vt_Cursor;
|
||||
#ifdef SQLT_BFLOAT
|
||||
if (type == (PyObject*) &g_NativeFloatVarType)
|
||||
return &vt_NativeFloat;
|
||||
#endif
|
||||
|
||||
PyErr_SetString(g_NotSupportedErrorException,
|
||||
"Variable_TypeByPythonType(): unhandled data type");
|
||||
|
|
|
@ -355,6 +355,10 @@ void initcx_Oracle(void)
|
|||
return;
|
||||
if (PyType_Ready(&g_ExternalObjectVarType) < 0)
|
||||
return;
|
||||
#ifdef SQLT_BFLOAT
|
||||
if (PyType_Ready(&g_NativeFloatVarType) < 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// initialize module and retrieve the dictionary
|
||||
module = Py_InitModule("cx_Oracle", g_ModuleMethods);
|
||||
|
@ -434,6 +438,9 @@ void initcx_Oracle(void)
|
|||
#ifdef ORACLE_9I
|
||||
ADD_TYPE_OBJECT("TIMESTAMP", &g_TimestampVarType)
|
||||
#endif
|
||||
#ifdef SQLT_BFLOAT
|
||||
ADD_TYPE_OBJECT("NATIVE_FLOAT", &g_NativeFloatVarType)
|
||||
#endif
|
||||
|
||||
// create constants required by Python DB API 2.0
|
||||
if (PyModule_AddStringConstant(module, "apilevel", "2.0") < 0)
|
||||
|
|
|
@ -258,6 +258,13 @@ information on the Python database API specification.
|
|||
\strong{NOTE:} This attribute is an extension to the DB API definition.
|
||||
\end{datadesc}
|
||||
|
||||
\begin{datadesc}{NATIVE_FLOAT}
|
||||
This type object is used to describe columns in a database that are of type
|
||||
binary_double or binary_float and is only available in Oracle 10g.
|
||||
|
||||
\strong{NOTE:} This attribute is an extension to the DB API definition.
|
||||
\end{datadesc}
|
||||
|
||||
\begin{datadesc}{NCLOB}
|
||||
This type object is used to describe columns in a database that are NCLOBs.
|
||||
|
||||
|
|
Loading…
Reference in New Issue