dibbler/sqlalchemy/orm/uowdumper.py
2010-05-07 17:33:49 +00:00

102 lines
3.5 KiB
Python

# orm/uowdumper.py
# Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp@zzzcomputing.com
#
# This module is part of SQLAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
"""Dumps out a string representation of a UOWTask structure"""
from sqlalchemy.orm import unitofwork
from sqlalchemy.orm import util as mapperutil
import StringIO
class UOWDumper(unitofwork.UOWExecutor):
def __init__(self, tasks, buf):
self.indent = 0
self.tasks = tasks
self.buf = buf
self.execute(None, tasks)
@classmethod
def dump(cls, tasks):
buf = StringIO.StringIO()
UOWDumper(tasks, buf)
return buf.getvalue()
def execute(self, trans, tasks, isdelete=None):
if isdelete is not True:
for task in tasks:
self._execute(trans, task, False)
if isdelete is not False:
for task in reversed(tasks):
self._execute(trans, task, True)
def _execute(self, trans, task, isdelete):
try:
i = self._indent()
if i:
i = i[:-1] + "+-"
self.buf.write(i + " " + self._repr_task(task))
self.buf.write(" (" + (isdelete and "delete " or "save/update ") + "phase) \n")
self.indent += 1
super(UOWDumper, self).execute(trans, [task], isdelete)
finally:
self.indent -= 1
def save_objects(self, trans, task):
for rec in sorted(task.polymorphic_tosave_elements, key=lambda a: a.state.sort_key):
if rec.listonly:
continue
self.buf.write(self._indent()[:-1] + "+-" + self._repr_task_element(rec) + "\n")
def delete_objects(self, trans, task):
for rec in task.polymorphic_todelete_elements:
if rec.listonly:
continue
self.buf.write(self._indent() + "- " + self._repr_task_element(rec) + "\n")
def execute_dependency(self, transaction, dep, isdelete):
self._dump_processor(dep, isdelete)
def _dump_processor(self, proc, deletes):
if deletes:
val = proc.targettask.polymorphic_todelete_elements
else:
val = proc.targettask.polymorphic_tosave_elements
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 getattr(te, 'state', None) is None:
objid = "(placeholder)"
else:
if attribute is not None:
objid = "%s.%s" % (mapperutil.state_str(te.state), attribute)
else:
objid = mapperutil.state_str(te.state)
if 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.description
else:
name = repr(task.mapper)
else:
name = '(none)'
return ("UOWTask(%s, %s)" % (hex(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 _indent(self):
return " |" * self.indent