From: Mike Bayer Date: Sat, 27 May 2006 17:46:03 +0000 (+0000) Subject: broke out dumper into a separate module X-Git-Tag: rel_0_2_0~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06ba0bd8544fa69932f931d9be862eddb2ec6984;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git broke out dumper into a separate module --- diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index db5211612d..b697ab3829 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -844,150 +844,10 @@ class UOWTask(object): 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: diff --git a/lib/sqlalchemy/orm/uowdumper.py b/lib/sqlalchemy/orm/uowdumper.py new file mode 100644 index 0000000000..ebe8535e1d --- /dev/null +++ b/lib/sqlalchemy/orm/uowdumper.py @@ -0,0 +1,188 @@ + +"""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")