def dump(self):
buf = StringIO.StringIO()
- self._dump(buf)
+ import uowdumper
+ uowdumper.UOWDumper(self, buf)
return buf.getvalue()
- def _dump(self, buf, indent=0, circularparent=None):
- # TODO: the dumper should go into a separate module/class, allow different dumper implementations
- def _indent():
- return " | " * indent
-
- headers = {}
- def header(buf, text):
- """writes a given header just once"""
- try:
- headers[text]
- except KeyError:
- buf.write(_indent() + " |\n")
- buf.write(text)
- headers[text] = True
-
- def _dump_processor(proc, deletes):
- if deletes:
- val = proc.targettask.polymorphic_todelete_elements
- else:
- val = proc.targettask.polymorphic_tosave_elements
-
- buf.write(_indent() + " |- %s attribute on %s (UOWDependencyProcessor(%d) processing %s)\n" % (
- repr(proc.processor.key),
- ("%s's to be %s" % (_repr_task_class(proc.targettask), deletes and "deleted" or "saved")),
- id(proc),
- _repr_task(proc.targettask))
- )
-
- if len(val) == 0:
- buf.write(_indent() + " | |-" + "(no objects)\n")
- for v in val:
- buf.write(_indent() + " | |-" + _repr_task_element(v, proc.processor.key) + "\n")
-
- def _repr_task_element(te, attribute=None):
- if te.obj is None:
- objid = "(placeholder)"
- else:
- if attribute is not None:
- objid = "%s(%d).%s" % (te.obj.__class__.__name__, id(te.obj), attribute)
- else:
- objid = "%s(%d)" % (te.obj.__class__.__name__, id(te.obj))
- return "%s (UOWTaskElement(%d, %s))" % (objid, id(te), (te.listonly and 'listonly' or (te.isdelete and 'delete' or 'save')))
-
- def _repr_task(task):
- if task.mapper is not None:
- if task.mapper.__class__.__name__ == 'Mapper':
- name = task.mapper.class_.__name__ + "/" + task.mapper.local_table.name + "/" + str(task.mapper.entity_name)
- else:
- name = repr(task.mapper)
- else:
- name = '(none)'
- return ("UOWTask(%d, %s)" % (id(task), name))
- def _repr_task_class(task):
- if task.mapper is not None and task.mapper.__class__.__name__ == 'Mapper':
- return task.mapper.class_.__name__
- else:
- return '(none)'
-
- def _repr(obj):
- return "%s(%d)" % (obj.__class__.__name__, id(obj))
-
- def _inheritance_tag(task):
- if task is not self:
- return (" (inheriting task %s)" % _repr_task(task))
- else:
- return ""
-
- def _dump_saveelements(task):
- for rec in task.tosave_elements:
- if rec.listonly:
- continue
- header(buf, _indent() + " |- Save elements"+ _inheritance_tag(task) + "\n")
- buf.write(_indent() + " |- " + _repr_task_element(rec) + "\n")
- for t in task.inheriting_tasks:
- _dump_saveelements(t)
-
- def _dump_deleteelements(task):
- for rec in task.todelete_elements:
- if rec.listonly:
- continue
- header(buf, _indent() + " |- Delete elements"+ _inheritance_tag(task) + "\n")
- buf.write(_indent() + " |- " + _repr_task_element(rec) + "\n")
- for t in task.inheriting_tasks:
- _dump_deleteelements(t)
-
- def _dump_dependencies(task):
- for dep in task.dependencies:
- header(buf, _indent() + " |- Save dependencies" + _inheritance_tag(task) + "\n")
- _dump_processor(dep, False)
- for t in task.inheriting_tasks:
- _dump_dependencies(t)
- for dep in task.dependencies:
- header(buf, _indent() + " |- Delete dependencies" + _inheritance_tag(task) + "\n")
- _dump_processor(dep, True)
-
- def _dump_childtasks(task):
- for child in task.childtasks:
- header(buf, _indent() + " |- Child tasks" + _inheritance_tag(task) + "\n")
- child._dump(buf, indent + 1)
- for t in task.inheriting_tasks:
- _dump_childtasks(t)
-
- if self.circular is not None:
- self.circular._dump(buf, indent, self)
- return
-
- i = _indent()
- if len(i):
- i = i[0:-1] + "-"
- if circularparent is not None:
- buf.write(i + " " + _repr_task(circularparent))
- buf.write("->circular->" + _repr_task(self))
- else:
- buf.write(i + " " + _repr_task(self))
-
- buf.write("\n")
- _dump_saveelements(self)
- for dep in self.cyclical_dependencies:
- header(buf, _indent() + " |- Cyclical Save dependencies\n")
- _dump_processor(dep, False)
- for element in self.tosave_elements:
- for task in element.childtasks:
- header(buf, _indent() + " |- Save subelements of UOWTaskElement(%s)\n" % id(element))
- task._dump(buf, indent + 1)
- _dump_dependencies(self)
- for dep in self.cyclical_dependencies:
- header(buf, _indent() + " |- Cyclical Delete dependencies\n")
- _dump_processor(dep, True)
- _dump_childtasks(self)
- for element in self.todelete_elements:
- for task in element.childtasks:
- header(buf, _indent() + " |- Delete subelements of UOWTaskElement(%s)\n" % id(element))
- task._dump(buf, indent + 1)
- _dump_deleteelements(self)
-
- if self.is_empty():
- buf.write(_indent() + " |- (empty task)\n")
- else:
- buf.write(_indent() + " |----\n")
-
- buf.write(_indent() + "\n")
def __repr__(self):
if self.mapper is not None:
--- /dev/null
+
+"""dumps out a string representation of a UOWTask structure"""
+
+class UOWDumper(object):
+ def __init__(self, task, buf, verbose=False):
+ self.verbose = verbose
+ self.indent = 0
+ self.task = task
+ self.buf = buf
+ self._dump(task)
+
+ def _dump_processor(self, proc, deletes):
+ if deletes:
+ val = proc.targettask.polymorphic_todelete_elements
+ else:
+ val = proc.targettask.polymorphic_tosave_elements
+
+ if self.verbose:
+ self.buf.write(self._indent() + " |- %s attribute on %s (UOWDependencyProcessor(%d) processing %s)\n" % (
+ repr(proc.processor.key),
+ ("%s's to be %s" % (self._repr_task_class(proc.targettask), deletes and "deleted" or "saved")),
+ id(proc),
+ self._repr_task(proc.targettask))
+ )
+ elif False:
+ self.buf.write(self._indent() + " |- %s attribute on %s\n" % (
+ repr(proc.processor.key),
+ ("%s's to be %s" % (self._repr_task_class(proc.targettask), deletes and "deleted" or "saved")),
+ )
+ )
+
+ if len(val) == 0:
+ if self.verbose:
+ self.buf.write(self._indent() + " | |-" + "(no objects)\n")
+ for v in val:
+ self.buf.write(self._indent() + " | |-" + self._repr_task_element(v, proc.processor.key, process=True) + "\n")
+
+ def _repr_task_element(self, te, attribute=None, process=False):
+ if te.obj is None:
+ objid = "(placeholder)"
+ else:
+ if attribute is not None:
+ objid = "%s(%d).%s" % (te.obj.__class__.__name__, id(te.obj), attribute)
+ else:
+ objid = "%s(%d)" % (te.obj.__class__.__name__, id(te.obj))
+ if self.verbose:
+ return "%s (UOWTaskElement(%d, %s))" % (objid, id(te), (te.listonly and 'listonly' or (te.isdelete and 'delete' or 'save')))
+ elif process:
+ return "Process %s" % (objid)
+ else:
+ return "%s %s" % ((te.isdelete and "Delete" or "Save"), objid)
+
+ def _repr_task(self, task):
+ if task.mapper is not None:
+ if task.mapper.__class__.__name__ == 'Mapper':
+ name = task.mapper.class_.__name__ + "/" + task.mapper.local_table.name + "/" + str(task.mapper.entity_name)
+ else:
+ name = repr(task.mapper)
+ else:
+ name = '(none)'
+ return ("UOWTask(%d, %s)" % (id(task), name))
+
+ def _repr_task_class(self, task):
+ if task.mapper is not None and task.mapper.__class__.__name__ == 'Mapper':
+ return task.mapper.class_.__name__
+ else:
+ return '(none)'
+
+ def _repr(self, obj):
+ return "%s(%d)" % (obj.__class__.__name__, id(obj))
+
+ def _indent(self):
+ return " | " * self.indent
+
+ def _dump(self, starttask, indent=None, circularparent=None):
+ try:
+ oldindent = self.indent
+ if indent is not None:
+ self.indent = indent
+ self._dump_impl(starttask, circularparent=circularparent)
+ finally:
+ self.indent = oldindent
+
+ def _dump_impl(self, starttask, circularparent=None):
+
+ headers = {}
+ def header(buf, text):
+ """writes a given header just once"""
+ try:
+ headers[text]
+ except KeyError:
+ self.buf.write(self._indent() + " |\n")
+ self.buf.write(text)
+ headers[text] = True
+
+ def _inheritance_tag(task):
+ if not self.verbose:
+ return ""
+ elif task is not starttask:
+ return (" (inheriting task %s)" % self._repr_task(task))
+ else:
+ 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)
+
+ 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)
+
+ 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)
+
+ 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)
+
+ if starttask.circular is not None:
+ self._dump(starttask.circular, indent=self.indent, circularparent=starttask)
+ return
+
+ i = self._indent()
+ if len(i):
+ i = i[0:-1] + "-"
+ if circularparent is not None:
+ self.buf.write(self._indent() + "\n")
+ self.buf.write(i + " " + self._repr_task(circularparent))
+ self.buf.write("->circular->" + self._repr_task(starttask))
+ else:
+ self.buf.write(self._indent() + "\n")
+ self.buf.write(i + " " + self._repr_task(starttask))
+
+ self.buf.write("\n")
+ _dump_saveelements(starttask)
+ for dep in starttask.cyclical_dependencies:
+ if self.verbose:
+ header(self.buf, self._indent() + " |- Cyclical Save dependencies\n")
+ self._dump_processor(dep, False)
+ for element in starttask.tosave_elements:
+ for task in element.childtasks:
+ if self.verbose:
+ header(self.buf, self._indent() + " |- Save subelements of UOWTaskElement(%s)\n" % id(element))
+ self._dump(task, indent = self.indent + 1)
+ _dump_dependencies(starttask)
+ for dep in starttask.cyclical_dependencies:
+ if self.verbose:
+ header(self.buf, self._indent() + " |- Cyclical Delete dependencies\n")
+ self._dump_processor(dep, True)
+ _dump_childtasks(starttask)
+ for element in starttask.todelete_elements:
+ for task in element.childtasks:
+ if self.verbose:
+ header(self.buf, self._indent() + " |- Delete subelements of UOWTaskElement(%s)\n" % id(element))
+ self._dump(task, indent = self.indent + 1)
+ _dump_deleteelements(starttask)
+
+ if starttask.is_empty():
+ self.buf.write(self._indent() + " |- (empty task)\n")
+ else:
+ self.buf.write(self._indent() + " |----\n")
+
+ self.buf.write(self._indent() + "\n")