Use dpiData_*() functions to simplify setting data; correct handling of
timestamp with time zone attributes.
This commit is contained in:
parent
df102db935
commit
1eba9d55be
46
src/Object.c
46
src/Object.c
|
@ -189,9 +189,7 @@ static int Object_ConvertFromPython(udt_Object *obj, PyObject *value,
|
|||
dpiNativeTypeNum *nativeTypeNum, dpiData *data, udt_Buffer *buffer)
|
||||
{
|
||||
PyObject *textValue, *valueType;
|
||||
dpiTimestamp *timestamp;
|
||||
udt_Object *otherObj;
|
||||
dpiBytes *bytes;
|
||||
udt_LOB *lob;
|
||||
int status;
|
||||
|
||||
|
@ -221,51 +219,45 @@ static int Object_ConvertFromPython(udt_Object *obj, PyObject *value,
|
|||
return -1;
|
||||
}
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_BYTES;
|
||||
bytes = &data->value.asBytes;
|
||||
bytes->ptr = (char*) buffer->ptr;
|
||||
bytes->length = buffer->size;
|
||||
dpiData_setBytes(data, (char*) buffer->ptr, buffer->size);
|
||||
} else if (PyBool_Check(value)) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_BOOLEAN;
|
||||
data->value.asBoolean = (value == Py_True);
|
||||
dpiData_setBool(data, (value == Py_True));
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
|
||||
} else if (PyInt_Check(value)) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_INT64;
|
||||
data->value.asInt64 = PyInt_AS_LONG(value);
|
||||
dpiData_setInt64(data, PyInt_AS_LONG(value));
|
||||
#endif
|
||||
} else if (PyLong_Check(value)) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_INT64;
|
||||
data->value.asInt64 = PyLong_AsLong(value);
|
||||
dpiData_setInt64(data, PyLong_AsLong(value));
|
||||
if (PyErr_Occurred())
|
||||
return -1;
|
||||
} else if (PyFloat_Check(value)) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_DOUBLE;
|
||||
data->value.asDouble = PyFloat_AS_DOUBLE(value);
|
||||
} else if (PyDateTime_Check(value) || PyDate_Check(value)) {
|
||||
dpiData_setDouble(data, PyFloat_AS_DOUBLE(value));
|
||||
} else if (PyDateTime_Check(value)) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_TIMESTAMP;
|
||||
timestamp = &data->value.asTimestamp;
|
||||
timestamp->year = PyDateTime_GET_YEAR(value);
|
||||
timestamp->month = PyDateTime_GET_MONTH(value);
|
||||
timestamp->day = PyDateTime_GET_DAY(value);
|
||||
if (PyDateTime_Check(value)) {
|
||||
timestamp->hour = PyDateTime_DATE_GET_HOUR(value);
|
||||
timestamp->minute = PyDateTime_DATE_GET_MINUTE(value);
|
||||
timestamp->second = PyDateTime_DATE_GET_SECOND(value);
|
||||
timestamp->fsecond = PyDateTime_DATE_GET_MICROSECOND(value) * 1000;
|
||||
} else {
|
||||
timestamp->hour = 0;
|
||||
timestamp->minute = 0;
|
||||
timestamp->second = 0;
|
||||
timestamp->fsecond = 0;
|
||||
}
|
||||
dpiData_setTimestamp(data, 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, 0, 0);
|
||||
} else if (PyDate_Check(value)) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_TIMESTAMP;
|
||||
dpiData_setTimestamp(data, PyDateTime_GET_YEAR(value),
|
||||
PyDateTime_GET_MONTH(value), PyDateTime_GET_DAY(value),
|
||||
0, 0, 0, 0, 0, 0);
|
||||
} else if (Py_TYPE(value) == &g_ObjectType) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_OBJECT;
|
||||
otherObj = (udt_Object*) value;
|
||||
data->value.asObject = otherObj->handle;
|
||||
dpiData_setObject(data, otherObj->handle);
|
||||
} else if (Py_TYPE(value) == &g_LOBType) {
|
||||
*nativeTypeNum = DPI_NATIVE_TYPE_LOB;
|
||||
lob = (udt_LOB*) value;
|
||||
data->value.asLOB = lob->handle;
|
||||
dpiData_setLOB(data, lob->handle);
|
||||
} else {
|
||||
PyErr_Format(g_NotSupportedErrorException,
|
||||
"Object_ConvertFromPython(): unhandled value type");
|
||||
|
|
|
@ -125,6 +125,8 @@ class TestObjectVar(BaseTestCase):
|
|||
'N First ', 2, 5, 12.5, 25.25, 50.125,
|
||||
cx_Oracle.Timestamp(2007, 3, 6, 0, 0, 0),
|
||||
cx_Oracle.Timestamp(2008, 9, 12, 16, 40),
|
||||
cx_Oracle.Timestamp(2009, 10, 13, 17, 50),
|
||||
cx_Oracle.Timestamp(2010, 11, 14, 18, 55),
|
||||
'Short CLOB value', 'Short NCLOB Value', b'Short BLOB value',
|
||||
(11, 'Sub object 1'),
|
||||
[(5, 'first element'), (6, 'second element')]),
|
||||
|
@ -134,6 +136,8 @@ class TestObjectVar(BaseTestCase):
|
|||
'N Third ', 4, 10, 43.25, 86.5, 192.125,
|
||||
cx_Oracle.Timestamp(2007, 6, 21, 0, 0, 0),
|
||||
cx_Oracle.Timestamp(2007, 12, 13, 7, 30, 45),
|
||||
cx_Oracle.Timestamp(2017, 6, 21, 23, 18, 45),
|
||||
cx_Oracle.Timestamp(2017, 7, 21, 8, 27, 13),
|
||||
'Another short CLOB value', 'Another short NCLOB Value',
|
||||
b'Yet another short BLOB value',
|
||||
(13, 'Sub object 3'),
|
||||
|
@ -150,8 +154,8 @@ class TestObjectVar(BaseTestCase):
|
|||
"FIXEDCHARVALUE", "NSTRINGVALUE", "NFIXEDCHARVALUE",
|
||||
"INTVALUE", "SMALLINTVALUE", "FLOATVALUE", "BINARYFLOATVALUE",
|
||||
"BINARYDOUBLEVALUE", "DATEVALUE", "TIMESTAMPVALUE",
|
||||
"CLOBVALUE", "NCLOBVALUE", "BLOBVALUE", "SUBOBJECTVALUE",
|
||||
"SUBOBJECTARRAY"]
|
||||
"TIMESTAMPTZVALUE", "TIMESTAMPLTZVALUE", "CLOBVALUE",
|
||||
"NCLOBVALUE", "BLOBVALUE", "SUBOBJECTVALUE", "SUBOBJECTARRAY"]
|
||||
actualAttributeNames = [a.name for a in typeObj.attributes]
|
||||
self.assertEqual(actualAttributeNames, expectedAttributeNames)
|
||||
typeObj = self.connection.gettype("UDT_OBJECTARRAY")
|
||||
|
@ -201,6 +205,8 @@ class TestObjectVar(BaseTestCase):
|
|||
obj.FLOATVALUE = 23.75
|
||||
obj.DATEVALUE = datetime.date(2017, 5, 9)
|
||||
obj.TIMESTAMPVALUE = datetime.datetime(2017, 5, 9, 9, 41, 13)
|
||||
obj.TIMESTAMPTZVALUE = datetime.datetime(1986, 8, 2, 15, 27, 38)
|
||||
obj.TIMESTAMPLTZVALUE = datetime.datetime(1999, 11, 12, 23, 5, 2)
|
||||
obj.BINARYFLOATVALUE = 14.25
|
||||
obj.BINARYDOUBLEVALUE = 29.1625
|
||||
obj.CLOBVALUE = clob
|
||||
|
@ -221,6 +227,8 @@ class TestObjectVar(BaseTestCase):
|
|||
'Fixed N ', 27, 13, 23.75, 14.25, 29.1625,
|
||||
cx_Oracle.Timestamp(2017, 5, 9, 0, 0, 0),
|
||||
cx_Oracle.Timestamp(2017, 5, 9, 9, 41, 13),
|
||||
cx_Oracle.Timestamp(1986, 8, 2, 15, 27, 38),
|
||||
cx_Oracle.Timestamp(1999, 11, 12, 23, 5, 2),
|
||||
'A short CLOB', 'A short NCLOB', b'A short BLOB',
|
||||
(23, 'Substring value'), None), None)
|
||||
self.connection.rollback()
|
||||
|
|
|
@ -71,6 +71,8 @@ create type &main_user..udt_Object as object (
|
|||
BinaryDoubleValue binary_double,
|
||||
DateValue date,
|
||||
TimestampValue timestamp,
|
||||
TimestampTZValue timestamp with time zone,
|
||||
TimestampLTZValue timestamp with local time zone,
|
||||
CLOBValue clob,
|
||||
NCLOBValue nclob,
|
||||
BLOBValue blob,
|
||||
|
@ -298,6 +300,10 @@ insert into &main_user..TestObjects values (1,
|
|||
&main_user..udt_Object(1, 'First row', 'First', 'N First Row', 'N First',
|
||||
2, 5, 12.5, 25.25, 50.125, to_date(20070306, 'YYYYMMDD'),
|
||||
to_timestamp('20080912 16:40:00', 'YYYYMMDD HH24:MI:SS'),
|
||||
to_timestamp_tz('20091013 17:50:00 00:00',
|
||||
'YYYYMMDD HH24:MI:SS TZH:TZM'),
|
||||
to_timestamp_tz('20101114 18:55:00 00:00',
|
||||
'YYYYMMDD HH24:MI:SS TZH:TZM'),
|
||||
'Short CLOB value', 'Short NCLOB Value',
|
||||
utl_raw.cast_to_raw('Short BLOB value'),
|
||||
&main_user..udt_SubObject(11, 'Sub object 1'),
|
||||
|
@ -313,6 +319,10 @@ insert into &main_user..TestObjects values (3,
|
|||
&main_user..udt_Object(3, 'Third row', 'Third', 'N Third Row', 'N Third',
|
||||
4, 10, 43.25, 86.5, 192.125, to_date(20070621, 'YYYYMMDD'),
|
||||
to_timestamp('20071213 07:30:45', 'YYYYMMDD HH24:MI:SS'),
|
||||
to_timestamp_tz('20170621 23:18:45 00:00',
|
||||
'YYYYMMDD HH24:MI:SS TZH:TZM'),
|
||||
to_timestamp_tz('20170721 08:27:13 00:00',
|
||||
'YYYYMMDD HH24:MI:SS TZH:TZM'),
|
||||
'Another short CLOB value', 'Another short NCLOB Value',
|
||||
utl_raw.cast_to_raw('Yet another short BLOB value'),
|
||||
&main_user..udt_SubObject(13, 'Sub object 3'),
|
||||
|
|
Loading…
Reference in New Issue