]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
factored out "inheriting_tasks" member of UOWTask. all "polymorphic traversal" is...
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 6 Jun 2006 00:02:48 +0000 (00:02 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 6 Jun 2006 00:02:48 +0000 (00:02 +0000)
lib/sqlalchemy/orm/unitofwork.py
lib/sqlalchemy/orm/uowdumper.py

index b8c6939f76774f1e9409d76f64294c1cb77af895..bf97f3b7961c91e8ebc065ce77752159cb8e2e28 100644 (file)
@@ -587,10 +587,6 @@ class UOWTask(object):
         # dependency processing, and before pre-delete processing and deletes
         self.childtasks = []
         
-        # a list of UOWTasks that correspond to Mappers which are inheriting
-        # mappers of this UOWTask's Mapper
-        #self.inheriting_tasks = util.Set()
-
         # whether this UOWTask is circular, meaning it holds a second
         # UOWTask that contains a special row-based dependency structure.
         self.circular = None
@@ -642,41 +638,38 @@ class UOWTask(object):
             pass
 
     def _save_objects(self, trans):
-        self.mapper.save_obj(self.tosave_objects, trans)
-        for task in self.inheriting_tasks:
-            task._save_objects(trans)
+        for task in self.polymorphic_tasks():
+            task.mapper.save_obj(task.tosave_objects, trans)
     def _delete_objects(self, trans):
-        self.mapper.delete_obj(self.todelete_objects, trans)
-        for task in self.inheriting_tasks:
-            task._delete_objects(trans)
+        for task in self.polymorphic_tasks():
+            task.mapper.delete_obj(task.todelete_objects, trans)
     def _execute_dependencies(self, trans):
-        for dep in self.dependencies:
-            dep.execute(trans, False)
-        for task in self.inheriting_tasks:
-            task._execute_dependencies(trans)
-        for dep in self.dependencies:
-            dep.execute(trans, True)
+        alltasks = list(self.polymorphic_tasks())
+        for task in alltasks:
+            for dep in task.dependencies:
+                dep.execute(trans, False)
+        alltasks.reverse()
+        for task in alltasks:
+            for dep in task.dependencies:
+                dep.execute(trans, True)
     def _execute_childtasks(self, trans):
-        for child in self.childtasks:
-            child.execute(trans)
-        for task in self.inheriting_tasks:
-            task._execute_childtasks(trans)
+        for task in self.polymorphic_tasks():
+            for child in task.childtasks:
+                child.execute(trans)
     def _execute_cyclical_dependencies(self, trans, isdelete):
-        for dep in self.cyclical_dependencies:
-            dep.execute(trans, isdelete)
-        for task in self.inheriting_tasks:
-            task._execute_cyclical_dependencies(trans, isdelete)
+        for task in self.polymorphic_tasks():
+            for dep in task.cyclical_dependencies:
+                dep.execute(trans, isdelete)
     def _execute_per_element_childtasks(self, trans, isdelete):
-        if isdelete:
-            for element in self.todelete_elements:
-                for task in element.childtasks:
-                    task.execute(trans)
-        else:
-            for element in self.tosave_elements:
-                for task in element.childtasks:
-                    task.execute(trans)
-        for task in self.inheriting_tasks:
-            task._execute_per_element_childtasks(trans, isdelete)
+        for ptask in self.polymorphic_tasks():
+            if isdelete:
+                for element in ptask.todelete_elements:
+                    for task in element.childtasks:
+                        task.execute(trans)
+            else:
+                for element in ptask.tosave_elements:
+                    for task in element.childtasks:
+                        task.execute(trans)
             
     def execute(self, trans):
         """executes this UOWTask.  saves objects to be saved, processes all dependencies
@@ -701,22 +694,20 @@ class UOWTask(object):
         self._execute_per_element_childtasks(trans, True)
         self._delete_objects(trans)
 
-    def _inheriting_tasks(self):
-        """returns a collection of UOWTasks whos mappers are immediate descendants of this UOWTask's mapper,
-        *or* are descendants of this UOWTask's mapper where the intervening anscestor mappers do not have
-        corresponding UOWTasks in the current UOWTransaction.
+    def polymorphic_tasks(self):
+        """returns an iteration consisting of this UOWTask, and all UOWTasks whose 
+        mappers are inheriting descendants of this UOWTask's mapper.  UOWTasks are returned in order
+        of their hierarchy to each other, meaning if UOWTask B's mapper inherits from UOWTask A's 
+        mapper, then UOWTask B will appear after UOWTask A in the iteration."""
         
-        Consider mapper A, which has descendant mappers B1 and B2.  B1 has descendant mapper C1, B2 has descendant 
-        mapper C2.  UOWTasks are present for mappers A, B1, C1 and C2.
+        # first us
+        yield self
         
-            A->
-                B1->C1
-                (B2)->C2
-                
-        calling inheriting_tasks for A's UOWTask yields B1, C2.  calling inheriting_tasks for B1's UOWTask yields C1.        
-        """
+        # "circular dependency" tasks aren't polymorphic
         if self.circular_parent is not None:
             return
+
+        # closure to locate the "next level" of inherited mapper UOWTasks
         def _tasks_by_mapper(mapper):
             for m in mapper._inheriting_mappers:
                 inherit_task = self.uowtransaction.tasks.get(m, None)
@@ -725,33 +716,30 @@ class UOWTask(object):
                 else:
                     for t in _tasks_by_mapper(m):
                         yield t
-        for t in _tasks_by_mapper(self.mapper):
-            yield t
-    inheriting_tasks = property(_inheriting_tasks)
-    
-    def polymorphic_tasks(self):
-        """returns a collection of all UOWTasks whos mappers are descendants of this UOWTask's mapper."""
-        yield self
-        for task in self.inheriting_tasks:
+        
+        # main yield loop
+        for task in _tasks_by_mapper(self.mapper):
             for t in task.polymorphic_tasks():
                 yield t
                 
     def contains_object(self, obj, polymorphic=False):
-        if obj in self.objects:
-            return True
         if polymorphic:
-            for task in self.inheriting_tasks:
-                if task.contains_object(obj, polymorphic=True):
+            for task in self.polymorphic_tasks():
+                if obj in task.objects:
                     return True
+        else:
+            if obj in self.objects:
+                return True
         return False
         
     def get_elements(self, polymorphic=False):
-        for rec in self.objects.values():
-            yield rec
         if polymorphic:
-            for task in self.inheriting_tasks:
-                for rec in task.get_elements(polymorphic=True):
+            for task in self.polymorphic_tasks():
+                for rec in task.objects.values():
                     yield rec
+        else:
+            for rec in self.objects.values():
+                yield rec
     
     polymorphic_tosave_elements = property(lambda self: [rec for rec in self.get_elements(polymorphic=True) if not rec.isdelete])
     polymorphic_todelete_elements = property(lambda self: [rec for rec in self.get_elements(polymorphic=True) if rec.isdelete])
index ebe8535e1dc8cee7b78a80dc3ceeca866b128d93..ab7a1449a275d4e2f43e07b9f2db32c3e247f66d 100644 (file)
@@ -102,44 +102,43 @@ class UOWDumper(object):
                 return ""
 
         def _dump_saveelements(task):
-            for rec in task.tosave_elements:
-                if rec.listonly:
-                    continue
-                if self.verbose:
-                    header(self.buf, self._indent() + "  |- Save elements"+ _inheritance_tag(task) + "\n")
-                self.buf.write(self._indent() + "  |- " + self._repr_task_element(rec)  + "\n")
-            for t in task.inheriting_tasks:
-                _dump_saveelements(t)
+            for ptask in task.polymorphic_tasks():
+                for rec in ptask.tosave_elements:
+                    if rec.listonly:
+                        continue
+                    if self.verbose:
+                        header(self.buf, self._indent() + "  |- Save elements"+ _inheritance_tag(task) + "\n")
+                    self.buf.write(self._indent() + "  |- " + self._repr_task_element(rec)  + "\n")
 
         def _dump_deleteelements(task):
-            for rec in task.todelete_elements:
-                if rec.listonly:
-                    continue
-                if self.verbose:
-                    header(self.buf, self._indent() + "  |- Delete elements"+ _inheritance_tag(task) + "\n")
-                self.buf.write(self._indent() + "  |- " + self._repr_task_element(rec) + "\n")
-            for t in task.inheriting_tasks:
-                _dump_deleteelements(t)
+            for ptask in task.polymorphic_tasks():
+                for rec in ptask.todelete_elements:
+                    if rec.listonly:
+                        continue
+                    if self.verbose:
+                        header(self.buf, self._indent() + "  |- Delete elements"+ _inheritance_tag(ptask) + "\n")
+                    self.buf.write(self._indent() + "  |- " + self._repr_task_element(rec) + "\n")
 
         def _dump_dependencies(task):
-            for dep in task.dependencies:
-                if self.verbose:
-                    header(self.buf, self._indent() + "  |- Save dependencies" + _inheritance_tag(task) + "\n")
-                self._dump_processor(dep, False)
-            for t in task.inheriting_tasks:
-                _dump_dependencies(t)
-            for dep in task.dependencies:
-                if self.verbose:
-                    header(self.buf, self._indent() + "  |- Delete dependencies" + _inheritance_tag(task) + "\n")
-                self._dump_processor(dep, True)
+            alltasks = list(task.polymorphic_tasks())
+            for task in alltasks:
+                for dep in task.dependencies:
+                    if self.verbose:
+                        header(self.buf, self._indent() + "  |- Save dependencies" + _inheritance_tag(task) + "\n")
+                    self._dump_processor(dep, False)
+            alltasks.reverse()
+            for task in alltasks:
+                for dep in task.dependencies:
+                    if self.verbose:
+                        header(self.buf, self._indent() + "  |- Delete dependencies" + _inheritance_tag(task) + "\n")
+                    self._dump_processor(dep, True)
     
         def _dump_childtasks(task):
-            for child in task.childtasks:
-                if self.verbose:
-                    header(self.buf, self._indent() + "  |- Child tasks" + _inheritance_tag(task) + "\n")
-                self._dump(child, indent = self.indent + 1)
-            for t in task.inheriting_tasks:
-                _dump_childtasks(t)
+            for ptask in task.polymorphic_tasks():
+                for child in ptask.childtasks:
+                    if self.verbose:
+                        header(self.buf, self._indent() + "  |- Child tasks" + _inheritance_tag(task) + "\n")
+                    self._dump(child, indent = self.indent + 1)
         
         if starttask.circular is not None:
             self._dump(starttask.circular, indent=self.indent, circularparent=starttask)