mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-22 17:06:33 +03:00
Definitely fixed date and time adapting problems (for mx too!)
This commit is contained in:
parent
000aa345ac
commit
996bd07c85
|
@ -2,6 +2,14 @@
|
||||||
|
|
||||||
* Preparing release 2.0 beta 6.
|
* 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
|
* lib/__init__.py: very nice hack from Harald Armin Massa to allow
|
||||||
py2exe and similar tools to do their work without problems.
|
py2exe and similar tools to do their work without problems.
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ import psycopg2
|
||||||
import mx.DateTime
|
import mx.DateTime
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
from psycopg2.extensions import adapt
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
DSN = sys.argv[1]
|
DSN = sys.argv[1]
|
||||||
|
|
||||||
|
@ -73,9 +75,11 @@ for n, x in zip(mx1[1:], curs.fetchone()):
|
||||||
try:
|
try:
|
||||||
# this will work only is psycopg has been compiled with datetime
|
# this will work only is psycopg has been compiled with datetime
|
||||||
# as the default typecaster for date/time values
|
# 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:
|
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 s
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# encoding.py - how to change client encoding (and test it works)
|
# enkoding.py - show to change client enkoding (and test it works)
|
||||||
# -*- encoding: latin-1 -*-
|
# -*- encoding: utf8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (C) 2004 Federico Di Gregorio <fog@debian.org>
|
# 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 "\n** This example is supposed to be run in a UNICODE terminal! **\n"
|
||||||
|
|
||||||
print "Available encodings:"
|
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 " ", a, "<->", b
|
||||||
|
|
||||||
print "Using STRING typecaster"
|
print "Using STRING typecaster"
|
||||||
print "Setting backend encoding to LATIN1 and executing queries:"
|
print "Setting backend encoding to LATIN1 and executing queries:"
|
||||||
conn.set_client_encoding('LATIN1')
|
conn.set_client_encoding('LATIN1')
|
||||||
curs = conn.cursor()
|
curs = conn.cursor()
|
||||||
curs.execute("SELECT %s::TEXT AS foo", ('<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute("SELECT %s::TEXT AS foo", ('àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", unicode(x, 'latin-1').encode('utf-8'), type(x)
|
print " ->", unicode(x, 'latin-1').encode('utf-8'), type(x)
|
||||||
curs.execute("SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", unicode(x, 'latin-1').encode('utf-8'), type(x)
|
print " ->", unicode(x, 'latin-1').encode('utf-8'), type(x)
|
||||||
|
|
||||||
print "Setting backend encoding to UTF8 and executing queries:"
|
print "Setting backend encoding to UTF8 and executing queries:"
|
||||||
conn.set_client_encoding('UNICODE')
|
conn.set_client_encoding('UNICODE')
|
||||||
curs = conn.cursor()
|
curs = conn.cursor()
|
||||||
curs.execute("SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'.encode('utf-8'),))
|
curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x, type(x)
|
print " ->", x, type(x)
|
||||||
curs.execute("SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x, type(x)
|
print " ->", x, type(x)
|
||||||
|
|
||||||
|
@ -63,20 +65,20 @@ psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
|
||||||
print "Setting backend encoding to LATIN1 and executing queries:"
|
print "Setting backend encoding to LATIN1 and executing queries:"
|
||||||
conn.set_client_encoding('LATIN1')
|
conn.set_client_encoding('LATIN1')
|
||||||
curs = conn.cursor()
|
curs = conn.cursor()
|
||||||
curs.execute("SELECT %s::TEXT AS foo", ('<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute("SELECT %s::TEXT AS foo", ('àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
print " ->", x.encode('utf-8'), ":", type(x)
|
||||||
curs.execute("SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
print " ->", x.encode('utf-8'), ":", type(x)
|
||||||
|
|
||||||
print "Setting backend encoding to UTF8 and executing queries:"
|
print "Setting backend encoding to UTF8 and executing queries:"
|
||||||
conn.set_client_encoding('UNICODE')
|
conn.set_client_encoding('UNICODE')
|
||||||
curs = conn.cursor()
|
curs = conn.cursor()
|
||||||
curs.execute("SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'.encode('utf-8'),))
|
curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
print " ->", x.encode('utf-8'), ":", type(x)
|
||||||
curs.execute("SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute("SELECT %s::TEXT AS foo", (u'àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
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:"
|
print "Setting backend encoding to LATIN1 and executing queries:"
|
||||||
conn.set_client_encoding('LATIN1')
|
conn.set_client_encoding('LATIN1')
|
||||||
curs = conn.cursor()
|
curs = conn.cursor()
|
||||||
curs.execute(u"SELECT %s::TEXT AS foo", ('<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute(u"SELECT %s::TEXT AS foo", ('àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
print " ->", x.encode('utf-8'), ":", type(x)
|
||||||
curs.execute(u"SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
print " ->", x.encode('utf-8'), ":", type(x)
|
||||||
|
|
||||||
print "Setting backend encoding to UTF8 and executing queries:"
|
print "Setting backend encoding to UTF8 and executing queries:"
|
||||||
conn.set_client_encoding('UNICODE')
|
conn.set_client_encoding('UNICODE')
|
||||||
curs = conn.cursor()
|
curs = conn.cursor()
|
||||||
curs.execute(u"SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'.encode('utf-8'),))
|
curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù'.encode('utf-8'),))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
print " ->", x.encode('utf-8'), ":", type(x)
|
||||||
curs.execute(u"SELECT %s::TEXT AS foo", (u'<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',))
|
curs.execute(u"SELECT %s::TEXT AS foo", (u'àèìòù',))
|
||||||
x = curs.fetchone()[0]
|
x = curs.fetchone()[0]
|
||||||
print " ->", x.encode('utf-8'), ":", type(x)
|
print " ->", x.encode('utf-8'), ":", type(x)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# tz.py - example of datetime objects with time zones
|
# tz.py - example of datetime objects with time zones
|
||||||
# -*- encoding: latin1 -*-
|
# -*- encoding: utf8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (C) 2004 Federico Di Gregorio <fog@debian.org>
|
# Copyright (C) 2004 Federico Di Gregorio <fog@debian.org>
|
||||||
#
|
#
|
||||||
|
|
|
@ -42,35 +42,61 @@ extern mxDateTimeModule_APIObject *mxDateTimeP;
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mxdatetime_str(mxdatetimeObject *self)
|
mxdatetime_str(mxdatetimeObject *self)
|
||||||
{
|
{
|
||||||
PyObject *res = NULL;
|
PyObject *str = NULL, *res = NULL;
|
||||||
char *buffer = NULL;
|
|
||||||
|
|
||||||
/* mxDateTimeObject *obj = (mxDateTimeObject*)self->wrapped; */
|
|
||||||
|
|
||||||
switch (self->type) {
|
switch (self->type) {
|
||||||
|
|
||||||
case PSYCO_MXDATETIME_TIME:
|
|
||||||
res = PyObject_CallMethod(self->wrapped, "strftime", "s",
|
|
||||||
"'%H:%M:%S'");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PSYCO_MXDATETIME_DATE:
|
case PSYCO_MXDATETIME_DATE:
|
||||||
res = PyObject_CallMethod(self->wrapped, "strftime", "s",
|
|
||||||
"'%Y-%m-%d'");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PSYCO_MXDATETIME_TIMESTAMP:
|
case PSYCO_MXDATETIME_TIMESTAMP:
|
||||||
res = PyObject_CallMethod(self->wrapped, "strftime", "s",
|
str = PyObject_Str(self->wrapped);
|
||||||
"'%Y-%m-%dT%H:%M:%S'");
|
|
||||||
|
/* 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;
|
break;
|
||||||
|
|
||||||
|
case PSYCO_MXDATETIME_TIME:
|
||||||
case PSYCO_MXDATETIME_INTERVAL:
|
case PSYCO_MXDATETIME_INTERVAL:
|
||||||
res = PyObject_CallMethod(self->wrapped, "strftime", "s",
|
str = PyObject_Str(self->wrapped);
|
||||||
"'%d:%H:%M:%S'");
|
|
||||||
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer) free(buffer);
|
if (str != NULL && res == NULL) {
|
||||||
|
res = PyString_FromFormat("'%s'", PyString_AsString(str));
|
||||||
|
}
|
||||||
|
Py_XDECREF(str);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,8 +117,7 @@ typecast_parse_time(char* s, char** t, int* len,
|
||||||
if (*s == '-') tzs = -1;
|
if (*s == '-') tzs = -1;
|
||||||
if (cz == 2) *ss = acc;
|
if (cz == 2) *ss = acc;
|
||||||
else if (cz == 3) *us = acc;
|
else if (cz == 3) *us = acc;
|
||||||
else if (cz == 4) *tz = acc;
|
acc = -1; cz = 4;
|
||||||
acc = -1; cz++;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
acc = (acc == -1 ? 0 : acc*10) + ((int)*s - (int)'0');
|
acc = (acc == -1 ? 0 : acc*10) + ((int)*s - (int)'0');
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[build_ext]
|
[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_EXTENSIONS enables extensions to PEP-249 (you really want this)
|
||||||
# PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower)
|
# PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower)
|
||||||
# HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.3
|
# HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.3
|
||||||
|
|
Loading…
Reference in New Issue
Block a user