From: Mike Bayer Date: Sat, 19 Jun 2010 17:51:55 +0000 (-0400) Subject: - Firebird dialect adds CHAR, VARCHAR types which X-Git-Tag: rel_0_6_2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77c3bb26c29c491c1094427345ca51f309938572;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Firebird dialect adds CHAR, VARCHAR types which accept a "charset" flag, to support Firebird "CHARACTER SET" clause. [ticket:1813] --- diff --git a/CHANGES b/CHANGES index 7eb7b2adb6..e8bea81ce8 100644 --- a/CHANGES +++ b/CHANGES @@ -92,6 +92,10 @@ CHANGES - Fixed incorrect signature in do_execute(), error introduced in 0.6.1. [ticket:1823] + - Firebird dialect adds CHAR, VARCHAR types which + accept a "charset" flag, to support Firebird + "CHARACTER SET" clause. [ticket:1813] + - declarative - a mixin class can now define a column that matches one which is present on a __table__ defined on a diff --git a/lib/sqlalchemy/dialects/firebird/base.py b/lib/sqlalchemy/dialects/firebird/base.py index 0d3143b3bd..d6e0f95bd1 100644 --- a/lib/sqlalchemy/dialects/firebird/base.py +++ b/lib/sqlalchemy/dialects/firebird/base.py @@ -78,9 +78,9 @@ from sqlalchemy.engine import base, default, reflection from sqlalchemy.sql import compiler -from sqlalchemy.types import (BIGINT, BLOB, BOOLEAN, CHAR, DATE, +from sqlalchemy.types import (BIGINT, BLOB, BOOLEAN, DATE, FLOAT, INTEGER, NUMERIC, SMALLINT, - TEXT, TIME, TIMESTAMP, VARCHAR) + TEXT, TIME, TIMESTAMP) RESERVED_WORDS = set([ @@ -123,6 +123,27 @@ RESERVED_WORDS = set([ ]) +class _StringType(sqltypes.String): + """Base for Firebird string types.""" + + def __init__(self, charset = None, **kw): + self.charset = charset + super(_StringType, self).__init__(**kw) + +class VARCHAR(_StringType, sqltypes.VARCHAR): + """Firebird VARCHAR type""" + __visit_name__ = 'VARCHAR' + + def __init__(self, length = None, **kwargs): + super(VARCHAR, self).__init__(length=length, **kwargs) + +class CHAR(_StringType, sqltypes.CHAR): + """Firebird CHAR type""" + __visit_name__ = 'CHAR' + + def __init__(self, length = None, **kwargs): + super(CHAR, self).__init__(length=length, **kwargs) + colspecs = { } @@ -159,6 +180,22 @@ class FBTypeCompiler(compiler.GenericTypeCompiler): def visit_BLOB(self, type_): return "BLOB SUB_TYPE 0" + def _extend_string(self, type_, basic): + charset = getattr(type_, 'charset', None) + if charset is None: + return basic + else: + return '%s CHARACTER SET %s' % (basic, charset) + + def visit_CHAR(self, type_): + basic = super(FBTypeCompiler, self).visit_CHAR(type_) + return self._extend_string(type_, basic) + + def visit_VARCHAR(self, type_): + basic = super(FBTypeCompiler, self).visit_VARCHAR(type_) + return self._extend_string(type_, basic) + + class FBCompiler(sql.compiler.SQLCompiler): """Firebird specific idiosincrasies""" diff --git a/test/dialect/test_firebird.py b/test/dialect/test_firebird.py index 9bdce8ff71..944d5bc2fe 100644 --- a/test/dialect/test_firebird.py +++ b/test/dialect/test_firebird.py @@ -259,6 +259,22 @@ class CompileTest(TestBase, AssertsCompiledSQL): i = insert(table1, values=dict(name='foo')).returning(func.length(table1.c.name)) self.assert_compile(i, "INSERT INTO mytable (name) VALUES (:name) RETURNING char_length(mytable.name) AS length_1") + def test_charset(self): + """Exercise CHARACTER SET options on string types.""" + + columns = [ + (firebird.CHAR, [1], {}, + 'CHAR(1)'), + (firebird.CHAR, [1], {'charset' : 'OCTETS'}, + 'CHAR(1) CHARACTER SET OCTETS'), + (firebird.VARCHAR, [1], {}, + 'VARCHAR(1)'), + (firebird.VARCHAR, [1], {'charset' : 'OCTETS'}, + 'VARCHAR(1) CHARACTER SET OCTETS'), + ] + + for type_, args, kw, res in columns: + self.assert_compile(type_(*args, **kw), res) diff --git a/test/sql/test_query.py b/test/sql/test_query.py index 5a4f033112..2b51d68a26 100644 --- a/test/sql/test_query.py +++ b/test/sql/test_query.py @@ -809,6 +809,7 @@ class QueryTest(TestBase): assert len(r) == 0 @testing.emits_warning('.*empty sequence.*') + @testing.fails_on('firebird', 'uses sql-92 bind rules') def test_literal_in(self): """similar to test_bind_in but use a bind with a value."""