]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
(no commit message)
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 17 Sep 2005 06:27:29 +0000 (06:27 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 17 Sep 2005 06:27:29 +0000 (06:27 +0000)
lib/sqlalchemy/mapper.py
lib/sqlalchemy/objectstore.py

index d3baa387abc52242607a2963b81498430e135101..fd6d50f211afcc825b9de9dbd007c4358800bf79 100644 (file)
@@ -153,7 +153,7 @@ class Mapper(object):
 
     def instances(self, cursor, db = None):
         result = util.HistoryArraySet()
-        cursor = engine.ResultProxy(cursor, echo = db.echo)
+        cursor = engine.ResultProxy(cursor, echo = db and db.echo)
         imap = {}
         while True:
             row = cursor.fetchone()
@@ -307,7 +307,7 @@ class Mapper(object):
     def _identity_key(self, row):
         return objectstore.get_row_key(row, self.class_, self.table, self.primary_keys[self.selectable])
 
-    def _instance(self, row, imap, result = None):
+    def _instance(self, row, imap, result = None, populate_existing = False):
         """pulls an object instance from the given row and appends it to the given result list.
         if the instance already exists in the given identity map, its not added.  in either
         case, executes all the property loaders on the instance to also process extra information
@@ -321,9 +321,16 @@ class Mapper(object):
             instance = objectstore.get(identitykey)
             if result is not None:
                 result.append_nohistory(instance)
-                
-            return instance
 
+            if populate_existing:
+                isnew = not imap.has_key(identitykey)
+                if isnew:
+                    imap[identitykey] = instance
+                for key, prop in self.props.iteritems():
+                    prop.execute(instance, row, identitykey, imap, isnew)
+
+            return instance
+                    
         # look in result-local identitymap for it.
         exists = imap.has_key(identitykey)      
         if not exists:
@@ -465,11 +472,11 @@ class PropertyLoader(MapperProperty):
             self.dependent = None
         def visit_binary(self, binary):
             if binary.operator == '=':
-                if binary.left.primary_key:
+                if isinstance(binary.left, schema.Column) and binary.left.primary_key:
                     if self.dependent is binary.left:
                         raise "bidirectional dependency not supported...specify foreignkey"
                     self.dependent = binary.right
-                elif binary.right.primary_key:
+                elif isinstance(binary.right, schema.Column) and binary.right.primary_key:
                     if self.dependent is binary.right:
                         raise "bidirectional dependency not supported...specify foreignkey"
                     self.dependent = binary.left
index b4d2ccff92216b220d21ac5ca691b2731b2536dc..f446d1b4c131ceec961558f37d9933381089e950 100644 (file)
@@ -220,26 +220,78 @@ class UnitOfWork(object):
     def commit(self, *objects):
         import sqlalchemy.mapper
 
-        self.commit_context = UOWTransaction()
+        commit_context = UOWTransaction(self)
         
         if len(objects):
             for obj in objects:
-                self.commit_context.append_task(obj)
+                commit_context.append_task(obj)
         else:
             for obj in [n for n in self.new] + [d for d in self.dirty]:
-                self.commit_context.append_task(obj)
+                commit_context.append_task(obj)
             for item in self.modified_lists:
                 obj = item.obj()
-                self.commit_context.append_task(obj)
+                commit_context.append_task(obj)
+
+        commit_context.execute()                   
+
+        # TODO: deleted stuff
+        
+        if self.parent:
+            uow.set(self.parent)
+            
+        
+            
+class UOWTransaction(object):
+    def __init__(self, uow):
+        self.uow = uow
+        self.mappers = {}
+        self.dependencies = {}
+        self.tasks = {}
+        self.saved_objects = util.HashSet()
+        self.saved_lists = util.HashSet()
+
+    def append_task(self, obj):
+        mapper = self.object_mapper(obj)
+        task = self.get_task_by_mapper(mapper)
+        task.objects.append(obj)
+
+    def get_task_by_mapper(self, mapper):
+        try:
+            return self.tasks[mapper]
+        except KeyError:
+            return self.tasks.setdefault(mapper, UOWTask(mapper))
+
+    # TODO: better interface for tasks with no object save, or multiple dependencies
+    def register_dependency(self, mapper, dependency, processor, stuff_to_process):
+        self.dependencies[(mapper, dependency)] = True
+        task = self.get_task_by_mapper(mapper)
+        if processor is not None:
+            task.dependencies.append((processor, stuff_to_process))
+
+    def register_saved_object(self, obj):
+        self.saved_objects.append(obj)
+
+    def register_saved_list(self, listobj):
+        self.saved_lists.append(listobj)
+
+    def object_mapper(self, obj):
+        import sqlalchemy.mapper
+        try:
+            return self.mappers[obj]
+        except KeyError:
+            mapper = sqlalchemy.mapper.object_mapper(obj)
+            self.mappers[obj] = mapper
+            return mapper
             
-        for task in self.commit_context.tasks.values():
+    def execute(self):
+        for task in self.tasks.values():
             task.mapper.register_dependencies(task.objects, self)
             
-        mapperlist = self.commit_context.tasks.values()
+        mapperlist = self.tasks.values()
         def compare(a, b):
-            if self.commit_context.dependencies.has_key((a.mapper, b.mapper)):
+            if self.dependencies.has_key((a.mapper, b.mapper)):
                 return -1
-            elif self.commit_context.dependencies.has_key((b.mapper, a.mapper)):
+            elif self.dependencies.has_key((b.mapper, a.mapper)):
                 return 1
             else:
                 return 0
@@ -255,55 +307,18 @@ class UnitOfWork(object):
                     processor.process_dependencies(stuff_to_process, self)
         except:
             raise
-            
-        for obj in self.commit_context.saved_objects:
-            mapper = sqlalchemy.mapper.object_mapper(obj)
+
+        for obj in self.saved_objects:
+            mapper = self.object_mapper(obj)
             obj._instance_key = mapper.identity_key(obj)
-            self.register_clean(obj)
+            self.uow.register_clean(obj)
 
-        for obj in self.commit_context.saved_lists:
+        for obj in self.saved_lists:
             try:
-                del self.modified_lists[obj]
+                del self.uow.modified_lists[obj]
             except KeyError:
                 pass
 
-        self.commit_context = None
-        # TODO: deleted stuff
-        
-        if self.parent:
-            uow.set(self.parent)
-            
-    def register_saved_object(self, obj):
-        self.commit_context.saved_objects.append(obj)
-
-    def register_saved_list(self, listobj):
-        self.commit_context.saved_lists.append(listobj)
-        
-    # TODO: better interface for tasks with no object save, or multiple dependencies
-    def register_dependency(self, mapper, dependency, processor, stuff_to_process):
-        self.commit_context.dependencies[(mapper, dependency)] = True
-        task = self.commit_context.get_task_by_mapper(mapper)
-        if processor is not None:
-            task.dependencies.append((processor, stuff_to_process))
-            
-class UOWTransaction(object):
-    def __init__(self):
-        self.dependencies = {}
-        self.tasks = {}
-        self.saved_objects = util.HashSet()
-        self.saved_lists = util.HashSet()
-
-    def append_task(self, obj):
-        import sqlalchemy.mapper
-        mapper = sqlalchemy.mapper.object_mapper(obj)
-        task = self.get_task_by_mapper(mapper)
-        task.objects.append(obj)
-
-    def get_task_by_mapper(self, mapper):
-        try:
-            return self.tasks[mapper]
-        except KeyError:
-            return self.tasks.setdefault(mapper, UOWTask(mapper))
         
 class UOWTask(object):
     def __init__(self, mapper):