[Zope3-checkins] CVS: zopeproducts/pypgsqlda - adapter.py:1.7
Christian 'Tiran' Heimes
heimes@faho.rwth-aachen.de
Fri, 21 Mar 2003 17:17:02 -0500
Update of /cvs-repository/zopeproducts/pypgsqlda
In directory cvs.zope.org:/tmp/cvs-serv29731/zopeproducts/pypgsqlda
Modified Files:
adapter.py
Log Message:
backport from branch with datetime converter added
now all types are basicly supported so you can use this adapter for testing
WARNING: timestamptz and interval have bugs due problems with mxDateTime and/or pyPgSQL. See code for more informations
=== zopeproducts/pypgsqlda/adapter.py 1.6 => 1.7 ===
--- zopeproducts/pypgsqlda/adapter.py:1.6 Wed Mar 19 17:18:50 2003
+++ zopeproducts/pypgsqlda/adapter.py Fri Mar 21 17:17:01 2003
@@ -22,6 +22,10 @@
import string
+import datetime
+from zope.app import datetimeutils
+
+
class pypgsqlAdapter(ZopeDatabaseAdapter):
"""A pypgsql adapter for Zope3"""
@@ -53,10 +57,17 @@
# helpers
-def isPgArray(data):
+def _isPgArray(data):
"""Check if data is a postgres array"""
return isinstance(data, PgArray)
+def _sec2my(sec):
+ """ Return second and mikro for a float second"""
+ # from psycopgda
+ sec, my = divmod(sec, 1.0)
+ my = round(my * 1000000)
+ return (sec, my)
+
# Converters
def convertINet(data):
@@ -75,11 +86,7 @@
else:
addr.append(32)
return (tuple([string.atoi(a) for a in addr[0].split('.')]), addr[1])
-
-def convertInterval(data):
- """Returns the length of the interval in seconds."""
- return data.seconds
-
+
def convertBool(data):
"""Returns a boolean as normal python boolean."""
return not not data
@@ -180,15 +187,63 @@
"""
return tuple([convertPoint(p) for p in groupPointList.findall(unicode(data))])
+def convertTime(data):
+ """Converts a mxDateTime.time object to a datetime.time object"""
+ # XXX: day?
+ if not data: return None
+ d, h, min, sec = data.tuple()
+ sec, my = _sec2my(sec)
+ return datetime.time(h, min, sec, my)
+
+def convertTimestamp(data):
+ """Converts a mxDateTime.datetime object to a datetime.datetime object"""
+ if not data: return None
+ y, m, d, h, min, sec, dayOfWeek, dayOfYear, dst = data.tuple()
+ sec, my = _sec2my(sec)
+ return datetime.datetime(y, m, d, h, min, sec, my)
+
+def convertTimestampTZ(data):
+ """Converts a mxDateTime.time object to a datetime.time object with timezone
+
+ XXX BUG BUG BUG
+ Warning: mxDateTime.DateTime returns wrong timezone
+ I got only CET (my local tz) as tz
+ XXX BUG BUG BUG
+ """
+ if not data: return None
+ y, m, d, h, min, sec, dayOfWeek, dayOfYear, dst = data.tuple()
+ sec, my = _sec2my(sec)
+ # time zone offset in minutes
+ tzoffset = data.gmtoffset().minutes
+ if tzoffset: tz = datetimeutils.tzinfo(tzoffset)
+ else: tz = datetimeutils.tzinfo(0)
+ return datetime.datetime(y, m, d, h, min, sec, my, tz)
+
+def convertInterval(data):
+ """Converts a mxDateTime.DateTimeDelta object to a datetime.timedelta object
+
+ XXX BUG BUG BUG
+ Warning: mxDateTime.DateTimeDelta returns wrong data for large intervals
+ for example 20 years are 20 days!
+ XXX BUG BUG BUG
+ """
+ days, hours, min, sec = data.tuple()
+ sec, my = _sec2my(sec)
+ return datetime.timedelta(days=days, hours=hours, minutes=min,
+ seconds=sec, microseconds=my)
+
def debug(data):
"""XXX used for debugging"""
import pdb;
pdb.set_trace()
print data
+ return data
+# http://www.cs.nott.ac.uk/TSG/manuals/databases/postgres/user/x774.htm#AEN1354
+# http://www.postgresql.org/docs/view.php?version=7.2&idoc=0&file=datatype.html
# types from pypgsql/libpqmodule.c
converter_mapping = {
- 'abstime' : debug, # PG_ABSTIME time
+ 'abstime' : unicode, # PG_ABSTIME XXXtime (obsolet)
'aclitem' : unicode, # PG_ACLITEM S unicode XXX PgArray
'blob' : string, # PG_BLOB string
'bool' : convertBool, # PG_BOOL boolean
@@ -200,7 +255,7 @@
# need more information! could be connection id
'cidr' : convertINet, # PG_CIDR network XXX
'circle' : convertCircle, # PG_CIRCLE geometric.circle
- 'date' : debug, # PG_DATE datetime.date
+ 'date' : convertTimestamp, # PG_DATE datetime.date
'float4' : identity, # PG_FLOAT4 float
'float' : identity, # PG_FLOAT8 float
'inet' : convertINet, # PG_INET network XXX
@@ -221,15 +276,15 @@
'polygon' : convertPolygon, # PG_POLYGON geometric.polygon
'refcursor' : unicode, # PG_REFCURSOR S unicode XXX: what? identitiy?
'regproc' : unicode, # PG_REGPROC S unicode XXX: what? identitiy?
- 'reltime' : debug, # PG_RELTIME datetime.delta
+ 'reltime' : unicode, # PG_RELTIME XXX datetime.delta (obsolet)
'rowid' : long, # PG_ROWID S longint; rowid is oid in pgpPgAdmin
'text' : identity, # PG_TEXT unicode
'tid' : debug, # PG_TID S unicode XXX number? what?
# need more information, could be transaction id
- 'time' : debug, # PG_TIME datetime.time
- 'timestamp' : debug, # PG_TIMESTAMP datetime.datetime
- 'timestamptz' : debug, # PG_TIMESTAMPTZ datetime.datetime
- 'tinterval' : debug, # PG_TINTERVAL datetime.delta
+ 'time' : convertTime, # PG_TIME datetime.time
+ 'timestamp' : convertTimestamp, # PG_TIMESTAMP datetime.datetime
+ 'timestamptz' : convertTimestampTZ, # PG_TIMESTAMPTZ datetime.datetime
+ 'tinterval' : unicode, # PG_TINTERVAL XXX datetime.delta (obsolet)
'unknown' : unicode, # PG_UNKNOWN S? unicode (unknown), XXX what?
'varbit' : unicode, # PG_VARBIT XXX see zpbit!
'varchar' : identity, # PG_VARCHAR unicode