Use dpiData_*() functions to simplify setting data; correct handling of

timestamp with time zone attributes.
This commit is contained in:
Anthony Tuininga 2017-07-21 15:35:49 -06:00
parent df102db935
commit 1eba9d55be
3 changed files with 39 additions and 29 deletions

View File

@ -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");

View File

@ -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()

View File

@ -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'),