]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- removed "extension()" MapperOption
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 3 Oct 2006 21:08:14 +0000 (21:08 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 3 Oct 2006 21:08:14 +0000 (21:08 +0000)
- TypeEngine objects can report on DBAPI types
- added set_input_sizes() to default dialect
- oracle dialect gets Timestamp type added, may need to call
set_input_sizes() to make it work with sub-second resolution [ticket:304]

lib/sqlalchemy/databases/oracle.py
lib/sqlalchemy/engine/default.py
lib/sqlalchemy/orm/__init__.py
lib/sqlalchemy/types.py

index e6d331109c27ff8072d51a4e52c5674d923b93d8..2a548fb782aeb1f5bc6d36d0b6dd7b447a61c6ea 100644 (file)
@@ -38,6 +38,13 @@ class OracleDateTime(sqltypes.DateTime):
 # Oracle does not allow milliseconds in DATE
 # Oracle does not support TIME columns
 
+# only if cx_oracle contains TIMESTAMP
+class OracleTimestamp(sqltypes.DateTime):
+    def get_col_spec(self):
+        return "TIMESTAMP"
+    def get_dbapi_type(self, dialect):
+        return dialect.TIMESTAMP
+        
 class OracleText(sqltypes.TEXT):
     def get_col_spec(self):
         return "CLOB"
@@ -79,17 +86,18 @@ colspecs = {
     sqltypes.Binary : OracleBinary,
     sqltypes.Boolean : OracleBoolean,
     sqltypes.TEXT : OracleText,
+    sqltypes.TIMESTAMP : OracleTimestamp,
     sqltypes.CHAR: OracleChar,
 }
 
-
 ischema_names = {
     'VARCHAR2' : OracleString,
     'DATE' : OracleDateTime,
     'DATETIME' : OracleDateTime,
     'NUMBER' : OracleNumeric,
     'BLOB' : OracleBinary,
-    'CLOB' : OracleText
+    'CLOB' : OracleText,
+    'TIMESTAMP' : OracleTimestamp
 }
 
 constraintSQL = """SELECT
@@ -122,8 +130,10 @@ def descriptor():
     ]}
 
 class OracleExecutionContext(default.DefaultExecutionContext):
-    pass
-    
+    def pre_exec(self, engine, proxy, compiled, parameters):
+        super(OracleExecutionContext).pre_exec(engine, proxy, compiled, parameters)
+        #self.set_input_sizes(proxy(), parameters)
+        
 class OracleDialect(ansisql.ANSIDialect):
     def __init__(self, use_ansi=True, module=None, threaded=True, **kwargs):
         self.use_ansi = use_ansi
@@ -132,6 +142,7 @@ class OracleDialect(ansisql.ANSIDialect):
             self.module = cx_Oracle
         else:
             self.module = module
+        self.supports_timestamp = hasattr(self.module, 'TIMESTAMP' )
         ansisql.ANSIDialect.__init__(self, **kwargs)
 
     def dbapi(self):
index dd9a0d278c6f5911a8ddcb82f8b770d92bcca6be..4a3791c35b5eb70ead9afbf5c214170a299ec169 100644 (file)
@@ -164,6 +164,29 @@ class DefaultExecutionContext(base.ExecutionContext):
         return self._last_updated_params                
     def lastrow_has_defaults(self):
         return self._lastrow_has_defaults
+    def set_input_sizes(self, cursor, parameters):
+        """given a cursor and ClauseParameters, call the appropriate style of 
+        setinputsizes() on the cursor, using DBAPI types from the bind parameter's
+        TypeEngine objects."""
+        if isinstance(parameters, list):
+            plist = parameters
+        else:
+            plist = [parameters]
+        if self.dialect.positional:
+            inputsizes = []
+            for params in plist[0]:
+                for key in params.positional:
+                    typeengine = params.binds[key].type
+                    inputsizes.append(typeengine.get_dbapi_type(self.dialect.module))
+            cursor.setinputsizes(*inputsizes)
+        else:
+            inputsizes = {}
+            for params in plist[0]:
+                for key in params.keys():
+                    typeengine = params.binds[key].type
+                    inputsizes[key] = typeengine.get_dbapi_type(self.dialect.module)
+            cursor.setinputsizes(**inputsizes)
+        
     def _process_defaults(self, engine, proxy, compiled, parameters):
         """INSERT and UPDATE statements, when compiled, may have additional columns added to their
         VALUES and SET lists corresponding to column defaults/onupdates that are present on the 
index ee0a6a4f1260b98ca9053a94043ecbbc1e90f7b8..b00151e9431fd66a71bb0a78a8f672dacd51185d 100644 (file)
@@ -17,7 +17,7 @@ import properties, strategies
 from session import Session as create_session
 
 __all__ = ['relation', 'backref', 'eagerload', 'lazyload', 'noload', 'deferred', 'defer', 'undefer',
-        'mapper', 'clear_mappers', 'sql', 'extension', 'class_mapper', 'object_mapper', 'MapperExtension', 'Query', 
+        'mapper', 'clear_mappers', 'sql', 'class_mapper', 'object_mapper', 'MapperExtension', 'Query', 
         'cascade_mappers', 'polymorphic_union', 'create_session', 'synonym', 'EXT_PASS'
         ]
 
@@ -58,11 +58,6 @@ def clear_mapper(m):
     new primary mapper."""
     del mapper_registry[m.hash_key]
 
-def extension(ext):
-    """returns a MapperOption that will add the given MapperExtension to the 
-    mapper returned by mapper.options()."""
-    return ExtensionOption(ext)
-    
 def eagerload(name):
     """returns a MapperOption that will convert the property of the given name
     into an eager load."""
index 31c6a232ed06c27b8d82e99e54f5c165adcabe40..9ce36cffdbda0c35aed9aa2786b9b7c237ffe731 100644 (file)
@@ -33,6 +33,11 @@ class AbstractType(object):
         return x is y
     def is_mutable(self):
         return False
+    def get_dbapi_type(self, dbapi):
+        """return the corresponding type object from the underlying DBAPI, if any.
+        
+        this can be useful for calling setinputsizes(), for example."""
+        return None
             
 class TypeEngine(AbstractType):
     def __init__(self, *args, **params):
@@ -91,6 +96,8 @@ class TypeDecorator(AbstractType):
         instance = self.__class__.__new__(self.__class__)
         instance.__dict__.update(self.__dict__)
         return instance
+    def get_dbapi_type(self, dbapi):
+        return self.impl.get_dbapi_type(dbapi)
 
 class MutableType(object):
     """a mixin that marks a Type as holding a mutable object"""
@@ -158,7 +165,9 @@ class String(TypeEngine):
             return value
         else:
             return value.decode(dialect.encoding)
-            
+    def get_dbapi_type(self, dbapi):
+        return dbapi.STRING
+        
 class Unicode(TypeDecorator):
     impl = String
     def convert_bind_param(self, value, dialect):
@@ -174,8 +183,9 @@ class Unicode(TypeDecorator):
         
 class Integer(TypeEngine):
     """integer datatype"""
-    pass
-    
+    def get_dbapi_type(self, dbapi):
+        return dbapi.NUMBER
+        
 class SmallInteger(Integer):
     """ smallint datatype """
     pass
@@ -187,6 +197,8 @@ class Numeric(TypeEngine):
         self.length = length
     def adapt(self, impltype):
         return impltype(precision=self.precision, length=self.length)
+    def get_dbapi_type(self, dbapi):
+        return dbapi.NUMBER
 
 class Float(Numeric):
     def __init__(self, precision = 10):
@@ -200,10 +212,13 @@ class DateTime(TypeEngine):
         self.timezone = timezone
     def adapt(self, impltype):
         return impltype(timezone=self.timezone)
+    def get_dbapi_type(self, dbapi):
+        return dbapi.DATETIME
         
 class Date(TypeEngine):
     """implements a type for datetime.date() objects"""
-    pass
+    def get_dbapi_type(self, dbapi):
+        return dbapi.DATETIME
 
 class Time(TypeEngine):
     """implements a type for datetime.time() objects"""
@@ -211,6 +226,8 @@ class Time(TypeEngine):
         self.timezone = timezone
     def adapt(self, impltype):
         return impltype(timezone=self.timezone)
+    def get_dbapi_type(self, dbapi):
+        return dbapi.DATETIME
 
 class Binary(TypeEngine):
     def __init__(self, length=None):
@@ -224,6 +241,8 @@ class Binary(TypeEngine):
         return value
     def adapt(self, impltype):
         return impltype(length=self.length)
+    def get_dbapi_type(self, dbapi):
+        return dbapi.BINARY
 
 class PickleType(MutableType, TypeDecorator):
     impl = Binary