Update of /usr/cvs/Public/pygresql/module
In directory druid.net:/tmp/cvs-serv20177

Modified Files:
        pgdb.py 
Log Message:
Simplified type casting further. The DBAPI types cannot be cached anyway, so we 
check only the Postgres types, keeping them as keys in a dictionary.
To see the diffs for this commit:
   
http://www.druid.net/pygresql/viewcvs.cgi/cvs/pygresql/module/pgdb.py.diff?r1=1.39&r2=1.40

Index: pgdb.py
===================================================================
RCS file: /usr/cvs/Public/pygresql/module/pgdb.py,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- pgdb.py     31 Oct 2008 17:13:50 -0000      1.39
+++ pgdb.py     1 Nov 2008 10:37:54 -0000       1.40
@@ -4,7 +4,7 @@
 #
 # Written by D'Arcy J.M. Cain
 #
-# $Id: pgdb.py,v 1.39 2008/10/31 17:13:50 cito Exp $
+# $Id: pgdb.py,v 1.40 2008/11/01 10:37:54 cito Exp $
 #
 
 """pgdb - DB-API 2.0 compliant module for PygreSQL.
@@ -78,7 +78,8 @@
 except ImportError: # otherwise (Python < 2.4)
        Decimal = float # use float instead of Decimal
 
-### module constants
+
+### Module Constants
 
 # compliant with DB SIG 2.0
 apilevel = '2.0'
@@ -89,75 +90,48 @@
 # this module use extended python format codes
 paramstyle = 'pyformat'
 
-### internal type handling class
+
+### Internal Types Handling
+
+def _cast_bool(value):
+       return value[:1] in ['t', 'T']
+
+
+def _cast_money(value):
+       return Decimal(''.join(filter(
+               lambda v: v in '0123456789.-', value)))
+
+
+_cast = {'bool': _cast_bool,
+       'int2': int, 'int4': int, 'serial': int,
+       'int8': long, 'oid': long, 'oid8': long,
+       'float4': float, 'float8': float,
+       'numeric': Decimal, 'money': _cast_money}
+
 
 class pgdbTypeCache:
        """Cache for database types."""
 
        def __init__(self, cnx):
+               """Initialize type cache for connection."""
                self._src = cnx.source()
                self._cache = {}
-               self._casters = {}
 
        def typecast(self, typ, value):
-               return self._typecaster(typ)(value)
-
-       def _typecaster(self, typ):
-               # Type comparisons are very expensive because of the
-               # shear amount of string comparisons it will generate.
-               # Cache type casters for much better performance
-               # when fetching many values.
-               try:
-                       return self._casters[typ]
-               except KeyError:
-                       caster = self._create_typecaster(typ)
-                       self._casters[typ] = caster
-                       return caster
-
-       def _create_typecaster(self, typ):
-
-               def no_cast(value):
+               """Cast value to database type."""
+               if value is None:
+                       # for NULL values, no typecast is necessary
+                       return None
+               cast = _cast.get(typ)
+               if cast is None:
+                       # no typecast available or necessary
                        return value
-
-               def cast_bool(value):
-                       return value[:1] in ['t','T']
-
-               def cast_money(value):
-                       return Decimal(''.join(filter(
-                               lambda v: v in '0123456789.-', value)))
-
-               def cast(caster):
-                       def cast_if_not_none(value):
-                               if value is None:
-                                       # NULL/None are equivalent regardless 
of type
-                                       return None
-                               else:
-                                       return caster(value)
-                       return cast_if_not_none
-
-               if typ == BOOL:
-                       return cast(cast_bool)
-               elif typ == STRING or typ == BINARY:
-                       return no_cast
-               elif typ == INTEGER:
-                       return cast(int)
-               elif typ == LONG:
-                       return cast(long)
-               elif typ == FLOAT:
-                       return cast(float)
-               elif typ == NUMERIC:
-                       return cast(Decimal)
-               elif typ == MONEY:
-                       return cast(cast_money)
-               elif typ == DATETIME:
-                       # format may differ ... we'll give string
-                       return no_cast
-               elif typ == ROWID:
-                       return cast(long)
                else:
-                       return no_cast
+                       return cast(value)
+               typecast = staticmethod(typecast)
 
        def getdescr(self, oid):
+               """Get name of database type with given oid."""
                try:
                        return self._cache[oid]
                except:
@@ -167,13 +141,49 @@
                        res = self._src.fetch(1)[0]
                        # The column name is omitted from the return value.
                        # It will have to be prepended by the caller.
-                       res = (res[0],
-                               None, int(res[1]),
+                       res = (res[0], None, int(res[1]),
                                None, None, None)
                        self._cache[oid] = res
                        return res
 
 
+class _quoteitem(dict):
+       def __getitem__(self, key):
+               return _quote(super(_quoteitem, self).__getitem__(key))
+
+
+def _quote(x):
+       if isinstance(x, DateTimeType):
+               x = str(x)
+       elif isinstance(x, unicode):
+               x = x.encode( 'utf-8' )
+       if isinstance(x, types.StringType):
+               x = "'%s'" % str(x).replace("\\", "\\\\").replace("'", "''")
+       elif isinstance(x, (types.IntType, types.LongType, types.FloatType)):
+               pass
+       elif x is None:
+               x = 'NULL'
+       elif isinstance(x, (types.ListType, types.TupleType)):
+               x = '(%s)' % ','.join(map(lambda x: str(_quote(x)), x))
+       elif Decimal is not float and isinstance(x, Decimal):
+               pass
+       elif hasattr(x, '__pg_repr__'):
+               x = x.__pg_repr__()
+       else:
+               raise InterfaceError('do not know how to handle type %s' % 
type(x))
+       return x
+
+
+def _quoteparams(s, params):
+       if hasattr(params, 'has_key'):
+               params = _quoteitem(params)
+       else:
+               params = tuple(map(_quote, params))
+       return s % params
+
+
+### Cursor Object
+
 class pgdbCursor:
        """Cursor Object."""
 
@@ -311,41 +321,7 @@
                pass
 
 
-class _quoteitem(dict):
-       def __getitem__(self, key):
-               return _quote(super(_quoteitem, self).__getitem__(key))
-
-
-def _quote(x):
-       if isinstance(x, DateTimeType):
-               x = str(x)
-       elif isinstance(x, unicode):
-               x = x.encode( 'utf-8' )
-       if isinstance(x, types.StringType):
-               x = "'%s'" % str(x).replace("\\", "\\\\").replace("'", "''")
-       elif isinstance(x, (types.IntType, types.LongType, types.FloatType)):
-               pass
-       elif x is None:
-               x = 'NULL'
-       elif isinstance(x, (types.ListType, types.TupleType)):
-               x = '(%s)' % ','.join(map(lambda x: str(_quote(x)), x))
-       elif Decimal is not float and isinstance(x, Decimal):
-               pass
-       elif hasattr(x, '__pg_repr__'):
-               x = x.__pg_repr__()
-       else:
-               raise InterfaceError('do not know how to handle type %s' % 
type(x))
-       return x
-
-
-def _quoteparams(s, params):
-       if hasattr(params, 'has_key'):
-               params = _quoteitem(params)
-       else:
-               params = tuple(map(_quote, params))
-
-       return s % params
-
+### Connection Objects
 
 class pgdbCnx:
        """Connection Object."""
@@ -527,7 +503,7 @@
        return str
 
 
-# if run as script, print some information
+# If run as script, print some information:
 
 if __name__ == '__main__':
        print 'PyGreSQL version', version

_______________________________________________
PyGreSQL mailing list
[email protected]
http://mailman.vex.net/mailman/listinfo/pygresql

Reply via email to