]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- type renaming extravaganza
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 8 Jul 2009 02:17:18 +0000 (02:17 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 8 Jul 2009 02:17:18 +0000 (02:17 +0000)
- changed the contract a bit on reflection.cache

12 files changed:
doc/build/reference/dialects/mysql.rst
lib/sqlalchemy/dialects/maxdb/base.py
lib/sqlalchemy/dialects/mssql/base.py
lib/sqlalchemy/dialects/mysql/base.py
lib/sqlalchemy/dialects/oracle/base.py
lib/sqlalchemy/dialects/sybase/base.py
lib/sqlalchemy/dialects/type_migration_guidelines.txt
lib/sqlalchemy/engine/reflection.py
lib/sqlalchemy/types.py
test/dialect/test_mysql.py
test/engine/test_reflection.py
test/sql/test_types.py

index 7df1c98434decd9e8a8a9a5f670f86fb2e0d24ad..a3a4f0e72c399a1984987497b156f88b8ec63dbb 100644 (file)
@@ -6,135 +6,135 @@ MySQL
 MySQL Column Types
 ------------------
 
-.. autoclass:: MSNumeric
+.. autoclass:: NUMERIC
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSDecimal
+.. autoclass:: DECIMAL
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSDouble
+.. autoclass:: DOUBLE
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSReal
+.. autoclass:: REAL
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSFloat
+.. autoclass:: FLOAT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSInteger
+.. autoclass:: INTEGER
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSBigInteger
+.. autoclass:: BIGINT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSMediumInteger
+.. autoclass:: MEDIUMINT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSTinyInteger
+.. autoclass:: TINYINT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSSmallInteger
+.. autoclass:: SMALLINT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSBit
+.. autoclass:: BIT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSDateTime
+.. autoclass:: DATETIME
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSDate
+.. autoclass:: DATE
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSTime
+.. autoclass:: TIME
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSTimeStamp
+.. autoclass:: TIMESTAMP
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSYear
+.. autoclass:: YEAR
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSText
+.. autoclass:: TEXT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSTinyText
+.. autoclass:: TINYTEXT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSMediumText
+.. autoclass:: MEDIUMTEXT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSLongText
+.. autoclass:: LONGTEXT
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSString
+.. autoclass:: VARCHAR
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSChar
+.. autoclass:: CHAR
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSNVarChar
+.. autoclass:: NVARCHAR
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSNChar
+.. autoclass:: NCHAR
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSVarBinary
+.. autoclass:: VARBINARY
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSBinary
+.. autoclass:: BINARY
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSBlob
+.. autoclass:: BLOB
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSTinyBlob
+.. autoclass:: TINYBLOB
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSMediumBlob
+.. autoclass:: MEDIUMBLOB
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSLongBlob
+.. autoclass:: LONGBLOB
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSEnum
+.. autoclass:: ENUM
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSSet
+.. autoclass:: SET
    :members: __init__
    :show-inheritance:
 
-.. autoclass:: MSBoolean
+.. autoclass:: BOOLEAN
    :members: __init__
    :show-inheritance:
 
index e81ecccb9b4e08a48bd42a2f117708c9b46c9b57..b5201c5590a1e4520416485b0ac365f0f7a3879a 100644 (file)
@@ -67,13 +67,6 @@ from sqlalchemy.engine import base as engine_base, default
 from sqlalchemy import types as sqltypes
 
 
-__all__ = [
-    'MaxString', 'MaxUnicode', 'MaxChar', 'MaxText', 'MaxInteger',
-    'MaxSmallInteger', 'MaxNumeric', 'MaxFloat', 'MaxTimestamp',
-    'MaxDate', 'MaxTime', 'MaxBoolean', 'MaxBlob',
-    ]
-
-
 class _StringType(sqltypes.String):
     _type = None
 
index fdec5741db79833a774e358ecc5a9ce0a5834eaa..8d695f988157f63efbcce9b6e7159543fa6f001c 100644 (file)
@@ -228,6 +228,9 @@ from sqlalchemy.sql import select, compiler, expression, operators as sql_operat
 from sqlalchemy.engine import default, base, reflection
 from sqlalchemy import types as sqltypes
 from decimal import Decimal as _python_Decimal
+from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, DECIMAL, NUMERIC, \
+                                FLOAT, TIMESTAMP
+            
 
 from sqlalchemy.dialects.mssql import information_schema as ischema
 
@@ -314,23 +317,26 @@ class MSNumeric(sqltypes.Numeric):
 
         return process
 
-class MSReal(sqltypes.Float):
+class REAL(sqltypes.Float):
     """A type for ``real`` numbers."""
 
     __visit_name__ = 'REAL'
 
     def __init__(self):
-        super(MSReal, self).__init__(precision=24)
+        super(REAL, self).__init__(precision=24)
+MSReal = REAL
 
-class MSTinyInteger(sqltypes.Integer):
+class TINYINT(sqltypes.Integer):
     __visit_name__ = 'TINYINT'
+MSTinyInteger = TINYINT
+
 
 # MSSQL DATE/TIME types have varied behavior, sometimes returning
 # strings.  MSDate/MSTime check for everything, and always
 # filter bind parameters into datetime objects (required by pyodbc,
 # not sure about other dialects).
 
-class MSDate(sqltypes.Date):
+class DATE(sqltypes.DATE):
     def bind_processor(self, dialect):
         def process(value):
             if type(value) == datetime.date:
@@ -349,11 +355,12 @@ class MSDate(sqltypes.Date):
             else:
                 return value
         return process
-    
-class MSTime(sqltypes.Time):
+MSDate = DATE
+
+class TIME(sqltypes.TIME):
     def __init__(self, precision=None, **kwargs):
         self.precision = precision
-        super(MSTime, self).__init__()
+        super(TIME, self).__init__()
 
     __zero_date = datetime.date(1900, 1, 1)
 
@@ -377,32 +384,42 @@ class MSTime(sqltypes.Time):
                 return value
         return process
 
+MSTime = TIME
+
 class _DateTimeBase(object):
     def bind_processor(self, dialect):
         def process(value):
+            # TODO: why ?
             if type(value) == datetime.date:
                 return datetime.datetime(value.year, value.month, value.day)
             else:
                 return value
         return process
 
-class MSDateTime(_DateTimeBase, sqltypes.DATETIME):
+class DATETIME(_DateTimeBase, sqltypes.DATETIME):
     pass
-    
-class MSSmallDateTime(_DateTimeBase, sqltypes.DateTime):
+MSDateTime = DATETIME
+
+class SMALLDATETIME(_DateTimeBase, sqltypes.DateTime):
     __visit_name__ = 'SMALLDATETIME'
+MSSmallDateTime = SMALLDATETIME
 
-class MSDateTime2(_DateTimeBase, sqltypes.DateTime):
+class DATETIME2(_DateTimeBase, sqltypes.DateTime):
     __visit_name__ = 'DATETIME2'
     
     def __init__(self, precision=None, **kwargs):
         self.precision = precision
+MSDateTime2 = DATETIME2
 
-class MSDateTimeOffset(sqltypes.TypeEngine):
+
+# TODO: is this not an Interval ?
+class DATETIMEOFFSET(sqltypes.TypeEngine):
     __visit_name__ = 'DATETIMEOFFSET'
     
     def __init__(self, precision=None, **kwargs):
         self.precision = precision
+MSDateTimeOffset = DATETIMEOFFSET
+
 
 class _StringType(object):
     """Base for MSSQL string types."""
@@ -424,7 +441,7 @@ class _StringType(object):
                            ', '.join(['%s=%r' % (k, params[k]) for k in params]))
 
 
-class MSText(_StringType, sqltypes.TEXT):
+class TEXT(_StringType, sqltypes.TEXT):
     """MSSQL TEXT type, for variable-length text up to 2^31 characters."""
 
     def __init__(self, *args, **kw):
@@ -437,8 +454,9 @@ class MSText(_StringType, sqltypes.TEXT):
         collation = kw.pop('collation', None)
         _StringType.__init__(self, collation)
         sqltypes.Text.__init__(self, *args, **kw)
+MSText = TEXT
 
-class MSNText(_StringType, sqltypes.UnicodeText):
+class NTEXT(_StringType, sqltypes.UnicodeText):
     """MSSQL NTEXT type, for variable-length unicode text up to 2^30
     characters."""
 
@@ -455,10 +473,10 @@ class MSNText(_StringType, sqltypes.UnicodeText):
         _StringType.__init__(self, collation)
         length = kwargs.pop('length', None)
         sqltypes.UnicodeText.__init__(self, length, **kwargs)
+MSNText = NTEXT
 
 
-
-class MSString(_StringType, sqltypes.VARCHAR):
+class VARCHAR(_StringType, sqltypes.VARCHAR):
     """MSSQL VARCHAR type, for variable-length non-Unicode data with a maximum
     of 8,000 characters."""
 
@@ -496,8 +514,9 @@ class MSString(_StringType, sqltypes.VARCHAR):
         collation = kw.pop('collation', None)
         _StringType.__init__(self, collation)
         sqltypes.VARCHAR.__init__(self, *args, **kw)
+MSString = VARCHAR
 
-class MSNVarchar(_StringType, sqltypes.NVARCHAR):
+class NVARCHAR(_StringType, sqltypes.NVARCHAR):
     """MSSQL NVARCHAR type.
 
     For variable-length unicode character data up to 4,000 characters."""
@@ -514,9 +533,9 @@ class MSNVarchar(_StringType, sqltypes.NVARCHAR):
         collation = kw.pop('collation', None)
         _StringType.__init__(self, collation)
         sqltypes.NVARCHAR.__init__(self, *args, **kw)
+MSNVarchar = NVARCHAR
 
-
-class MSChar(_StringType, sqltypes.CHAR):
+class CHAR(_StringType, sqltypes.CHAR):
     """MSSQL CHAR type, for fixed-length non-Unicode data with a maximum
     of 8,000 characters."""
 
@@ -554,9 +573,9 @@ class MSChar(_StringType, sqltypes.CHAR):
         collation = kw.pop('collation', None)
         _StringType.__init__(self, collation)
         sqltypes.CHAR.__init__(self, *args, **kw)
+MSChar = CHAR
 
-
-class MSNChar(_StringType, sqltypes.NCHAR):
+class NCHAR(_StringType, sqltypes.NCHAR):
     """MSSQL NCHAR type.
 
     For fixed-length unicode character data up to 4,000 characters."""
@@ -573,19 +592,23 @@ class MSNChar(_StringType, sqltypes.NCHAR):
         collation = kw.pop('collation', None)
         _StringType.__init__(self, collation)
         sqltypes.NCHAR.__init__(self, *args, **kw)
+MSNChar = NCHAR
 
-class MSBinary(sqltypes.Binary):
+class BINARY(sqltypes.Binary):
     __visit_name__ = 'BINARY'
+MSBinary = BINARY
 
-class MSVarBinary(sqltypes.Binary):
+class VARBINARY(sqltypes.Binary):
     __visit_name__ = 'VARBINARY'
-
+MSVarBinary = VARBINARY
         
-class MSImage(sqltypes.Binary):
+class IMAGE(sqltypes.Binary):
     __visit_name__ = 'IMAGE'
+MSImage = IMAGE
 
-class MSBit(sqltypes.TypeEngine):
+class BIT(sqltypes.TypeEngine):
     __visit_name__ = 'BIT'
+MSBit = BIT
     
 class MSBoolean(sqltypes.Boolean):
     def result_processor(self, dialect):
@@ -607,18 +630,21 @@ class MSBoolean(sqltypes.Boolean):
                 return value and True or False
         return process
 
-class MSMoney(sqltypes.TypeEngine):
+class MONEY(sqltypes.TypeEngine):
     __visit_name__ = 'MONEY'
+MSMoney = MONEY
 
-class MSSmallMoney(MSMoney):
+class SMALLMONEY(MSMoney):
     __visit_name__ = 'SMALLMONEY'
+MSSmallMoney = SMALLMONEY
 
-
-class MSUniqueIdentifier(sqltypes.TypeEngine):
+class UNIQUEIDENTIFIER(sqltypes.TypeEngine):
     __visit_name__ = "UNIQUEIDENTIFIER"
+MSUniqueIdentifier = UNIQUEIDENTIFIER
 
-class MSVariant(sqltypes.TypeEngine):
+class SQL_VARIANT(sqltypes.TypeEngine):
     __visit_name__ = 'SQL_VARIANT'
+MSVariant = SQL_VARIANT
 
 class MSTypeCompiler(compiler.GenericTypeCompiler):
     def _extend(self, spec, type_):
@@ -819,42 +845,42 @@ class MSExecutionContext(default.DefaultExecutionContext):
 
 colspecs = {
     sqltypes.Numeric : MSNumeric,
-    sqltypes.DateTime : MSDateTime,
-    sqltypes.Date : MSDate,
-    sqltypes.Time : MSTime,
+    sqltypes.DateTime : DATETIME,
+    sqltypes.Date : DATE,
+    sqltypes.Time : TIME,
     sqltypes.Boolean : MSBoolean,
 }
 
 ischema_names = {
-    'int' : sqltypes.INTEGER,
-    'bigint': sqltypes.BigInteger,
-    'smallint' : sqltypes.SmallInteger,
-    'tinyint' : MSTinyInteger,
-    'varchar' : MSString,
-    'nvarchar' : MSNVarchar,
-    'char' : MSChar,
-    'nchar' : MSNChar,
-    'text' : MSText,
-    'ntext' : MSNText,
-    'decimal' : sqltypes.DECIMAL,
-    'numeric' : sqltypes.NUMERIC,
-    'float' : sqltypes.FLOAT,
-    'datetime' : sqltypes.DATETIME,
-    'datetime2' : MSDateTime2,
-    'datetimeoffset' : MSDateTimeOffset,
-    'date': sqltypes.DATE,
-    'time': MSTime,
-    'smalldatetime' : MSSmallDateTime,
-    'binary' : MSBinary,
-    'varbinary' : MSVarBinary,
-    'bit': sqltypes.Boolean,
-    'real' : MSReal,
-    'image' : MSImage,
-    'timestamp': sqltypes.TIMESTAMP,
-    'money': MSMoney,
-    'smallmoney': MSSmallMoney,
-    'uniqueidentifier': MSUniqueIdentifier,
-    'sql_variant': MSVariant,
+    'int' : INTEGER,
+    'bigint': BIGINT,
+    'smallint' : SMALLINT,
+    'tinyint' : TINYINT,
+    'varchar' : VARCHAR,
+    'nvarchar' : NVARCHAR,
+    'char' : CHAR,
+    'nchar' : NCHAR,
+    'text' : TEXT,
+    'ntext' : NTEXT,
+    'decimal' : DECIMAL,
+    'numeric' : NUMERIC,
+    'float' : FLOAT,
+    'datetime' : DATETIME,
+    'datetime2' : DATETIME2,
+    'datetimeoffset' : DATETIMEOFFSET,
+    'date': DATE,
+    'time': TIME,
+    'smalldatetime' : SMALLDATETIME,
+    'binary' : BINARY,
+    'varbinary' : VARBINARY,
+    'bit': BIT,
+    'real' : REAL,
+    'image' : IMAGE,
+    'timestamp': TIMESTAMP,
+    'money': MONEY,
+    'smallmoney': SMALLMONEY,
+    'uniqueidentifier': UNIQUEIDENTIFIER,
+    'sql_variant': SQL_VARIANT,
 }
 
 class MSSQLCompiler(compiler.SQLCompiler):
index de315ab4591ad8748a3ba2e0c5b1cf3bba6cf2b4..3ea033fb52f9bf7ae5a948c74ca4e6d1c67b3adf 100644 (file)
@@ -23,8 +23,8 @@ then you will need to import them from this module::
 
   Table('mytable', metadata,
         Column('id', Integer, primary_key=True),
-        Column('ittybittyblob', mysql.MSTinyBlob),
-        Column('biggy', mysql.MSBigInteger(unsigned=True)))
+        Column('ittybittyblob', mysql.TINYBLOB),
+        Column('biggy', mysql.BIGINT(unsigned=True)))
 
 All standard MySQL column types are supported.  The OpenGIS types are
 available for use via table reflection but have no special support or mapping
@@ -190,16 +190,7 @@ from sqlalchemy.engine import reflection
 from sqlalchemy.engine import base as engine_base, default
 from sqlalchemy import types as sqltypes
 
-
-__all__ = (
-    'MSBigInteger', 'MSMediumInteger', 'MSBinary', 'MSBit', 'MSBlob', 'MSBoolean',
-    'MSChar', 'MSDate', 'MSDateTime', 'MSDecimal', 'MSDouble',
-    'MSEnum', 'MSFloat', 'MSInteger', 'MSLongBlob', 'MSLongText',
-    'MSMediumBlob', 'MSMediumText', 'MSNChar', 'MSNVarChar',
-    'MSNumeric', 'MSSet', 'MSSmallInteger', 'MSString', 'MSText',
-    'MSTime', 'MSTimeStamp', 'MSTinyBlob', 'MSTinyInteger',
-    'MSTinyText', 'MSVarBinary', 'MSYear' )
-
+from sqlalchemy.types import DATE, DATETIME
 
 RESERVED_WORDS = set(
     ['accessible', 'add', 'all', 'alter', 'analyze','and', 'as', 'asc',
@@ -254,25 +245,62 @@ SET_RE = re.compile(
 class _NumericType(object):
     """Base for MySQL numeric types."""
 
-    def __init__(self, kw):
+    def __init__(self, **kw):
         self.unsigned = kw.pop('unsigned', False)
         self.zerofill = kw.pop('zerofill', False)
+        super(_NumericType, self).__init__(**kw)
+        
+class _FloatType(_NumericType, sqltypes.Float):
+    def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
+        if isinstance(self, (REAL, DOUBLE)) and \
+            (
+                (precision is None and scale is not None) or
+                (precision is not None and scale is None)
+            ):
+           raise exc.ArgumentError(
+               "You must specify both precision and scale or omit "
+               "both altogether.")
+
+        super(_FloatType, self).__init__(precision=precision, asdecimal=asdecimal, **kw)
+        self.scale = scale
+
+class _DecimalType(_NumericType):
+    def bind_processor(self, dialect):
+        return None
+
+    def result_processor(self, dialect):
+        # TODO: this behavior might by MySQLdb specific,
+        # i.e. that Decimals are returned by the DBAPI
+        if not self.asdecimal:
+            def process(value):
+                if isinstance(value, decimal.Decimal):
+                    return float(value)
+                else:
+                    return value
+            return process
+        else:
+            return None
 
+class _IntegerType(_NumericType, sqltypes.Integer):
+    def __init__(self, display_width=None, **kw):
+        self.display_width = display_width
+        super(_IntegerType, self).__init__(**kw)
 
-class _StringType(object):
+class _StringType(sqltypes.String):
     """Base for MySQL string types."""
 
     def __init__(self, charset=None, collation=None,
                  ascii=False, unicode=False, binary=False,
-                 national=False, **kwargs):
+                 national=False, **kw):
         self.charset = charset
         # allow collate= or collation=
-        self.collation = kwargs.get('collate', collation)
+        self.collation = kw.pop('collate', collation)
         self.ascii = ascii
         self.unicode = unicode
         self.binary = binary
         self.national = national
-
+        super(_StringType, self).__init__(**kw)
+        
     def __repr__(self):
         attributes = inspect.getargspec(self.__init__)[0][1:]
         attributes.extend(inspect.getargspec(_StringType.__init__)[0][1:])
@@ -287,7 +315,18 @@ class _StringType(object):
                            ', '.join(['%s=%r' % (k, params[k]) for k in params]))
 
 
-class MSNumeric(sqltypes.Numeric, _NumericType):
+class _BinaryType(sqltypes.Binary):
+    """Base for MySQL binary types."""
+
+    def result_processor(self, dialect):
+        def process(value):
+            if value is None:
+                return None
+            else:
+                return util.buffer(value)
+        return process
+
+class NUMERIC(_DecimalType, sqltypes.NUMERIC):
     """MySQL NUMERIC type."""
     
     __visit_name__ = 'NUMERIC'
@@ -308,25 +347,10 @@ class MSNumeric(sqltypes.Numeric, _NumericType):
           numeric.
 
         """
-        _NumericType.__init__(self, kw)
-        sqltypes.Numeric.__init__(self, precision, scale, asdecimal=asdecimal, **kw)
+        super(NUMERIC, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal, **kw)
 
-    def bind_processor(self, dialect):
-        return None
 
-    def result_processor(self, dialect):
-        if not self.asdecimal:
-            def process(value):
-                if isinstance(value, decimal.Decimal):
-                    return float(value)
-                else:
-                    return value
-            return process
-        else:
-            return None
-
-
-class MSDecimal(MSNumeric):
+class DECIMAL(_DecimalType, sqltypes.DECIMAL):
     """MySQL DECIMAL type."""
     
     __visit_name__ = 'DECIMAL'
@@ -347,10 +371,10 @@ class MSDecimal(MSNumeric):
           numeric.
 
         """
-        super(MSDecimal, self).__init__(precision, scale, asdecimal=asdecimal, **kw)
-
+        super(DECIMAL, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal, **kw)
 
-class MSDouble(sqltypes.Float, _NumericType):
+    
+class DOUBLE(_FloatType):
     """MySQL DOUBLE type."""
 
     __visit_name__ = 'DOUBLE'
@@ -371,19 +395,9 @@ class MSDouble(sqltypes.Float, _NumericType):
           numeric.
 
         """
-        if ((precision is None and scale is not None) or
-            (precision is not None and scale is None)):
-            raise exc.ArgumentError(
-                "You must specify both precision and scale or omit "
-                "both altogether.")
-
-        _NumericType.__init__(self, kw)
-        sqltypes.Float.__init__(self, asdecimal=asdecimal, **kw)
-        self.scale = scale
-        self.precision = precision
+        super(DOUBLE, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal, **kw)
 
-
-class MSReal(MSDouble):
+class REAL(_FloatType):
     """MySQL REAL type."""
 
     __visit_name__ = 'REAL'
@@ -404,10 +418,9 @@ class MSReal(MSDouble):
           numeric.
 
         """
-        MSDouble.__init__(self, precision, scale, asdecimal, **kw)
-
+        super(REAL, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal, **kw)
 
-class MSFloat(sqltypes.Float, _NumericType):
+class FLOAT(_FloatType, sqltypes.FLOAT):
     """MySQL FLOAT type."""
 
     __visit_name__ = 'FLOAT'
@@ -428,16 +441,12 @@ class MSFloat(sqltypes.Float, _NumericType):
           numeric.
 
         """
-        _NumericType.__init__(self, kw)
-        sqltypes.Float.__init__(self, asdecimal=asdecimal, **kw)
-        self.scale = scale
-        self.precision = precision
+        super(FLOAT, self).__init__(precision=precision, scale=scale, asdecimal=asdecimal, **kw)
 
     def bind_processor(self, dialect):
         return None
 
-
-class MSInteger(sqltypes.Integer, _NumericType):
+class INTEGER(_IntegerType, sqltypes.INTEGER):
     """MySQL INTEGER type."""
 
     __visit_name__ = 'INTEGER'
@@ -455,16 +464,9 @@ class MSInteger(sqltypes.Integer, _NumericType):
           numeric.
 
         """
-        if 'length' in kw:
-            util.warn_deprecated("'length' is deprecated for MSInteger and subclasses.  Use 'display_width'.")
-            self.display_width = kw.pop('length')
-        else:
-            self.display_width = display_width
-        _NumericType.__init__(self, kw)
-        sqltypes.Integer.__init__(self, **kw)
-
+        super(INTEGER, self).__init__(display_width=display_width, **kw)
 
-class MSBigInteger(MSInteger):
+class BIGINT(_IntegerType, sqltypes.BIGINT):
     """MySQL BIGINTEGER type."""
 
     __visit_name__ = 'BIGINT'
@@ -482,10 +484,9 @@ class MSBigInteger(MSInteger):
           numeric.
 
         """
-        super(MSBigInteger, self).__init__(display_width, **kw)
+        super(BIGINT, self).__init__(display_width=display_width, **kw)
 
-
-class MSMediumInteger(MSInteger):
+class MEDIUMINT(_IntegerType):
     """MySQL MEDIUMINTEGER type."""
 
     __visit_name__ = 'MEDIUMINT'
@@ -503,10 +504,9 @@ class MSMediumInteger(MSInteger):
           numeric.
 
         """
-        super(MSMediumInteger, self).__init__(display_width, **kw)
-
+        super(MEDIUMINT, self).__init__(display_width=display_width, **kw)
 
-class MSTinyInteger(MSInteger):
+class TINYINT(_IntegerType):
     """MySQL TINYINT type."""
 
     __visit_name__ = 'TINYINT'
@@ -528,10 +528,9 @@ class MSTinyInteger(MSInteger):
           numeric.
 
         """
-        super(MSTinyInteger, self).__init__(display_width, **kw)
+        super(TINYINT, self).__init__(display_width=display_width, **kw)
 
-
-class MSSmallInteger(sqltypes.SmallInteger, MSInteger):
+class SMALLINT(_IntegerType, sqltypes.SMALLINT):
     """MySQL SMALLINTEGER type."""
 
     __visit_name__ = 'SMALLINT'
@@ -549,12 +548,9 @@ class MSSmallInteger(sqltypes.SmallInteger, MSInteger):
           numeric.
 
         """
-        self.display_width = display_width
-        _NumericType.__init__(self, kw)
-        sqltypes.SmallInteger.__init__(self, **kw)
+        super(SMALLINT, self).__init__(display_width=display_width, **kw)
 
-
-class MSBit(sqltypes.TypeEngine):
+class BIT(sqltypes.TypeEngine):
     """MySQL BIT type.
 
     This type is for MySQL 5.0.3 or greater for MyISAM, and 5.0.5 or greater for
@@ -584,21 +580,7 @@ class MSBit(sqltypes.TypeEngine):
             return value
         return process
 
-# TODO: probably don't need datetime/date types since no behavior changes
-
-class MSDateTime(sqltypes.DateTime):
-    """MySQL DATETIME type."""
-    
-    __visit_name__ = 'DATETIME'
-
-
-class MSDate(sqltypes.Date):
-    """MySQL DATE type."""
-    __visit_name__ = 'DATE'
-
-
-
-class MSTime(sqltypes.Time):
+class TIME(sqltypes.TIME):
     """MySQL TIME type."""
 
     __visit_name__ = 'TIME'
@@ -612,28 +594,11 @@ class MSTime(sqltypes.Time):
                 return None
         return process
 
-class MSTimeStamp(sqltypes.TIMESTAMP):
-    """MySQL TIMESTAMP type.
-
-    To signal the orm to automatically re-select modified rows to retrieve the
-    updated timestamp, add a ``server_default`` to your
-    :class:`~sqlalchemy.Column` specification::
-
-        from sqlalchemy.databases import mysql
-        Column('updated', mysql.MSTimeStamp,
-               server_default=sql.text('CURRENT_TIMESTAMP')
-              )
-
-    The full range of MySQL 4.1+ TIMESTAMP defaults can be specified in
-    the the default::
-
-        server_default=sql.text('CURRENT TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')
-
-    """
+class TIMESTAMP(sqltypes.TIMESTAMP):
+    """MySQL TIMESTAMP type."""
     __visit_name__ = 'TIMESTAMP'
 
-
-class MSYear(sqltypes.TypeEngine):
+class YEAR(sqltypes.TypeEngine):
     """MySQL YEAR type, for single byte storage of years 1901-2155."""
 
     __visit_name__ = 'YEAR'
@@ -641,13 +606,12 @@ class MSYear(sqltypes.TypeEngine):
     def __init__(self, display_width=None):
         self.display_width = display_width
 
-
-class MSText(_StringType, sqltypes.Text):
+class TEXT(_StringType, sqltypes.TEXT):
     """MySQL TEXT type, for text up to 2^16 characters."""
 
     __visit_name__ = 'TEXT'
 
-    def __init__(self, length=None, **kwargs):
+    def __init__(self, length=None, **kw):
         """Construct a TEXT.
 
         :param length: Optional, if provided the server may optimize storage
@@ -675,12 +639,9 @@ class MSText(_StringType, sqltypes.Text):
           only the collation of character data.
 
         """
-        _StringType.__init__(self, **kwargs)
-        sqltypes.Text.__init__(self, length,
-                               kwargs.get('convert_unicode', False), kwargs.get('assert_unicode', None))
-
+        super(TEXT, self).__init__(length=length, **kw)
 
-class MSTinyText(MSText):
+class TINYTEXT(_StringType):
     """MySQL TINYTEXT type, for text up to 2^8 characters."""
 
     __visit_name__ = 'TINYTEXT'
@@ -709,11 +670,9 @@ class MSTinyText(MSText):
           only the collation of character data.
 
         """
+        super(TINYTEXT, self).__init__(**kwargs)
 
-        super(MSTinyText, self).__init__(**kwargs)
-
-
-class MSMediumText(MSText):
+class MEDIUMTEXT(_StringType):
     """MySQL MEDIUMTEXT type, for text up to 2^24 characters."""
 
     __visit_name__ = 'MEDIUMTEXT'
@@ -742,9 +701,9 @@ class MSMediumText(MSText):
           only the collation of character data.
 
         """
-        super(MSMediumText, self).__init__(**kwargs)
+        super(MEDIUMTEXT, self).__init__(**kwargs)
 
-class MSLongText(MSText):
+class LONGTEXT(_StringType):
     """MySQL LONGTEXT type, for text up to 2^32 characters."""
 
     __visit_name__ = 'LONGTEXT'
@@ -773,11 +732,10 @@ class MSLongText(MSText):
           only the collation of character data.
 
         """
-        super(MSLongText, self).__init__(**kwargs)
-
-
+        super(LONGTEXT, self).__init__(**kwargs)
 
-class MSString(_StringType, sqltypes.String):
+    
+class VARCHAR(_StringType, sqltypes.VARCHAR):
     """MySQL VARCHAR type, for variable-length character data."""
 
     __visit_name__ = 'VARCHAR'
@@ -806,12 +764,9 @@ class MSString(_StringType, sqltypes.String):
           only the collation of character data.
 
         """
-        _StringType.__init__(self, **kwargs)
-        sqltypes.String.__init__(self, length,
-                                 kwargs.get('convert_unicode', False), kwargs.get('assert_unicode', None))
-
+        super(VARCHAR, self).__init__(length=length, **kwargs)
 
-class MSChar(_StringType, sqltypes.CHAR):
+class CHAR(_StringType, sqltypes.CHAR):
     """MySQL CHAR type, for fixed-length character data."""
 
     __visit_name__ = 'CHAR'
@@ -829,13 +784,9 @@ class MSChar(_StringType, sqltypes.CHAR):
           compatible with the national character set.
 
         """
-        _StringType.__init__(self, **kwargs)
-        sqltypes.CHAR.__init__(self, length,
-                               kwargs.get('convert_unicode', False))
-
-
+        super(CHAR, self).__init__(length=length, **kwargs)
 
-class MSNVarChar(_StringType, sqltypes.String):
+class NVARCHAR(_StringType, sqltypes.NVARCHAR):
     """MySQL NVARCHAR type.
 
     For variable-length character data in the server's configured national
@@ -858,13 +809,10 @@ class MSNVarChar(_StringType, sqltypes.String):
 
         """
         kwargs['national'] = True
-        _StringType.__init__(self, **kwargs)
-        sqltypes.String.__init__(self, length,
-                                 kwargs.get('convert_unicode', False))
+        super(NVARCHAR, self).__init__(length=length, **kwargs)
 
 
-
-class MSNChar(_StringType, sqltypes.CHAR):
+class NCHAR(_StringType, sqltypes.NCHAR):
     """MySQL NCHAR type.
 
     For fixed-length character data in the server's configured national
@@ -887,23 +835,11 @@ class MSNChar(_StringType, sqltypes.CHAR):
 
         """
         kwargs['national'] = True
-        _StringType.__init__(self, **kwargs)
-        sqltypes.CHAR.__init__(self, length,
-                               kwargs.get('convert_unicode', False))
-
+        super(NCHAR, self).__init__(length=length, **kwargs)
 
-class _BinaryType(sqltypes.Binary):
-    """Base for MySQL binary types."""
 
-    def result_processor(self, dialect):
-        def process(value):
-            if value is None:
-                return None
-            else:
-                return util.buffer(value)
-        return process
 
-class MSVarBinary(_BinaryType):
+class VARBINARY(_BinaryType):
     """MySQL VARBINARY type, for variable length binary data."""
 
     __visit_name__ = 'VARBINARY'
@@ -914,10 +850,9 @@ class MSVarBinary(_BinaryType):
         :param length: Maximum data length, in characters.
 
         """
-        super(MSVarBinary, self).__init__(length, **kw)
-
+        super(VARBINARY, self).__init__(length=length, **kw)
 
-class MSBinary(_BinaryType):
+class BINARY(_BinaryType):
     """MySQL BINARY type, for fixed length binary data"""
 
     __visit_name__ = 'BINARY'
@@ -932,17 +867,9 @@ class MSBinary(_BinaryType):
           specified, this will generate a BLOB.  This usage is deprecated.
 
         """
-        super(MSBinary, self).__init__(length, **kw)
+        super(BINARY, self).__init__(length=length, **kw)
 
-    def result_processor(self, dialect):
-        def process(value):
-            if value is None:
-                return None
-            else:
-                return util.buffer(value)
-        return process
-
-class MSBlob(_BinaryType):
+class BLOB(_BinaryType, sqltypes.BLOB):
     """MySQL BLOB type, for binary data up to 2^16 bytes"""
 
     __visit_name__ = 'BLOB'
@@ -955,39 +882,25 @@ class MSBlob(_BinaryType):
           ``length`` characters.
 
         """
-        super(MSBlob, self).__init__(length, **kw)
+        super(BLOB, self).__init__(length=length, **kw)
 
-    def result_processor(self, dialect):
-        def process(value):
-            if value is None:
-                return None
-            else:
-                return util.buffer(value)
-        return process
-
-    def __repr__(self):
-        return "%s()" % self.__class__.__name__
 
-
-class MSTinyBlob(MSBlob):
+class TINYBLOB(_BinaryType):
     """MySQL TINYBLOB type, for binary data up to 2^8 bytes."""
     
     __visit_name__ = 'TINYBLOB'
 
-
-class MSMediumBlob(MSBlob):
+class MEDIUMBLOB(_BinaryType):
     """MySQL MEDIUMBLOB type, for binary data up to 2^24 bytes."""
 
     __visit_name__ = 'MEDIUMBLOB'
 
-
-class MSLongBlob(MSBlob):
+class LONGBLOB(_BinaryType):
     """MySQL LONGBLOB type, for binary data up to 2^32 bytes."""
 
     __visit_name__ = 'LONGBLOB'
 
-
-class MSEnum(MSString):
+class ENUM(_StringType):
     """MySQL ENUM type."""
 
     __visit_name__ = 'ENUM'
@@ -1078,10 +991,10 @@ class MSEnum(MSString):
 
         self.strict = kw.pop('strict', False)
         length = max([len(v) for v in self.enums] + [0])
-        super(MSEnum, self).__init__(length, **kw)
+        super(ENUM, self).__init__(length=length, **kw)
 
     def bind_processor(self, dialect):
-        super_convert = super(MSEnum, self).bind_processor(dialect)
+        super_convert = super(ENUM, self).bind_processor(dialect)
         def process(value):
             if self.strict and value is not None and value not in self.enums:
                 raise exc.InvalidRequestError('"%s" not a valid value for '
@@ -1092,7 +1005,7 @@ class MSEnum(MSString):
                 return value
         return process
 
-class MSSet(MSString):
+class SET(_StringType):
     """MySQL SET type."""
 
     __visit_name__ = 'SET'
@@ -1141,7 +1054,7 @@ class MSSet(MSString):
 
         self.values = strip_values
         length = max([len(v) for v in strip_values] + [0])
-        super(MSSet, self).__init__(length, **kw)
+        super(SET, self).__init__(length=length, **kw)
 
     def result_processor(self, dialect):
         def process(value):
@@ -1165,7 +1078,7 @@ class MSSet(MSString):
         return process
 
     def bind_processor(self, dialect):
-        super_convert = super(MSSet, self).bind_processor(dialect)
+        super_convert = super(SET, self).bind_processor(dialect)
         def process(value):
             if value is None or isinstance(value, (int, long, basestring)):
                 pass
@@ -1181,8 +1094,7 @@ class MSSet(MSString):
                 return value
         return process
 
-
-class MSBoolean(sqltypes.Boolean):
+class BOOLEAN(sqltypes.Boolean):
     """MySQL BOOLEAN type."""
 
     __visit_name__ = 'BOOLEAN'
@@ -1206,63 +1118,83 @@ class MSBoolean(sqltypes.Boolean):
                 return value and True or False
         return process
 
+# old names
+MSBoolean = BOOLEAN
+MSSet = SET
+MSEnum = ENUM
+MSLongBlob = LONGBLOB
+MSMediumBlob = MEDIUMBLOB
+MSTinyBlob = TINYBLOB
+MSBlob = BLOB
+MSBinary = BINARY
+MSVarBinary = VARBINARY
+MSNChar = NCHAR
+MSNVarChar = NVARCHAR
+MSChar = CHAR
+MSString = VARCHAR
+MSLongText = LONGTEXT
+MSMediumText = MEDIUMTEXT
+MSTinyText = TINYTEXT
+MSText = TEXT
+MSYear = YEAR
+MSTimeStamp = TIMESTAMP
+MSTime = TIME
+MSBit = BIT
+MSSmallInteger = SMALLINT
+MSTinyInteger = TINYINT
+MSMediumInteger = MEDIUMINT
+MSBigInteger = BIGINT
+MSNumeric = NUMERIC
+MSDecimal = DECIMAL
+MSDouble = DOUBLE
+MSReal = REAL
+MSFloat = FLOAT
+MSInteger = INTEGER
+
 colspecs = {
-    sqltypes.Integer: MSInteger,
-    sqltypes.SmallInteger: MSSmallInteger,
-    sqltypes.Numeric: MSNumeric,
-    sqltypes.Float: MSFloat,
-    sqltypes.DateTime: MSDateTime,
-    sqltypes.Date: MSDate,
-    sqltypes.Time: MSTime,
-    sqltypes.String: MSString,
-    sqltypes.Binary: MSBlob,
-    sqltypes.Boolean: MSBoolean,
-    sqltypes.Text: MSText,
-    sqltypes.CHAR: MSChar,
-    sqltypes.NCHAR: MSNChar,
-    sqltypes.TIMESTAMP: MSTimeStamp,
-    sqltypes.BLOB: MSBlob,
-    MSDouble: MSDouble,
-    MSReal: MSReal,
-    _BinaryType: _BinaryType,
+    sqltypes.Numeric: NUMERIC,
+    sqltypes.Float: FLOAT,
+    sqltypes.Binary: _BinaryType,
+    sqltypes.Boolean: BOOLEAN,
+    sqltypes.Time: TIME,
 }
 
 # Everything 3.23 through 5.1 excepting OpenGIS types.
 ischema_names = {
-    'bigint': MSBigInteger,
-    'binary': MSBinary,
-    'bit': MSBit,
-    'blob': MSBlob,
-    'boolean':MSBoolean,
-    'char': MSChar,
-    'date': MSDate,
-    'datetime': MSDateTime,
-    'decimal': MSDecimal,
-    'double': MSDouble,
-    'enum': MSEnum,
-    'fixed': MSDecimal,
-    'float': MSFloat,
-    'int': MSInteger,
-    'integer': MSInteger,
-    'longblob': MSLongBlob,
-    'longtext': MSLongText,
-    'mediumblob': MSMediumBlob,
-    'mediumint': MSMediumInteger,
-    'mediumtext': MSMediumText,
-    'nchar': MSNChar,
-    'nvarchar': MSNVarChar,
-    'numeric': MSNumeric,
-    'set': MSSet,
-    'smallint': MSSmallInteger,
-    'text': MSText,
-    'time': MSTime,
-    'timestamp': MSTimeStamp,
-    'tinyblob': MSTinyBlob,
-    'tinyint': MSTinyInteger,
-    'tinytext': MSTinyText,
-    'varbinary': MSVarBinary,
-    'varchar': MSString,
-    'year': MSYear,
+    'bigint': BIGINT,
+    'binary': BINARY,
+    'bit': BIT,
+    'blob': BLOB,
+    'boolean':BOOLEAN,
+    'char': CHAR,
+    'date': DATE,
+    'datetime': DATETIME,
+    'decimal': DECIMAL,
+    'double': DOUBLE,
+    'enum': ENUM,
+    'fixed': DECIMAL,
+    'float': FLOAT,
+    'int': INTEGER,
+    'integer': INTEGER,
+    'longblob': LONGBLOB,
+    'longtext': LONGTEXT,
+    'mediumblob': MEDIUMBLOB,
+    'mediumint': MEDIUMINT,
+    'mediumtext': MEDIUMTEXT,
+    'nchar': NCHAR,
+    'nvarchar': NVARCHAR,
+    'numeric': NUMERIC,
+    'set': SET,
+    'smallint': SMALLINT,
+    'text': TEXT,
+    'time': TIME,
+    'timestamp': TIMESTAMP,
+    'tinyblob': TINYBLOB,
+    'tinyint': TINYINT,
+    'tinytext': TINYTEXT,
+    'varbinary': VARBINARY,
+    'varchar': VARCHAR,
+    'year': YEAR,
 }
 
 class MySQLExecutionContext(default.DefaultExecutionContext):
@@ -1305,29 +1237,27 @@ class MySQLCompiler(compiler.SQLCompiler):
         
     def visit_typeclause(self, typeclause):
         type_ = typeclause.type.dialect_impl(self.dialect)
-        if isinstance(type_, MSInteger):
+        if isinstance(type_, sqltypes.Integer):
             if getattr(type_, 'unsigned', False):
                 return 'UNSIGNED INTEGER'
             else:
                 return 'SIGNED INTEGER'
-        elif isinstance(type_, (MSDecimal, MSDateTime, MSDate, MSTime)):
+        elif isinstance(type_, sqltypes.TIMESTAMP):
+            return 'DATETIME'
+        elif isinstance(type_, (sqltypes.DECIMAL, sqltypes.DateTime, sqltypes.Date, sqltypes.Time)):
             return self.dialect.type_compiler.process(type_)
-        elif isinstance(type_, MSText):
+        elif isinstance(type_, sqltypes.Text):
             return 'CHAR'
-        elif (isinstance(type_, _StringType) and not
-              isinstance(type_, (MSEnum, MSSet))):
+        elif (isinstance(type_, sqltypes.String) and not
+              isinstance(type_, (ENUM, SET))):
             if getattr(type_, 'length'):
                 return 'CHAR(%s)' % type_.length
             else:
                 return 'CHAR'
-        elif isinstance(type_, _BinaryType):
+        elif isinstance(type_, sqltypes.Binary):
             return 'BINARY'
-        elif isinstance(type_, MSNumeric):
+        elif isinstance(type_, NUMERIC):
             return self.dialect.type_compiler.process(type_).replace('NUMERIC', 'DECIMAL')
-        elif isinstance(type_, MSTimeStamp):
-            return 'DATETIME'
-        elif isinstance(type_, (MSDateTime, MSDate, MSTime)):
-            return self.dialect.type_compiler.process(type_)
         else:
             return None
 
@@ -1890,13 +1820,11 @@ class MySQLDialect(default.DefaultDialect):
 
     @reflection.cache
     def get_columns(self, connection, table_name, schema=None, **kw):
-
         parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
         return parsed_state.columns
 
     @reflection.cache
     def get_primary_keys(self, connection, table_name, schema=None, **kw):
-
         parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
         for key in parsed_state.keys:
             if key['type'] == 'PRIMARY':
@@ -1910,7 +1838,7 @@ class MySQLDialect(default.DefaultDialect):
 
         parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
         default_schema = None
-
+        
         fkeys = []
 
         for spec in parsed_state.constraints:
@@ -1982,13 +1910,15 @@ class MySQLDialect(default.DefaultDialect):
         return sql
 
     def _parsed_state_or_create(self, connection, table_name, schema=None, **kw):
-        if 'parsed_state' in kw:
-            return kw['parsed_state']
-        else:
-            return self._setup_parser(connection, table_name, schema)
+        return self._setup_parser(
+                        connection, 
+                        table_name, 
+                        schema, 
+                        info_cache=kw.get('info_cache', None)
+                    )
         
-    def _setup_parser(self, connection, table_name, schema=None):
-
+    @reflection.cache
+    def _setup_parser(self, connection, table_name, schema=None, **kw):
         charset = self._connection_charset
         try:
             parser = self.parser
index dff0f52fac469cfc1cc08aab91874202c13d5d7a..36ee65be1d22d8b101def5339cfdd2407f287765 100644 (file)
@@ -117,12 +117,33 @@ from sqlalchemy.engine import default, base, reflection
 from sqlalchemy.sql import compiler, visitors, expression
 from sqlalchemy.sql import operators as sql_operators, functions as sql_functions
 from sqlalchemy import types as sqltypes
-
+from sqlalchemy.types import VARCHAR, NVARCHAR, CHAR, DATE, DATETIME, \
+                BLOB, CLOB, TIMESTAMP, FLOAT
+                
 RESERVED_WORDS = set('''SHARE RAW DROP BETWEEN FROM DESC OPTION PRIOR LONG THEN DEFAULT ALTER IS INTO MINUS INTEGER NUMBER GRANT IDENTIFIED ALL TO ORDER ON FLOAT DATE HAVING CLUSTER NOWAIT RESOURCE ANY TABLE INDEX FOR UPDATE WHERE CHECK SMALLINT WITH DELETE BY ASC REVOKE LIKE SIZE RENAME NOCOMPRESS NULL GROUP VALUES AS IN VIEW EXCLUSIVE COMPRESS SYNONYM SELECT INSERT EXISTS NOT TRIGGER ELSE CREATE INTERSECT PCTFREE DISTINCT CONNECT SET MODE OF UNIQUE VARCHAR2 VARCHAR LOCK OR CHAR DECIMAL UNION PUBLIC AND START UID COMMENT'''.split()) 
 
-class OracleRaw(sqltypes.Binary):
+class RAW(sqltypes.Binary):
     pass
+OracleRaw = RAW
+
+class NCLOB(sqltypes.Text):
+    __visit_name__ = 'NCLOB'
+
+VARCHAR2 = VARCHAR
+NVARCHAR2 = NVARCHAR
 
+class NUMBER(sqltypes.Numeric):
+    __visit_name__ = 'NUMBER'
+    
+class BFILE(sqltypes.Binary):
+    __visit_name__ = 'BFILE'
+
+class DOUBLE_PRECISION(sqltypes.Numeric):
+    __visit_name__ = 'DOUBLE_PRECISION'
+
+class LONG(sqltypes.Text):
+    __visit_name__ = 'LONG'
+    
 class OracleBoolean(sqltypes.Boolean):
     def result_processor(self, dialect):
         def process(value):
@@ -148,20 +169,20 @@ colspecs = {
 }
 
 ischema_names = {
-    'VARCHAR2' : sqltypes.VARCHAR,
-    'NVARCHAR2' : sqltypes.NVARCHAR,
-    'CHAR' : sqltypes.CHAR,
-    'DATE' : sqltypes.DATE,
-    'DATETIME' : sqltypes.DATETIME,
-    'NUMBER' : sqltypes.Numeric,
-    'BLOB' : sqltypes.BLOB,
-    'BFILE' : sqltypes.Binary,
-    'CLOB' : sqltypes.CLOB,
-    'TIMESTAMP' : sqltypes.TIMESTAMP,
-    'RAW' : OracleRaw,
-    'FLOAT' : sqltypes.Float,
-    'DOUBLE PRECISION' : sqltypes.Numeric,
-    'LONG' : sqltypes.Text,
+    'VARCHAR2' : VARCHAR,
+    'NVARCHAR2' : NVARCHAR,
+    'CHAR' : CHAR,
+    'DATE' : DATE,
+    'DATETIME' : DATETIME,
+    'NUMBER' : NUMBER,
+    'BLOB' : BLOB,
+    'BFILE' : BFILE,
+    'CLOB' : CLOB,
+    'TIMESTAMP' : TIMESTAMP,
+    'RAW' : RAW,
+    'FLOAT' : FLOAT,
+    'DOUBLE PRECISION' : DOUBLE_PRECISION,
+    'LONG' : LONG,
 }
 
 
index 0612e8c3820b201bfe2ea9d659b8d18d4726debb..3c90ca0087777ac23d507aab163568e9a6453f8f 100644 (file)
@@ -35,12 +35,6 @@ from sqlalchemy import MetaData, Table, Column
 from sqlalchemy import String, Integer, SMALLINT, CHAR, ForeignKey
 from sqlalchemy.dialects.sybase.schema import *
 
-__all__ = [
-    'SybaseMoney', 'SybaseSmallMoney',
-    'SybaseUniqueIdentifier',
-    ]
-
-
 RESERVED_WORDS = set([
     "add", "all", "alter", "and",
     "any", "as", "asc", "backup",
index 63a1115d58cc565d64c703ee78adb540f8f5ec26..335311234f9e292033e40d10c49963d19c705574 100644 (file)
@@ -31,6 +31,44 @@ type is specifying a type *or* arguments that are not present generically, it sh
 match the real name of the type on that backend, in uppercase.  E.g. postgres.INET,
 mysql.ENUM, postgres.ARRAY.  
 
+Or follow this handy flowchart:
+
+     is the type in types.py as an UPPERCASE type ?
+        |     |
+        |    yes    --->   does your type need special behavior or arguments ?   no ---->  don't make a
+        |                   ^                     yes                                      type, make sure the dialect's
+        |                   no                     |                                       base.py imports the types.py
+        |                   |                      |                                       UPPERCASE name into its namespace
+        v                is it                     v
+        no  --------  a native  yes -----> build new type
+                       DB type?                    |
+                                                   v
+                                        is this type native to the database ?
+                                (i.e. BIT is native to MySQL, "Boolean" is *not* native to Oracle)
+                                         yes                               no
+                                          |                                 |
+                                          v                                 v
+                                name the type THE SAME                  name the type using
+                                as that of the DB,                      MixedCase, i.e.
+                                using UPPERCASE                         OracleBoolean
+                                (i.e. BIT, NCHAR, INTERVAL)                 |
+                                          |                                 |
+                                          +----------------+----------------+
+                                                           |
+                                                           v
+    the type should                         is the name of this type
+    subclass the                <----- yes  identical to an UPPERCASE name 
+    UPPERCASE                                         in types.py?
+    type in types.py                                      no
+    (i.e. class BLOB(types.BLOB))                         |
+                                                          v
+                                                  subclass the closest
+                                                  MixedCase type types.py,
+                                                  i.e. 
+                                                  class DATETIME2(types.DateTime),
+                                                  class BIT(types.TypeEngine)                                                          
+
+
 Ideally one should be able to specify a schema using names imported completely from a 
 dialect, all matching the real name on that backend:
 
index bb1f5019928d4484c884ec66b4c3e4e413774c43..e4dd1ed48914517bd6235f86455b2bea1ae564d8 100644 (file)
@@ -27,10 +27,14 @@ from sqlalchemy import schema as sa_schema
 
 @util.decorator
 def cache(fn, self, con, *args, **kw):
-    info_cache = kw.pop('info_cache', None)
+    info_cache = kw.get('info_cache', None)
     if info_cache is None:
         return fn(self, con, *args, **kw)
-    key = (fn.__name__, args, str(kw))
+    key = (
+            fn.__name__, 
+            tuple(a for a in args if isinstance(a, basestring)), 
+            tuple((k, v) for k, v in kw.iteritems() if isinstance(v, basestring))
+        )
     ret = info_cache.get(key)
     if ret is None:
         ret = fn(self, con, *args, **kw)
index 6e2f22c9ff9f3c528d677572da63da9fbd5729ea..965849df02bf007a464392f250d66baed8238284 100644 (file)
@@ -966,15 +966,6 @@ class CLOB(Text):
 
     __visit_name__ = 'CLOB'
 
-class NCLOB(Text):
-    """The NCLOB type.
-    
-    TODO: is this only Oracle ?
-    """
-
-    __visit_name__ = 'NCLOB'
-
-
 class VARCHAR(String):
     """The SQL VARCHAR type."""
 
index 44cfe11f2c832ec57fb7a5cc6be7f2698a60043c..fd70b79635353cffe582cd24330917a0435f0b15 100644 (file)
@@ -704,8 +704,8 @@ class TypesTest(TestBase, AssertsExecutionResults):
                  ( mysql.MSSmallInteger(4), mysql.MSSmallInteger(4), ),
                  ( mysql.MSMediumInteger(), mysql.MSMediumInteger(), ),
                  ( mysql.MSMediumInteger(8), mysql.MSMediumInteger(8), ),
-                 ( Binary(3), mysql.MSBlob(3), ),
-                 ( Binary(), mysql.MSBlob() ),
+                 ( Binary(3), mysql.TINYBLOB(), ),
+                 ( Binary(), mysql.BLOB() ),
                  ( mysql.MSBinary(3), mysql.MSBinary(3), ),
                  ( mysql.MSVarBinary(3),),
                  ( mysql.MSVarBinary(), mysql.MSBlob()),
@@ -933,8 +933,8 @@ class SQLTest(TestBase, AssertsCompiledSQL):
             (DateTime, "CAST(t.col AS DATETIME)"),
             (Date, "CAST(t.col AS DATE)"),
             (Time, "CAST(t.col AS TIME)"),
-            (m.MSDateTime, "CAST(t.col AS DATETIME)"),
-            (m.MSDate, "CAST(t.col AS DATE)"),
+            (DateTime, "CAST(t.col AS DATETIME)"),
+            (Date, "CAST(t.col AS DATE)"),
             (m.MSTime, "CAST(t.col AS TIME)"),
             (m.MSTimeStamp, "CAST(t.col AS DATETIME)"),
             (m.MSYear, "t.col"),
index 3d115b9a3d188fe5bd52ff450f7235900fd442f4..06451bbc4d83331d25807e9cbc3310db6a2a8787 100644 (file)
@@ -64,13 +64,16 @@ class ReflectionTest(TestBase, ComparesTables):
         t1 = Table('t1', meta, 
                 Column('id', sa.Integer, primary_key=True),
                 Column('t2id', sa.Integer, sa.ForeignKey('t2.id')),
-                Column('t3id', sa.Integer, sa.ForeignKey('t3.id'))
+                Column('t3id', sa.Integer, sa.ForeignKey('t3.id')),
+                test_needs_fk=True
         )
         t2 = Table('t2', meta, 
-                Column('id', sa.Integer, primary_key=True)
+                Column('id', sa.Integer, primary_key=True),
+                test_needs_fk=True
         )
         t3 = Table('t3', meta, 
-                Column('id', sa.Integer, primary_key=True)
+                Column('id', sa.Integer, primary_key=True),
+                test_needs_fk=True
         )
         meta.create_all()
         try:
index c3c331bed636ee7e7951e44f34d8d3e1cdb3b176..16a94110a88ffff1671d106a16fa0dc9d7ef274d 100644 (file)
@@ -38,17 +38,10 @@ class AdaptTest(TestBase):
         
         # TODO: migrate these tests to dialect modules
         
-        mysql_dialect = mysql.MySQLDialect()
         postgres_dialect = postgres.PGDialect()
         firebird_dialect = firebird.FBDialect()
 
         for dialect, start, test in [
-            (mysql_dialect, String(), mysql.MSString),
-            (mysql_dialect, VARCHAR(), mysql.MSString),
-            (mysql_dialect, String(50), mysql.MSString),
-            (mysql_dialect, Unicode(), mysql.MSString),
-            (mysql_dialect, UnicodeText(), mysql.MSText),
-            (mysql_dialect, NCHAR(), mysql.MSNChar),
             (postgres_dialect, String(), String),
             (postgres_dialect, VARCHAR(), String),
             (postgres_dialect, String(50), String),