diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-09-07 20:04:10 +0000 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2006-09-07 20:04:10 +0000 |
| commit | 45dd486e0694a1dd60baa7410d2caeb00146333f (patch) | |
| tree | 1a074fd77bc9399ee07627e15f78a552766dca56 /lib/sqlalchemy | |
| parent | 8f43b24f325a7129e947405587f40aa1749424b4 (diff) | |
| download | sqlalchemy-45dd486e0694a1dd60baa7410d2caeb00146333f.tar.gz | |
- more rearrangements of unit-of-work commit scheme to better allow
dependencies within circular flushes to work properly...updated
task traversal/logging implementation
this work is still under construction ! requires more unit tests and
new dumper needs to be finished.
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/orm/unitofwork.py | 111 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/uowdumper.py | 75 |
2 files changed, 140 insertions, 46 deletions
diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index c0bb219a3..17c77785a 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -516,6 +516,71 @@ class UOWDependencyProcessor(object): 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): @@ -600,56 +665,12 @@ class UOWTask(object): 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 diff --git a/lib/sqlalchemy/orm/uowdumper.py b/lib/sqlalchemy/orm/uowdumper.py index ab7a1449a..f49c35d7f 100644 --- a/lib/sqlalchemy/orm/uowdumper.py +++ b/lib/sqlalchemy/orm/uowdumper.py @@ -1,13 +1,83 @@ +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: @@ -144,6 +214,7 @@ class UOWDumper(object): self._dump(starttask.circular, indent=self.indent, circularparent=starttask) return + i = self._indent() if len(i): i = i[0:-1] + "-" @@ -185,3 +256,5 @@ class UOWDumper(object): self.buf.write(self._indent() + " |----\n") self.buf.write(self._indent() + "\n") + + |
