[pywin32-checkins] pywin32/win32/src odbc.cpp,1.21,1.22
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: Roger U. <ru...@us...> - 2008-10-10 23:34:22
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv14248 Modified Files: odbc.cpp Log Message: Correct units for microseconds in datetime fields Add space for terminating null when binding WCHAR output buffer Index: odbc.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/odbc.cpp,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** odbc.cpp 6 Oct 2008 00:40:28 -0000 1.21 --- odbc.cpp 10 Oct 2008 23:34:15 -0000 1.22 *************** *** 627,634 **** { const TIMESTAMP_STRUCT *dt = (const TIMESTAMP_STRUCT *) v; ! return PyObject_CallFunction(datetime_class, "hhhhhhl", dt->year, dt->month, dt->day, ! dt->hour, dt->minute, dt->second, dt->fraction); ! // ??? Not sure what units fraction uses ??? } --- 627,635 ---- { const TIMESTAMP_STRUCT *dt = (const TIMESTAMP_STRUCT *) v; ! // Units for fraction is billionths, python datetime uses microseconds ! unsigned long usec=dt->fraction/1000; ! return PyObject_CallFunction(datetime_class, "hhhhhhk", dt->year, dt->month, dt->day, ! dt->hour, dt->minute, dt->second, usec); } *************** *** 839,842 **** --- 840,861 ---- } + // Class to hold a temporary reference that decrements itself + class TmpPyObject + { + public: + PyObject *tmp; + TmpPyObject() { tmp=NULL; } + TmpPyObject(PyObject *ob) { tmp=ob; } + PyObject * operator= (PyObject *ob){ + Py_XDECREF(tmp); + tmp=ob; + return tmp; + } + + boolean operator== (PyObject *ob) { return tmp==ob; } + operator PyObject *() { return tmp; } + ~TmpPyObject() { Py_XDECREF(tmp); } + }; + static int ibindDate(cursorObject*cur, int column, PyObject *item) { *************** *** 846,850 **** return 0; TIMESTAMP_STRUCT *dt = (TIMESTAMP_STRUCT*) ib->bind_area ; ! ZeroMemory(dt, sizeof(*dt)); // Accept either a PyTime or datetime object if (PyTime_Check(item)){ --- 865,869 ---- return 0; TIMESTAMP_STRUCT *dt = (TIMESTAMP_STRUCT*) ib->bind_area ; ! ZeroMemory(dt, len); // Accept either a PyTime or datetime object if (PyTime_Check(item)){ *************** *** 858,886 **** dt->minute = st.wMinute; dt->second = st.wSecond; ! dt->fraction = st.wMilliseconds; ! // ??? Not sure what units fraction is in ??? } else{ // Python 2.3 doesn't have C Api for datetime ! PyObject *timeseq = PyObject_CallMethod(item, "timetuple", NULL); if (timeseq==NULL) return 0; ! PyObject *timetuple=PySequence_Tuple(timeseq); ! if (timetuple==NULL){ ! Py_DECREF(timeseq); return 0; ! } ! // Last 3 items are ignored. Need to figure out how to get fractional seconds also. PyObject *obwday, *obyday, *obdst; ! if (!PyArg_ParseTuple(timetuple, "hhh|hhhOOO:TIMESTAMP_STRUCT", &dt->year, &dt->month, &dt->day, &dt->hour, &dt->minute, &dt->second, ! &obwday, &obyday, &obdst)){ ! Py_DECREF(timeseq); ! Py_DECREF(timetuple); return 0; } ! Py_DECREF(timeseq); ! Py_DECREF(timetuple); } --- 877,909 ---- dt->minute = st.wMinute; dt->second = st.wSecond; ! // Fraction is in nanoseconds ! dt->fraction = st.wMilliseconds * 1000000; } else{ // Python 2.3 doesn't have C Api for datetime ! TmpPyObject timeseq = PyObject_CallMethod(item, "timetuple", NULL); if (timeseq==NULL) return 0; ! timeseq=PySequence_Tuple(timeseq); ! if (timeseq==NULL) return 0; ! // Last 3 items are ignored. PyObject *obwday, *obyday, *obdst; ! if (!PyArg_ParseTuple(timeseq, "hhh|hhhOOO:TIMESTAMP_STRUCT", &dt->year, &dt->month, &dt->day, &dt->hour, &dt->minute, &dt->second, ! &obwday, &obyday, &obdst)) return 0; + + TmpPyObject usec=PyObject_GetAttrString(item, "microsecond"); + if (usec != NULL){ + dt->fraction=PyLong_AsUnsignedLong(usec); + if (dt->fraction == -1 && PyErr_Occurred()) + return 0; + // Convert to nanoseconds + dt->fraction *= 1000; } ! else ! PyErr_Clear(); } *************** *** 892,896 **** SQL_TIMESTAMP, len, ! 0, ib->bind_area, len, --- 915,919 ---- SQL_TIMESTAMP, len, ! 9, // Decimal digits of precision, appears to be ignored for datetime ib->bind_area, len, *************** *** 1014,1018 **** { const WCHAR *wval = (WCHAR *)PyUnicode_AsUnicode(item); ! Py_ssize_t nchars = PyUnicode_GetSize(item) + 1; Py_ssize_t nbytes = nchars * sizeof(WCHAR); --- 1037,1041 ---- { const WCHAR *wval = (WCHAR *)PyUnicode_AsUnicode(item); ! Py_ssize_t nchars = PyUnicode_GetSize(item); Py_ssize_t nbytes = nchars * sizeof(WCHAR); *************** *** 1021,1028 **** return 0; ! wcsncpy((WCHAR *)ib->bind_area, wval, nchars); /* See above re SQL_VARCHAR */ int sqlType = SQL_WVARCHAR; ! if (nbytes > 255) { ib->sqlBytesAvailable = SQL_LEN_DATA_AT_EXEC(ib->len); --- 1044,1051 ---- return 0; ! memcpy(ib->bind_area, wval, nbytes); /* See above re SQL_VARCHAR */ int sqlType = SQL_WVARCHAR; ! if (nchars > 255) { ib->sqlBytesAvailable = SQL_LEN_DATA_AT_EXEC(ib->len); *************** *** 1042,1046 **** SQL_C_WCHAR, sqlType, ! nbytes, 0, ib->bind_area, --- 1065,1069 ---- SQL_C_WCHAR, sqlType, ! nchars, 0, ib->bind_area, *************** *** 1204,1208 **** unsigned long prec; short nullok; ! short nsize = sizeof(nsize); short scale = 0; SQLDescribeCol( --- 1227,1231 ---- unsigned long prec; short nullok; ! short nsize; short scale = 0; SQLDescribeCol( *************** *** 1213,1217 **** &nsize, &vtype, ! &vsize, &scale, &nullok); --- 1236,1240 ---- &nsize, &vtype, ! &vsize, // This is column size in characters &scale, &nullok); *************** *** 1256,1260 **** dateCopy, SQL_C_TIMESTAMP, ! sizeof(TIMESTAMP_STRUCT), pos, false); --- 1279,1283 ---- dateCopy, SQL_C_TIMESTAMP, ! vsize, pos, false); *************** *** 1285,1288 **** --- 1308,1314 ---- case SQL_VARCHAR: case SQL_WVARCHAR: + bindOutputVar(cur, wcharCopy, SQL_C_WCHAR, (vsize+1)*sizeof(WCHAR), pos, false); + typeOf = DbiString; + break; case SQL_LONGVARCHAR: case SQL_WLONGVARCHAR: |