[Zope3-checkins] CVS: zopeproducts/psycopgda - adapter.py:1.5

Stephan Richter srichter at cosmos.phy.tufts.edu
Fri Mar 19 20:25:21 EST 2004


Update of /cvs-repository/zopeproducts/psycopgda
In directory cvs.zope.org:/tmp/cvs-serv31175/src/zopeproducts/psycopgda

Modified Files:
	adapter.py 
Log Message:
Applied patch from issue 197. The patch had a little bug, which I corrected.


=== zopeproducts/psycopgda/adapter.py 1.4 => 1.5 ===
--- zopeproducts/psycopgda/adapter.py:1.4	Mon Jun  2 04:22:49 2003
+++ zopeproducts/psycopgda/adapter.py	Fri Mar 19 20:25:20 2004
@@ -15,11 +15,11 @@
 
 $Id$
 """
-
 from zope.app.rdb import ZopeDatabaseAdapter, parseDSN
 
 from datetime import date, time, datetime, timedelta
 import psycopg
+import re
 
 # These OIDs are taken from pg_types.h from PostgreSQL headers.
 # Unfortunatelly psycopg does not export them as constants, and
@@ -36,6 +36,9 @@
 #TINTERVAL_OID   = 704
 
 # Date/time parsing functions
+
+_dateFmt = re.compile(r"^(\d\d\d\d)-?([01]\d)-?([0-3]\d)$")
+
 def parse_date(s):
     """Parses ISO-8601 compliant dates and returns a tuple (year, month,
     day).
@@ -44,12 +47,15 @@
         YYYY-MM-DD  (extended format)
         YYYYMMDD    (basic format)
     """
-    if len(s) == 8:
-        return (int(s[:4]), int(s[4:6]), int(s[6:]))    # YYYYMMDD
-    elif len(s) == 10 and s[4] == s[7] == '-':
-        return (int(s[:4]), int(s[5:7]), int(s[8:]))    # YYYY-MM-DD
-    else:
+    m = _dateFmt.match(s)
+    if m is None:
         raise ValueError, 'invalid date string: %s' % s
+    year, month, day = m.groups()
+    return int(year), int(month), int(day)
+
+
+_timeFmt = re.compile(
+    r"^([0-2]\d)(?::?([0-5]\d)(?::?([0-5]\d)(?:[.,](\d+))?)?)?$")
 
 def parse_time(s):
     """Parses ISO-8601 compliant times and returns a tuple (hour, minute,
@@ -62,28 +68,18 @@
         HH:MM         or HHMM
         HH
     """
-    if len(s) == 2:
-        return (int(s[:2]), 0, 0)                       # HH
-    elif len(s) == 4:
-        return (int(s[:2]), int(s[2:]), 0)              # HHMM
-    elif len(s) == 5 and s[2] == ':':
-        return (int(s[:2]), int(s[3:]), 0)              # HH:MM
-    elif len(s) == 6:
-        return (int(s[:2]), int(s[2:4]), int(s[4:]))    # HHMMSS
-    elif len(s) == 8 and s[2] == s[5] == ':':
-        return (int(s[:2]), int(s[3:5]), int(s[6:]))    # HH:MM:SS
-    elif len(s) > 9 and s[2] == s[5] == ':' and s[8] == '.':
-        return (int(s[:2]), int(s[3:5]), float(s[6:]))  # HH:MM:SS.ssss
-    elif len(s) > 9 and s[2] == s[5] == ':' and s[8] == ',':
-        return (int(s[:2]), int(s[3:5]), float(s[6:8] + "." + s[9:]))
-                                                        # HH:MM:SS,ssss
-    elif len(s) > 7 and s[6] == '.':
-        return (int(s[:2]), int(s[2:4]), float(s[4:]))  # HHMMSS.ssss
-    elif len(s) > 7 and s[6] == ',':
-        return (int(s[:2]), int(s[2:4]), float(s[4:6] + "." + s[7:]))
-                                                        # HHMMSS,ssss
-    else:
+    m = _timeFmt.match(s)
+    if m is None:
         raise ValueError, 'invalid time string: %s' % s
+    hr, mn, sc, msc = m.groups(0)
+    if msc != 0:
+        sc = float("%s.%s" % (sc, msc))
+    else:
+        sc = int(sc)
+    return int(hr), int(mn), sc
+
+
+_tzFmt = re.compile(r"^([+-])([0-2]\d)(?::?([0-5]\d))?$")
 
 def parse_tz(s):
     """Parses ISO-8601 timezones and returns the offset east of UTC in
@@ -95,22 +91,18 @@
         +/-HH
         Z           (equivalent to +0000)
     """
-    if s == "Z":
+    if s == 'Z':
         return 0
-    if len(s) in (3, 5, 6) and s[0] in ('+', '-'):
-        hoff = int(s[1:3])
-        if len(s) > 3:
-            moff = int(s[-2:])
-            if len(s) == 6 and s[3] != ':':
-                raise ValueError, 'invalid time zone: %s' % s
-        else:
-            moff = 0
-        if s[0] == '-':
-            return - hoff * 60 - moff
-        else:
-            return hoff * 60 + moff
-    else:
+    m = _tzFmt.match(s)
+    if m is None:
         raise ValueError, 'invalid time zone: %s' % s
+    d, hoff, moff = m.groups(0)
+    if d == "-":
+        return - int(hoff) * 60 - int(moff)
+    return int(hoff) * 60 + int(moff)
+
+
+_tzPos = re.compile(r"[Z+-]")
 
 def parse_timetz(s):
     """Parses ISO-8601 compliant times that may include timezone information
@@ -123,13 +115,27 @@
     parse_tz().  Time zone should immediatelly follow time without intervening
     spaces.
     """
-    idx = s.find('+')
-    if idx < 0: idx = s.find('-')
-    if idx < 0: idx = s.find('Z')
-    if idx < 0:
+    m = _tzPos.search(s)
+    if m is None:
         return parse_time(s) + (None,)
-    else:
-        return parse_time(s[:idx]) + (parse_tz(s[idx:]),)
+    pos = m.start()
+    return parse_time(s[:pos]) + (parse_tz(s[pos:]),)
+
+
+_datetimeFmt = re.compile(r"[T ]")
+
+def _split_datetime(s):
+    """Split date and time parts of ISO-8601 compliant timestamp and
+    return a tuple (date, time).
+
+    ' ' or 'T' used to separate date and time parts.
+    """
+    m = _datetimeFmt.search(s)
+    if m is None:
+        raise ValueError, 'time part of datetime missing: %s' % s
+    pos = m.start()
+    return s[:pos], s[pos + 1:]
+
 
 def parse_datetime(s):
     """Parses ISO-8601 compliant timestamp and returns a tuple (year, month,
@@ -138,11 +144,9 @@
     Formats accepted are those listed in the descriptions of parse_date() and
     parse_time() with ' ' or 'T' used to separate date and time parts.
     """
-    idx = s.find('T')
-    if idx < 0: idx = s.find(' ')
-    if idx < 0:
-        raise ValueError, 'time part of datetime missing: %s' % s
-    return parse_date(s[:idx]) + parse_time(s[idx + 1:])
+    dt, tm = _split_datetime(s)
+    return parse_date(dt) + parse_time(tm)
+
 
 def parse_datetimetz(s):
     """Parses ISO-8601 compliant timestamp that may include timezone
@@ -155,11 +159,8 @@
     Formats accepted are those listed in the descriptions of parse_date() and
     parse_timetz() with ' ' or 'T' used to separate date and time parts.
     """
-    idx = s.find('T')
-    if idx < 0: idx = s.find(' ')
-    if idx < 0:
-        raise ValueError, 'time part of datetime missing: %s' % s
-    return parse_date(s[:idx]) + parse_timetz(s[idx + 1:])
+    dt, tm = _split_datetime(s)
+    return parse_date(dt) + parse_timetz(tm)
 
 
 def parse_interval(s):
@@ -216,7 +217,7 @@
         hr, mn, sc = parse_time(s)
         sc, micro = divmod(sc, 1.0)
         micro = round(micro * 1000000)
-        return time(hr, mn, sc, micro)
+        return time(hr, mn, int(sc), int(micro))
 
 def _conv_timetz(s):
     if s:
@@ -225,14 +226,14 @@
         sc, micro = divmod(sc, 1.0)
         micro = round(micro * 1000000)
         if tz: tz = tzinfo(tz)
-        return time(hr, mn, sc, micro, tz)
+        return time(hr, mn, int(sc), int(micro), tz)
 
 def _conv_timestamp(s):
     if s:
         y, m, d, hr, mn, sc = parse_datetime(s)
         sc, micro = divmod(sc, 1.0)
         micro = round(micro * 1000000)
-        return datetime(y, m, d, hr, mn, sc, micro)
+        return datetime(y, m, d, hr, mn, int(sc), int(micro))
 
 def _conv_timestamptz(s):
     if s:
@@ -241,7 +242,7 @@
         sc, micro = divmod(sc, 1.0)
         micro = round(micro * 1000000)
         if tz: tz = tzinfo(tz)
-        return datetime(y, m, d, hr, mn, sc, micro, tz)
+        return datetime(y, m, d, hr, mn, int(sc), int(micro), tz)
 
 def _conv_interval(s):
     if s:
@@ -286,15 +287,13 @@
     it might be something like '1 month', which is a variable number of days.
     """
 
-
     def _connection_factory(self):
         """Create a Psycopg DBI connection based on the DSN"""
         conn_info = parseDSN(self.dsn)
         conn_list = []
-        for option in dsn2option_mapping:
-            if conn_info[option]:
-                conn_list.append('%s=%s' %(dsn2option_mapping[option],
-                                           conn_info[option]))
+        for dsnname, optname in dsn2option_mapping.iteritems():
+            if conn_info[dsnname]:
+                conn_list.append('%s=%s' % (optname, conn_info[dsnname]))
         conn_str = ' '.join(conn_list)
         self._registerTypes()
         return psycopg.connect(conn_str)
@@ -307,4 +306,3 @@
         psycopg.register_type(TIMESTAMP)
         psycopg.register_type(TIMESTAMPTZ)
         psycopg.register_type(INTERVAL)
-




More information about the Zope3-Checkins mailing list