From: Mike Bayer Date: Tue, 1 Feb 2011 21:34:37 +0000 (-0500) Subject: - Some adjustments so that Interbase is supported as well. X-Git-Tag: rel_0_7b1~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a2c332f5e2faf321a89e93d5d183d7ec3767084;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Some adjustments so that Interbase is supported as well. FB/Interbase version idents are parsed into a structure such as (8, 1, 1, 'interbase') or (2, 1, 588, 'firebird') so they can be distinguished. [ticket:1885] - fixed relfection of the "autoincrement" flag against a default placed on the column. --- diff --git a/CHANGES b/CHANGES index 594bcfa5ff..7ab5fbd023 100644 --- a/CHANGES +++ b/CHANGES @@ -170,6 +170,12 @@ CHANGES - New DBAPI support for pymysql, a pure Python port of MySQL-python. [ticket:1991] +- firebird + - Some adjustments so that Interbase is supported as well. + FB/Interbase version idents are parsed into a structure + such as (8, 1, 1, 'interbase') or (2, 1, 588, 'firebird') + so they can be distinguished. [ticket:1885] + - drizzle - New dialect for Drizzle, a MySQL variant. Uses MySQL-python for the DBAPI. [ticket:2003] diff --git a/doc/build/core/engines.rst b/doc/build/core/engines.rst index 2d135f459d..4f59cd21e6 100644 --- a/doc/build/core/engines.rst +++ b/doc/build/core/engines.rst @@ -63,7 +63,7 @@ Driver Connect string Py2K Py3K ibm-db_ thirdparty thirdparty thirdparty thirdparty thirdparty thirdparty **Drizzle** mysql-python_ ``drizzle+mysqldb``\* yes development no yes yes -**Firebird** +**Firebird / Interbase** kinterbasdb_ ``firebird+kinterbasdb``\* yes development no yes yes **Informix** informixdb_ ``informix+informixdb``\* yes development no unknown unknown diff --git a/lib/sqlalchemy/dialects/firebird/base.py b/lib/sqlalchemy/dialects/firebird/base.py index 32ffbfd69b..84222e428d 100644 --- a/lib/sqlalchemy/dialects/firebird/base.py +++ b/lib/sqlalchemy/dialects/firebird/base.py @@ -375,7 +375,13 @@ class FBDialect(default.DefaultDialect): def initialize(self, connection): super(FBDialect, self).initialize(connection) - self._version_two = self.server_version_info > (2, ) + self._version_two = ('firebird' in self.server_version_info and \ + self.server_version_info >= (2, ) + ) or \ + ('interbase' in self.server_version_info and \ + self.server_version_info >= (6, ) + ) + if not self._version_two: # TODO: whatever other pre < 2.0 stuff goes here self.ischema_names = ischema_names.copy() @@ -510,7 +516,7 @@ class FBDialect(default.DefaultDialect): def get_columns(self, connection, table_name, schema=None, **kw): # Query to extract the details of all the fields of the given table tblqry = """ - SELECT DISTINCT r.rdb$field_name AS fname, + SELECT r.rdb$field_name AS fname, r.rdb$null_flag AS null_flag, t.rdb$type_name AS ftype, f.rdb$field_sub_type AS stype, @@ -587,7 +593,7 @@ class FBDialect(default.DefaultDialect): 'type' : coltype, 'nullable' : not bool(row['null_flag']), 'default' : defvalue, - 'autoincrement':default is None + 'autoincrement':defvalue is None } if orig_colname.lower() == orig_colname: diff --git a/lib/sqlalchemy/dialects/firebird/kinterbasdb.py b/lib/sqlalchemy/dialects/firebird/kinterbasdb.py index 73989097be..216fec2703 100644 --- a/lib/sqlalchemy/dialects/firebird/kinterbasdb.py +++ b/lib/sqlalchemy/dialects/firebird/kinterbasdb.py @@ -49,6 +49,8 @@ from sqlalchemy.dialects.firebird.base import FBDialect, \ FBCompiler, FBExecutionContext from sqlalchemy import util, types as sqltypes from sqlalchemy.util.compat import decimal +from re import match + class _FBNumeric_kinterbasdb(sqltypes.Numeric): def bind_processor(self, dialect): @@ -133,18 +135,23 @@ class FBDialect_kinterbasdb(FBDialect): # that for backward compatibility reasons returns a string like # LI-V6.3.3.12981 Firebird 2.0 # where the first version is a fake one resembling the old - # Interbase signature. This is more than enough for our purposes, - # as this is mainly (only?) used by the testsuite. - - from re import match + # Interbase signature. fbconn = connection.connection version = fbconn.server_version - m = match('\w+-V(\d+)\.(\d+)\.(\d+)\.(\d+) \w+ (\d+)\.(\d+)', version) + + return self._parse_version_info(version) + + def _parse_version_info(self, version): + m = match('\w+-V(\d+)\.(\d+)\.(\d+)\.(\d+)( \w+ (\d+)\.(\d+))?', version) if not m: raise AssertionError( "Could not determine version from string '%s'" % version) - return tuple([int(x) for x in m.group(5, 6, 4)]) + + if m.group(5) != None: + return tuple([int(x) for x in m.group(6, 7, 4)] + ['firebird']) + else: + return tuple([int(x) for x in m.group(1, 2, 3)] + ['interbase']) def is_disconnect(self, e): if isinstance(e, (self.dbapi.OperationalError, diff --git a/test/dialect/test_firebird.py b/test/dialect/test_firebird.py index 532a93ed09..c1b4c590ca 100644 --- a/test/dialect/test_firebird.py +++ b/test/dialect/test_firebird.py @@ -355,10 +355,18 @@ class MiscTest(TestBase): select([func.count(t.c.id)], func.length(t.c.name) == 5).execute().first()[0] == 1 - def test_server_version_info(self): - version = testing.db.dialect.server_version_info - assert len(version) == 3, 'Got strange version info: %s' \ - % repr(version) + def test_version_parsing(self): + for string, result in [ + ("WI-V1.5.0.1234 Firebird 1.5", (1, 5, 1234, 'firebird')), + ("UI-V6.3.2.18118 Firebird 2.1", (2, 1, 18118, 'firebird')), + ("LI-V6.3.3.12981 Firebird 2.0", (2, 0, 12981, 'firebird')), + ("WI-V8.1.1.333", (8, 1, 1, 'interbase')), + ("WI-V8.1.1.333 Firebird 1.5", (1, 5, 333, 'firebird')), + ]: + eq_( + testing.db.dialect._parse_version_info(string), + result + ) @testing.provide_metadata def test_rowcount_flag(self):