def branch(self, task):
return UOWDependencyProcessor(self.processor, task)
+class UOWExecutor(object):
+ def execute(self, trans, task, isdelete=None):
+ if isdelete is not True:
+ self.execute_save_steps(trans, task)
+ if isdelete is not False:
+ self.execute_delete_steps(trans, task)
+
+ def save_objects(self, trans, task):
+ task._save_objects(trans)
+
+ def delete_objects(self, trans, task):
+ task._delete_objects(trans)
+
+ def execute_dependency(self, trans, dep, isdelete):
+ dep.execute(trans, isdelete)
+
+ def execute_save_steps(self, trans, task):
+ if task.circular is not None:
+ self.execute_save_steps(trans, task.circular)
+ else:
+ self.save_objects(trans, task)
+ self.execute_cyclical_dependencies(trans, task, False)
+ self.execute_per_element_childtasks(trans, task, False)
+ self.execute_dependencies(trans, task, False)
+ self.execute_dependencies(trans, task, True)
+ self.execute_childtasks(trans, task, False)
+
+ def execute_delete_steps(self, trans, task):
+ if task.circular is not None:
+ self.execute_delete_steps(trans, task.circular)
+ else:
+ self.execute_cyclical_dependencies(trans, task, True)
+ self.execute_childtasks(trans, task, True)
+ self.execute_per_element_childtasks(trans, task, True)
+ self.delete_objects(trans, task)
+
+ def execute_dependencies(self, trans, task, isdelete=None):
+ alltasks = list(task.polymorphic_tasks())
+ if isdelete is not True:
+ for task in alltasks:
+ for dep in task.dependencies:
+ self.execute_dependency(trans, dep, False)
+ if isdelete is not False:
+ alltasks.reverse()
+ for task in alltasks:
+ for dep in task.dependencies:
+ self.execute_dependency(trans, dep, True)
+
+ def execute_childtasks(self, trans, task, isdelete=None):
+ for polytask in task.polymorphic_tasks():
+ for child in polytask.childtasks:
+ self.execute(trans, child, isdelete)
+
+ def execute_cyclical_dependencies(self, trans, task, isdelete):
+ for polytask in task.polymorphic_tasks():
+ for dep in polytask.cyclical_dependencies:
+ self.execute_dependency(trans, dep, isdelete)
+
+ def execute_per_element_childtasks(self, trans, task, isdelete):
+ for polytask in task.polymorphic_tasks():
+ for element in polytask.tosave_elements + polytask.todelete_elements:
+ for child in element.childtasks:
+ self.execute(trans, child, isdelete)
+
+
class UOWTask(object):
"""represents the full list of objects that are to be saved/deleted by a specific Mapper."""
def __init__(self, uowtransaction, mapper, circular_parent=None):
def _delete_objects(self, trans):
for task in self.polymorphic_tasks():
task.mapper.delete_obj(task.todelete_objects, trans)
- def _execute_dependencies(self, trans):
- 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 task in self.polymorphic_tasks():
- for child in task.childtasks:
- child.execute(trans)
- def _execute_cyclical_dependencies(self, 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):
- 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
that have been registered, and deletes objects to be deleted. """
- # a "circular" task is a circularly-sorted collection of UOWTask/UOWTaskElements
- # derived from the components of this UOWTask, which accounts for inter-row dependencies.
- # if one was created for this UOWTask, it replaces the execution for this UOWTask.
- if self.circular is not None:
- self.circular.execute(trans)
- return
-
- # TODO: add a visitation system to the UOW classes and have this execution called
- # from a separate executor object ? (would also handle dumping)
-
- self._save_objects(trans)
- self._execute_cyclical_dependencies(trans, False)
- self._execute_per_element_childtasks(trans, False)
- self._execute_dependencies(trans)
- self._execute_cyclical_dependencies(trans, True)
- self._execute_childtasks(trans)
- self._execute_per_element_childtasks(trans, True)
- self._delete_objects(trans)
+ UOWExecutor().execute(trans, self)
def polymorphic_tasks(self):
"""returns an iteration consisting of this UOWTask, and all UOWTasks whose
+import unitofwork
"""dumps out a string representation of a UOWTask structure"""
-class UOWDumper(object):
+class UOWDumper(unitofwork.UOWExecutor):
def __init__(self, task, buf, verbose=False):
self.verbose = verbose
self.indent = 0
self.task = task
self.buf = buf
+ self.starttask = task
+ #self.execute(None, task)
self._dump(task)
+
+ # execute stuff is UNDER CONSTRUCTION
+
+ def execute(self, trans, task, isdelete=None):
+ oldstarttask = self.starttask
+ self.starttask = task
+ try:
+ i = self._indent()
+ if len(i):
+ i = i[0:-1] + "-"
+ if task.circular is not None:
+ self.buf.write(self._indent() + "\n")
+ self.buf.write(i + " " + self._repr_task(task))
+ self.buf.write("->circular->" + self._repr_task(task.circular))
+ else:
+ self.buf.write(self._indent() + "\n")
+ self.buf.write(i + " " + self._repr_task(task))
+ self.buf.write("\n")
+ super(UOWDumper, self).execute(trans, task, isdelete)
+ finally:
+ self.starttask = oldstarttask
+
+ def save_objects(self, trans, task):
+ for rec in task.tosave_elements:
+ if rec.listonly:
+ continue
+ if self.verbose:
+ header(self.buf, self._indent() + " |- Save elements"+ self._inheritance_tag(task) + "\n")
+ self.buf.write(self._indent() + " |- " + self._repr_task_element(rec) + "\n")
+
+ def delete_objects(self, trans, task):
+ for rec in task.todelete_elements:
+ if rec.listonly:
+ continue
+ if self.verbose:
+ header(self.buf, self._indent() + " |- Delete elements"+ self._inheritance_tag(task) + "\n")
+ self.buf.write(self._indent() + " |- " + self._repr_task_element(rec) + "\n")
+
+ def _inheritance_tag(self, task):
+ if not self.verbose:
+ return ""
+ elif task is not self.starttask:
+ return (" (inheriting task %s)" % self._repr_task(task))
+ else:
+ return ""
+
+ def execute_dependency(self, transaction, dep, isdelete):
+ #self.buf.write()
+ pass
+
+ def execute_save_steps(self, trans, task):
+ super(UOWDumper, self).execute_save_steps(trans, task)
+
+ def execute_delete_steps(self, trans, task):
+ super(UOWDumper, self).execute_delete_steps(trans, task)
+
+ def execute_dependencies(self, trans, task, isdelete=None):
+ super(UOWDumper, self).execute_dependencies(trans, task, isdelete)
+
+ def execute_childtasks(self, trans, task, isdelete=None):
+ super(UOWDumper, self).execute_childtasks(trans, task, isdelete)
+
+ def execute_cyclical_dependencies(self, trans, task, isdelete):
+ super(UOWDumper, self).execute_cyclical_dependencies(trans, task, isdelete)
+
+ def execute_per_element_childtasks(self, trans, task, isdelete):
+ super(UOWDumper, self).execute_per_element_childtasks(trans, task, isdelete)
def _dump_processor(self, proc, deletes):
if deletes:
self._dump(starttask.circular, indent=self.indent, circularparent=starttask)
return
+
i = self._indent()
if len(i):
i = i[0:-1] + "-"
self.buf.write(self._indent() + " |----\n")
self.buf.write(self._indent() + "\n")
+
+