diff options
author | Sylvain Thenault <sylvain.thenault@logilab.fr> | 2008-08-06 18:55:11 +0200 |
---|---|---|
committer | Sylvain Thenault <sylvain.thenault@logilab.fr> | 2008-08-06 18:55:11 +0200 |
commit | c29704aa086b0867581c9b5d89f6fecd31953076 (patch) | |
tree | 7b25b1f79e0cd6f602d44487a5b08a8ab02bb77d /db.py | |
parent | f89e70ed95cac5395a0a861ff8e4fc966faad7c5 (diff) | |
parent | bea3fe59dbc3f30c74ec14ef947ad59b78bb476b (diff) | |
download | logilab-common-c29704aa086b0867581c9b5d89f6fecd31953076.tar.gz |
merge
Diffstat (limited to 'db.py')
-rw-r--r-- | db.py | 42 |
1 files changed, 33 insertions, 9 deletions
@@ -163,7 +163,8 @@ class PyCursor: class DBAPIAdapter: """Base class for all DBAPI adpaters""" - + UNKNOWN = None + def __init__(self, native_module, pywrap=False): """ :type native_module: module @@ -171,7 +172,15 @@ class DBAPIAdapter: """ self._native_module = native_module self._pywrap = pywrap - + # optimisation: copy type codes from the native module to this instance + # since the .process_value method may be heavily used + for typecode in ('STRING', 'BOOLEAN', 'BINARY', 'DATETIME', 'NUMBER', + 'UNKNOWN'): + try: + setattr(self, typecode, getattr(self, typecode)) + except AttributeError: + print 'WARNING: %s adapter has no %s type code' % (self, typecode) + def connect(self, host='', database='', user='', password='', port=''): """Wraps the native module connect method""" kwargs = {'host' : host, 'port' : port, 'database' : database, @@ -197,8 +206,9 @@ class DBAPIAdapter: return getattr(self._native_module, attrname) def process_value(self, value, description, encoding='utf-8', binarywrap=None): + # if the dbapi module isn't supporting type codes, override to return value directly typecode = description[1] - assert typecode is not None, self # dbapi module isn't supporting type codes, override to return value directly + assert typecode is not None, self if typecode == self.STRING: if isinstance(value, str): return unicode(value, encoding, 'replace') @@ -206,6 +216,12 @@ class DBAPIAdapter: return bool(value) elif typecode == self.BINARY and not binarywrap is None: return binarywrap(value) + elif typecode == self.UNKNOWN: + # may occurs on constant selection for instance (eg SELECT 'hop') + # with postgresql at least + if isinstance(value, str): + return unicode(value, encoding, 'replace') + ## elif typecode == dbapimod.DATETIME: ## pass ## elif typecode == dbapimod.NUMBER: @@ -253,12 +269,18 @@ class _PsycopgAdapter(DBAPIAdapter): cnx = self._native_module.connect(cnx_string) cnx.set_isolation_level(1) return self._wrap_if_needed(cnx, user) + class _Psycopg2Adapter(_PsycopgAdapter): """Simple Psycopg2 Adapter to DBAPI (cnx_string differs from classical ones) """ - BOOLEAN = 16 # XXX see additional types in psycopg2.extensions + # not defined in psycopg2.extensions + # "select typname from pg_type where oid=705"; + UNKNOWN = 705 + def __init__(self, native_module, pywrap=False): + from psycopg2 import extensions + self.BOOLEAN = extensions.BOOLEAN DBAPIAdapter.__init__(self, native_module, pywrap) self._init_psycopg2() @@ -314,14 +336,16 @@ class _PgsqlAdapter(DBAPIAdapter): class _PySqlite2Adapter(DBAPIAdapter): """Simple pysqlite2 Adapter to DBAPI """ + # no type code in pysqlite2 + BINARY = 'XXX' + STRING = 'XXX' + DATETIME = 'XXX' + NUMBER = 'XXX' + BOOLEAN = 'XXX' + def __init__(self, native_module, pywrap=False): DBAPIAdapter.__init__(self, native_module, pywrap) self._init_pysqlite2() - # no type code in pysqlite2 - self.BINARY = 'XXX' - self.STRING = 'XXX' - self.DATETIME = 'XXX' - self.NUMBER = 'XXX' def _init_pysqlite2(self): """initialize pysqlite2 to use mx.DateTime for date and timestamps""" |