]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Firebird dialect adds CHAR, VARCHAR types which
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 19 Jun 2010 17:51:55 +0000 (13:51 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 19 Jun 2010 17:51:55 +0000 (13:51 -0400)
accept a "charset" flag, to support Firebird
"CHARACTER SET" clause.  [ticket:1813]

CHANGES
lib/sqlalchemy/dialects/firebird/base.py
test/dialect/test_firebird.py
test/sql/test_query.py

diff --git a/CHANGES b/CHANGES
index 7eb7b2adb6ea4c94012929360b803f6f0bf65e30..e8bea81ce8fcd81b73a981fcad83e9dea4d230e3 100644 (file)
--- 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 
index 0d3143b3bd8c6c3214964a57f229eb26411627ad..d6e0f95bd10593c293c910befc64d30f2797bbfc 100644 (file)
@@ -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"""
index 9bdce8ff713bfc8c7597e335c0c985a9af8eaa40..944d5bc2fe51ab0f3bbf1730ae952bbd13135e7d 100644 (file)
@@ -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)
 
 
 
index 5a4f033112d2227b53454fd6ca29666800dfbef5..2b51d68a26c75a0f83515c88d2212e19ebbaa586 100644 (file)
@@ -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."""