diff options
| -rw-r--r-- | ChangeLog | 8 | ||||
| -rw-r--r-- | examples/dt.py | 8 | ||||
| -rw-r--r-- | examples/encoding.py | 32 | ||||
| -rw-r--r-- | examples/tz.py | 2 | ||||
| -rw-r--r-- | psycopg/adapter_mxdatetime.c | 62 | ||||
| -rw-r--r-- | psycopg/typecast.c | 3 | ||||
| -rw-r--r-- | setup.cfg | 2 |
7 files changed, 78 insertions, 39 deletions
@@ -1,6 +1,14 @@ 2005-11-16 Federico Di Gregorio <fog@initd.org> * Preparing release 2.0 beta 6. + + * psycopg/adapter_mxdatetime.c: fixed all problems with mx conversions. + + * psycopg/typecast.c: now the timezone is set correctly even if there + are no microseconds and/or the offset is 0; + + * examples/encoding.py: fixed example by using python utf8 encoding for + the whole file. * lib/__init__.py: very nice hack from Harald Armin Massa to allow py2exe and similar tools to do their work without problems. diff --git a/examples/dt.py b/examples/dt.py index 9933164..76f0c78 100644 --- a/examples/dt.py +++ b/examples/dt.py @@ -23,6 +23,8 @@ import psycopg2 import mx.DateTime import datetime +from psycopg2.extensions import adapt + if len(sys.argv) > 1: DSN = sys.argv[1] @@ -73,9 +75,11 @@ for n, x in zip(mx1[1:], curs.fetchone()): try: # this will work only is psycopg has been compiled with datetime # as the default typecaster for date/time values - s = repr(n) + "\n -> " + repr(x) + "\n -> " + x.isoformat() + s = repr(n) + "\n -> " + str(adapt(n)) + \ + "\n -> " + repr(x) + "\n -> " + x.isoformat() except: - s = repr(n) + "\n -> " + repr(x) + "\n -> " + str(x) + s = repr(n) + "\n -> " + str(adapt(n)) + \ + "\n -> " + repr(x) + "\n -> " + str(x) print s print diff --git a/examples/encoding.py b/examples/encoding.py index 94af0d0..da57bcf 100644 --- a/examples/encoding.py +++ b/examples/encoding.py @@ -1,5 +1,5 @@ -# encoding.py - how to change client encoding (and test it works) -# -*- encoding: latin-1 -*- +# enkoding.py - show to change client enkoding (and test it works) +# -*- encoding: utf8 -*- # # Copyright (C) 2004 Federico Di Gregorio <fog@debian.org> # @@ -33,27 +33,29 @@ print "Initial encoding for this connection is", conn.encoding print "\n** This example is supposed to be run in a UNICODE terminal! **\n" print "Available encodings:" -for a, b in psycopg2.extensions.encodings.items(): +encs = psycopg2.extensions.encodings.items() +encs.sort() +for a, b in encs: print " ", a, "<->", b print "Using STRING typecaster" print "Setting backend encoding to LATIN1 and executing queries:" conn.set_client_encoding('LATIN1') curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", ('�����',)) +curs.execute("SELECT %s::TEXT AS foo", ('àèìòù',)) x = curs.fetchone()[0] print " ->", unicode(x, 'latin-1').encode('utf-8'), type(x) -curs.execute("SELECT %s::TEXT AS foo", (u'�����',)) +curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) x = curs.fetchone()[0] print " ->", unicode(x, 'latin-1').encode('utf-8'), type(x) print "Setting backend encoding to UTF8 and executing queries:" conn.set_client_encoding('UNICODE') curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", (u'�����'.encode('utf-8'),)) +curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),)) x = curs.fetchone()[0] print " ->", x, type(x) -curs.execute("SELECT %s::TEXT AS foo", (u'�����',)) +curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) x = curs.fetchone()[0] print " ->", x, type(x) @@ -63,20 +65,20 @@ psycopg2.extensions.register_type(psycopg2.extensions.UNICODE) print "Setting backend encoding to LATIN1 and executing queries:" conn.set_client_encoding('LATIN1') curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", ('�����',)) +curs.execute("SELECT %s::TEXT AS foo", ('àèìòù',)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) -curs.execute("SELECT %s::TEXT AS foo", (u'�����',)) +curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) print "Setting backend encoding to UTF8 and executing queries:" conn.set_client_encoding('UNICODE') curs = conn.cursor() -curs.execute("SELECT %s::TEXT AS foo", (u'�����'.encode('utf-8'),)) +curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) -curs.execute("SELECT %s::TEXT AS foo", (u'�����',)) +curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) @@ -85,19 +87,19 @@ print "Executing full UNICODE queries" print "Setting backend encoding to LATIN1 and executing queries:" conn.set_client_encoding('LATIN1') curs = conn.cursor() -curs.execute(u"SELECT %s::TEXT AS foo", ('�����',)) +curs.execute(u"SELECT %s::TEXT AS foo", ('àèìòù',)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) -curs.execute(u"SELECT %s::TEXT AS foo", (u'�����',)) +curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù',)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) print "Setting backend encoding to UTF8 and executing queries:" conn.set_client_encoding('UNICODE') curs = conn.cursor() -curs.execute(u"SELECT %s::TEXT AS foo", (u'�����'.encode('utf-8'),)) +curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) -curs.execute(u"SELECT %s::TEXT AS foo", (u'�����',)) +curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù',)) x = curs.fetchone()[0] print " ->", x.encode('utf-8'), ":", type(x) diff --git a/examples/tz.py b/examples/tz.py index 8fe40af..c27bf30 100644 --- a/examples/tz.py +++ b/examples/tz.py @@ -1,5 +1,5 @@ # tz.py - example of datetime objects with time zones -# -*- encoding: latin1 -*- +# -*- encoding: utf8 -*- # # Copyright (C) 2004 Federico Di Gregorio <fog@debian.org> # diff --git a/psycopg/adapter_mxdatetime.c b/psycopg/adapter_mxdatetime.c index dcc24d4..3b23148 100644 --- a/psycopg/adapter_mxdatetime.c +++ b/psycopg/adapter_mxdatetime.c @@ -42,35 +42,61 @@ extern mxDateTimeModule_APIObject *mxDateTimeP; static PyObject * mxdatetime_str(mxdatetimeObject *self) { - PyObject *res = NULL; - char *buffer = NULL; + PyObject *str = NULL, *res = NULL; - /* mxDateTimeObject *obj = (mxDateTimeObject*)self->wrapped; */ - switch (self->type) { - - case PSYCO_MXDATETIME_TIME: - res = PyObject_CallMethod(self->wrapped, "strftime", "s", - "'%H:%M:%S'"); - break; case PSYCO_MXDATETIME_DATE: - res = PyObject_CallMethod(self->wrapped, "strftime", "s", - "'%Y-%m-%d'"); - break; - case PSYCO_MXDATETIME_TIMESTAMP: - res = PyObject_CallMethod(self->wrapped, "strftime", "s", - "'%Y-%m-%dT%H:%M:%S'"); + str = PyObject_Str(self->wrapped); + + /* given the limitation of the mx.DateTime module that uses the same + type for both date and timestamp values we need to do some black + magic and make sure we're not using an adapt()ed timestamp as a + simple date */ + if (strncmp(&(PyString_AsString(str)[11]), "00:00:00.000", 12) == 0) { + PyObject *tmp = + PyString_FromStringAndSize(PyString_AsString(str), 10); + Py_DECREF(str); + str = tmp; + } break; + case PSYCO_MXDATETIME_TIME: case PSYCO_MXDATETIME_INTERVAL: - res = PyObject_CallMethod(self->wrapped, "strftime", "s", - "'%d:%H:%M:%S'"); + str = PyObject_Str(self->wrapped); + + /* given the limitation of the mx.DateTime module that uses the same + type for both time and delta values we need to do some black magic + and make sure we're not using an adapt()ed interval as a simple + time */ + if (PyString_Size(str) > 8 && PyString_AsString(str)[8] == ':') { + mxDateTimeDeltaObject *obj = (mxDateTimeDeltaObject*)self->wrapped; + + char buffer[8]; + int i, j, x; + + double ss = obj->hour*3600.0 + obj->minute*60.0 + obj->second; + int us = (int)((ss - floor(ss))*1000000); + + for (i=1000000, j=0; i > 0 ; i /= 10) { + x = us/i; + us -= x*i; + buffer[j++] = '0'+x; + } + buffer[j] = '\0'; + + res = PyString_FromFormat("'%ld days %d.%s seconds'", + obj->day, (int)round(ss), buffer); + } break; } - if (buffer) free(buffer); + if (str != NULL && res == NULL) { + res = PyString_FromFormat("'%s'", PyString_AsString(str)); + } + Py_XDECREF(str); + return res; } diff --git a/psycopg/typecast.c b/psycopg/typecast.c index 4ea839b..3ab5163 100644 --- a/psycopg/typecast.c +++ b/psycopg/typecast.c @@ -117,8 +117,7 @@ typecast_parse_time(char* s, char** t, int* len, if (*s == '-') tzs = -1; if (cz == 2) *ss = acc; else if (cz == 3) *us = acc; - else if (cz == 4) *tz = acc; - acc = -1; cz++; + acc = -1; cz = 4; break; default: acc = (acc == -1 ? 0 : acc*10) + ((int)*s - (int)'0'); @@ -1,5 +1,5 @@ [build_ext] -define=PSYCOPG_EXTENSIONS,PSYCOPG_DISPLAY_SIZE,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3 +define=PSYCOPG_DEBUG,PSYCOPG_EXTENSIONS,PSYCOPG_DISPLAY_SIZE,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3 # PSYCOPG_EXTENSIONS enables extensions to PEP-249 (you really want this) # PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower) # HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.3 |
