diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-08-06 21:11:27 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2009-08-06 21:11:27 +0000 |
| commit | 8fc5005dfe3eb66a46470ad8a8c7b95fc4d6bdca (patch) | |
| tree | ae9e27d12c9fbf8297bb90469509e1cb6a206242 /lib/sqlalchemy/connectors | |
| parent | 7638aa7f242c6ea3d743aa9100e32be2052546a6 (diff) | |
| download | sqlalchemy-8fc5005dfe3eb66a46470ad8a8c7b95fc4d6bdca.tar.gz | |
merge 0.6 series to trunk.
Diffstat (limited to 'lib/sqlalchemy/connectors')
| -rw-r--r-- | lib/sqlalchemy/connectors/__init__.py | 6 | ||||
| -rw-r--r-- | lib/sqlalchemy/connectors/mxodbc.py | 24 | ||||
| -rw-r--r-- | lib/sqlalchemy/connectors/pyodbc.py | 80 | ||||
| -rw-r--r-- | lib/sqlalchemy/connectors/zxJDBC.py | 43 |
4 files changed, 153 insertions, 0 deletions
diff --git a/lib/sqlalchemy/connectors/__init__.py b/lib/sqlalchemy/connectors/__init__.py new file mode 100644 index 000000000..f1383ad82 --- /dev/null +++ b/lib/sqlalchemy/connectors/__init__.py @@ -0,0 +1,6 @@ + + +class Connector(object): + pass + +
\ No newline at end of file diff --git a/lib/sqlalchemy/connectors/mxodbc.py b/lib/sqlalchemy/connectors/mxodbc.py new file mode 100644 index 000000000..a0f3f0216 --- /dev/null +++ b/lib/sqlalchemy/connectors/mxodbc.py @@ -0,0 +1,24 @@ +from sqlalchemy.connectors import Connector + +class MxODBCConnector(Connector): + driver='mxodbc' + supports_sane_rowcount = False + supports_sane_multi_rowcount = False + supports_unicode_statements = False + supports_unicode_binds = False + + @classmethod + def import_dbapi(cls): + import mxODBC as module + return module + + def create_connect_args(self, url): + '''Return a tuple of *args,**kwargs''' + # FIXME: handle mx.odbc.Windows proprietary args + opts = url.translate_connect_args(username='user') + opts.update(url.query) + argsDict = {} + argsDict['user'] = opts['user'] + argsDict['password'] = opts['password'] + connArgs = [[opts['dsn']], argsDict] + return connArgs diff --git a/lib/sqlalchemy/connectors/pyodbc.py b/lib/sqlalchemy/connectors/pyodbc.py new file mode 100644 index 000000000..4f8d6d517 --- /dev/null +++ b/lib/sqlalchemy/connectors/pyodbc.py @@ -0,0 +1,80 @@ +from sqlalchemy.connectors import Connector + +import sys +import re +import urllib + +class PyODBCConnector(Connector): + driver='pyodbc' + supports_sane_rowcount = False + supports_sane_multi_rowcount = False + # PyODBC unicode is broken on UCS-4 builds + supports_unicode = sys.maxunicode == 65535 + supports_unicode_statements = supports_unicode + default_paramstyle = 'named' + + # for non-DSN connections, this should + # hold the desired driver name + pyodbc_driver_name = None + + @classmethod + def dbapi(cls): + return __import__('pyodbc') + + def create_connect_args(self, url): + opts = url.translate_connect_args(username='user') + opts.update(url.query) + + keys = opts + query = url.query + + if 'odbc_connect' in keys: + connectors = [urllib.unquote_plus(keys.pop('odbc_connect'))] + else: + dsn_connection = 'dsn' in keys or ('host' in keys and 'database' not in keys) + if dsn_connection: + connectors= ['dsn=%s' % (keys.pop('host', '') or keys.pop('dsn', ''))] + else: + port = '' + if 'port' in keys and not 'port' in query: + port = ',%d' % int(keys.pop('port')) + + connectors = ["DRIVER={%s}" % keys.pop('driver', self.pyodbc_driver_name), + 'Server=%s%s' % (keys.pop('host', ''), port), + 'Database=%s' % keys.pop('database', '') ] + + user = keys.pop("user", None) + if user: + connectors.append("UID=%s" % user) + connectors.append("PWD=%s" % keys.pop('password', '')) + else: + connectors.append("TrustedConnection=Yes") + + # if set to 'Yes', the ODBC layer will try to automagically convert + # textual data from your database encoding to your client encoding + # This should obviously be set to 'No' if you query a cp1253 encoded + # database from a latin1 client... + if 'odbc_autotranslate' in keys: + connectors.append("AutoTranslate=%s" % keys.pop("odbc_autotranslate")) + + connectors.extend(['%s=%s' % (k,v) for k,v in keys.iteritems()]) + return [[";".join (connectors)], {}] + + def is_disconnect(self, e): + if isinstance(e, self.dbapi.ProgrammingError): + return "The cursor's connection has been closed." in str(e) or 'Attempt to use a closed connection.' in str(e) + elif isinstance(e, self.dbapi.Error): + return '[08S01]' in str(e) + else: + return False + + def _get_server_version_info(self, connection): + dbapi_con = connection.connection + version = [] + r = re.compile('[.\-]') + for n in r.split(dbapi_con.getinfo(self.dbapi.SQL_DBMS_VER)): + try: + version.append(int(n)) + except ValueError: + version.append(n) + return tuple(version) diff --git a/lib/sqlalchemy/connectors/zxJDBC.py b/lib/sqlalchemy/connectors/zxJDBC.py new file mode 100644 index 000000000..3cdfeb32e --- /dev/null +++ b/lib/sqlalchemy/connectors/zxJDBC.py @@ -0,0 +1,43 @@ +import sys +from sqlalchemy.connectors import Connector + +class ZxJDBCConnector(Connector): + driver = 'zxjdbc' + + supports_sane_rowcount = False + supports_sane_multi_rowcount = False + + supports_unicode_binds = True + supports_unicode_statements = sys.version > '2.5.0+' + description_encoding = None + default_paramstyle = 'qmark' + + jdbc_db_name = None + jdbc_driver_name = None + + @classmethod + def dbapi(cls): + from com.ziclix.python.sql import zxJDBC + return zxJDBC + + def _driver_kwargs(self): + """return kw arg dict to be sent to connect().""" + return {} + + def create_connect_args(self, url): + hostname = url.host + dbname = url.database + d, u, p, v = ("jdbc:%s://%s/%s" % (self.jdbc_db_name, hostname, dbname), + url.username, url.password, self.jdbc_driver_name) + return [[d, u, p, v], self._driver_kwargs()] + + def is_disconnect(self, e): + if not isinstance(e, self.dbapi.ProgrammingError): + return False + e = str(e) + return 'connection is closed' in e or 'cursor is closed' in e + + def _get_server_version_info(self, connection): + # use connection.connection.dbversion, and parse appropriately + # to get a tuple + raise NotImplementedError() |
