]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Provisional fix for #51, very slightly adapted from the patch posted in the ticket...
authorJason Pellerin <jpellerin@gmail.com>
Sun, 5 Feb 2006 14:43:10 +0000 (14:43 +0000)
committerJason Pellerin <jpellerin@gmail.com>
Sun, 5 Feb 2006 14:43:10 +0000 (14:43 +0000)
lib/sqlalchemy/ext/proxy.py
test/proxy_engine.py

index ae5f40cfa6ec5ac498afdfa964c0e64b00a310b0..6139164bf1d6268f72095e688a5c3dd77aec1254 100644 (file)
@@ -57,7 +57,9 @@ class ProxyEngine(object):
         # something for oid column name, and the call happens too early
         # to proxy, so effecticely no oids are allowed when using
         # proxy engine
-        return None
+        if self.storage.engine is None:
+            return None
+        return self.get_engine().oid_column_name()
     
     def columnimpl(self, column):
         """Proxy point: return a ProxyColumnImpl
@@ -100,47 +102,37 @@ class ProxyTableImpl(sql.TableImpl):
 
     engine = property(lambda self: self._engine.engine)
 
-class ProxyTypeEngine(object):
-    """Proxy type engine; defers engine access to ProxyEngine
+class ProxyType(object):
+    """ProxyType base class; used by ProxyTypeEngine to construct proxying
+    types    
     """
     def __init__(self, engine, typeobj):
         self._engine = engine
         self.typeobj = typeobj
-        
-    engine = property(lambda self: self._engine.engine)    
-
-    def __getattr__(self, attr):
-        # NOTE:
-        # profiling so far indicates that caching the type_descriptor
-        # results is more trouble than it's worth
-        return getattr(self.engine.type_descriptor(self.typeobj), attr)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 
+    def __getattribute__(self, attr):
+        if attr.startswith('__') and attr.endswith('__'):
+            return object.__getattribute__(self, attr)
+        
+        engine = object.__getattribute__(self, '_engine').engine
+        typeobj = object.__getattribute__(self, 'typeobj')        
+        return getattr(engine.type_descriptor(typeobj), attr)
 
+    def __repr__(self):
+        return '<Proxy %s>' % (object.__getattribute__(self, 'typeobj'))
+    
+class ProxyTypeEngine(object):
+    """Proxy type engine; creates dynamic proxy type subclass that is instance
+    of actual type, but proxies engine-dependant operations through the proxy
+    engine.    
+    """
+    def __new__(cls, engine, typeobj):
+        """Create a new subclass of ProxyType and typeobj
+        so that internal isinstance() calls will get the expected result.
+        """
+        if isinstance(typeobj, type):
+            typeclass = typeobj
+        else:
+            typeclass = typeobj.__class__
+        typed = type('ProxyTypeHelper', (ProxyType, typeclass), {})
+        return typed(engine, typeobj)    
index 7d508481e54765c7de223950082ad6108eb7c546..150752f65b2d9aeba802dd846a96ccb7569fff8c 100644 (file)
@@ -27,7 +27,6 @@ class ProxyEngineTest(PersistTest):
         objectstore.clear()
         
     def test_engine_connect(self):
-
         # connect to a real engine
         module_engine.connect(testbase.db_uri)
         users.create()
@@ -110,7 +109,6 @@ class ProxyEngineTest(PersistTest):
     def test_table_singleton_a(self):
         """set up for table singleton check
         """
-
         #
         # For this 'test', create a proxy engine instance, connect it
         # to a real engine, and make it do some work
@@ -131,7 +129,6 @@ class ProxyEngineTest(PersistTest):
         """check that a table on a 2nd proxy engine instance gets 2nd table
         instance
         """
-
         #
         # Now create a new proxy engine instance and attach the same
         # table as the first test. This should result in 2 table instances,
@@ -163,7 +160,7 @@ class ProxyEngineTest(PersistTest):
                 return 'a'
             
             def type_descriptor(self, typeobj):
-                if typeobj == type(1):
+                if typeobj == types.Integer:
                     return TypeEngineX2()
                 else:
                     return TypeEngineSTR()
@@ -193,19 +190,65 @@ class ProxyEngineTest(PersistTest):
         engine = ProxyEngine()
         engine.storage.engine = EngineA()
 
-        a = engine.type_descriptor(type(1))
+        a = engine.type_descriptor(sqltypes.Integer)
         assert a.convert_bind_param(12, engine) == 24
         assert a.convert_bind_param([1,2,3], engine) == [1, 2, 3, 1, 2, 3]
 
-        a2 = engine.type_descriptor(type('hi'))
+        a2 = engine.type_descriptor(sqltypes.String)
         assert a2.convert_bind_param(12, engine) == "'12'"
         assert a2.convert_bind_param([1,2,3], engine) == "'[1, 2, 3]'"
         
         engine.storage.engine = EngineB()
-        b = engine.type_descriptor(type(1))
+        b = engine.type_descriptor(sqltypes.Integer)
         assert b.convert_bind_param(12, engine) == 'monkey'
         assert b.convert_bind_param([1,2,3], engine) == 'monkey'
         
+
+    def test_type_engine_autoincrement(self):
+        engine = ProxyEngine()
+        dogs = Table('dogs', engine,
+                     Column('dog_id', Integer, primary_key=True),
+                     Column('breed', String),
+                     Column('name', String))
+        
+        class Dog(object):
+            pass
+        
+        assign_mapper(Dog, dogs)
+
+        engine.connect(testbase.db_uri)
+        dogs.create()
+
+        spot = Dog()
+        spot.breed = 'beagle'
+        spot.name = 'Spot'
+
+        rover = Dog()
+        rover.breed = 'spaniel'
+        rover.name = 'Rover'
+        
+        objectstore.commit()
+        
+        assert spot.dog_id > 0, "Spot did not get an id"
+        assert rover.dog_id != spot.dog_id
+        
+    def  test_type_proxy_schema_gen(self):
+        from sqlalchemy.databases.postgres import PGSchemaGenerator
+
+        engine = ProxyEngine()
+        lizards = Table('lizards', engine,
+                        Column('id', Integer, primary_key=True),
+                        Column('name', String))
+        
+        # this doesn't really CONNECT to pg, just establishes pg as the
+        # actual engine so that we can determine that it gets the right
+        # answer
+        engine.connect('postgres://database=test&port=5432&host=127.0.0.1&user=scott&password=tiger')
+
+        sg = PGSchemaGenerator(engine.proxy())
+        id_spec = sg.get_column_specification(lizards.c.id)
+        assert id_spec == 'id SERIAL NOT NULL PRIMARY KEY'
+        
         
 if __name__ == "__main__":
     testbase.main()