From 51366310ee6e4214300ee77b3c002e47e1875cd6 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 30 Oct 2005 16:54:51 +0000 Subject: [PATCH] --- examples/adjacencytree/tables.py | 8 ++++---- lib/sqlalchemy/mapper.py | 2 +- lib/sqlalchemy/objectstore.py | 10 ++++++---- lib/sqlalchemy/sql.py | 23 +++++++++++------------ lib/sqlalchemy/util.py | 31 +++++++++++++++++++++++++------ test/dependency.py | 8 ++++---- 6 files changed, 51 insertions(+), 31 deletions(-) diff --git a/examples/adjacencytree/tables.py b/examples/adjacencytree/tables.py index f39062892b..46939f1751 100644 --- a/examples/adjacencytree/tables.py +++ b/examples/adjacencytree/tables.py @@ -2,8 +2,8 @@ from sqlalchemy.schema import * import sqlalchemy.engine import os -#engine = sqlalchemy.engine.create_engine('sqlite', ':memory:', {}, echo = True) -engine = sqlalchemy.engine.create_engine('postgres', {'database':'test', 'host':'127.0.0.1', 'user':'scott', 'password':'tiger'}, echo=True) +engine = sqlalchemy.engine.create_engine('sqlite', ':memory:', {}, echo = True) +#engine = sqlalchemy.engine.create_engine('postgres', {'database':'test', 'host':'127.0.0.1', 'user':'scott', 'password':'tiger'}, echo=True) #engine = sqlalchemy.engine.create_engine('oracle', {'dsn':os.environ['DSN'], 'user':os.environ['USER'], 'password':os.environ['PASSWORD']}, echo=True) @@ -29,7 +29,7 @@ print "\n\n\n----------------------------" print "Creating Tree Table:" print "----------------------------" -#treedata.create() -#trees.create() +treedata.create() +trees.create() diff --git a/lib/sqlalchemy/mapper.py b/lib/sqlalchemy/mapper.py index 4fc5fbc8b4..b91095b50e 100644 --- a/lib/sqlalchemy/mapper.py +++ b/lib/sqlalchemy/mapper.py @@ -911,7 +911,7 @@ class PropertyLoader(MapperProperty): for child in childlist.added_items(): self._synchronize(obj, child, None, False) if self.direction == PropertyLoader.LEFT: - uowcommit.register_object(child) + uowcommit.register_object(child, sort=True) if self.direction != PropertyLoader.RIGHT or len(childlist.added_items()) == 0: for child in childlist.deleted_items(): self._synchronize(obj, child, None, True) diff --git a/lib/sqlalchemy/objectstore.py b/lib/sqlalchemy/objectstore.py index 5920e82c81..28c551a781 100644 --- a/lib/sqlalchemy/objectstore.py +++ b/lib/sqlalchemy/objectstore.py @@ -281,7 +281,7 @@ class UOWTransaction(object): self.deleted_objects = util.HashSet() self.deleted_lists = util.HashSet() - def register_object(self, obj, isdelete = False, listonly = False): + def register_object(self, obj, isdelete = False, listonly = False, **kwargs): """adds an object to this UOWTransaction to be updated in the database. 'isdelete' indicates whether the object is to be deleted or saved (update/inserted). 'listonly', indicates that only this object's dependency relationships should be @@ -291,7 +291,7 @@ class UOWTransaction(object): mapper = object_mapper(obj) self.mappers.append(mapper) task = self.get_task_by_mapper(mapper) - task.append(obj, listonly, isdelete=isdelete) + task.append(obj, listonly, isdelete=isdelete, **kwargs) def get_task_by_mapper(self, mapper): try: @@ -324,7 +324,7 @@ class UOWTransaction(object): task.mapper.register_dependencies(self) head = self._sort_dependencies() - #print "Task dump:\n" + head.dump() + print "Task dump:\n" + head.dump() if head is not None: head.execute(self) @@ -408,7 +408,7 @@ class UOWTask(object): def is_empty(self): return len(self.objects) == 0 and len(self.dependencies) == 0 and len(self.childtasks) == 0 - def append(self, obj, listonly = False, childtask = None, isdelete = False): + def append(self, obj, listonly = False, childtask = None, isdelete = False, sort=False): """appends an object to this task, to be either saved or deleted depending on the 'isdelete' attribute of this UOWTask. 'listonly' indicates that the object should only be processed as a dependency and not actually saved/deleted. @@ -417,6 +417,8 @@ class UOWTask(object): tasks, to assign dependent operations at the per-object instead of per-task level.""" try: rec = self.objects[obj] + if sort: + self.objects.toend(obj) except KeyError: rec = UOWTaskElement(obj) self.objects[obj] = rec diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index 6ea444b29b..bae42022e8 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -713,7 +713,7 @@ class Select(Selectable): self.use_labels = use_labels self.id = "Select(%d)" % id(self) self.name = None - self.whereclause = whereclause + self.whereclause = None self._engine = engine self.rowid_column = None @@ -729,8 +729,8 @@ class Select(Selectable): self.append_column(c) if whereclause is not None: - self.set_whereclause(whereclause) - + self.append_whereclause(whereclause) + for f in from_obj: self.append_from(f) @@ -757,25 +757,24 @@ class Select(Selectable): else: co._make_proxy(self) - def set_whereclause(self, whereclause): + def append_whereclause(self, whereclause): if type(whereclause) == str: - self.whereclause = TextClause(whereclause) + whereclause = TextClause(whereclause) class CorrelatedVisitor(ClauseVisitor): def visit_select(s, select): for f in self.froms.keys(): select.clear_from(f) select.issubquery = True - self.whereclause.accept_visitor(CorrelatedVisitor()) - - self.whereclause._process_from_dict(self.froms, False) - def append_whereclause(self, clause): + whereclause.accept_visitor(CorrelatedVisitor()) + whereclause._process_from_dict(self.froms, False) + if self.whereclause is not None: - self.whereclause = and_(self.whereclause, clause) + self.whereclause = and_(self.whereclause, whereclause) else: - self.whereclause = clause - + self.whereclause = whereclause + def clear_from(self, id): self.append_from(FromClause(from_name = None, from_key = id)) diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index 2276ef5544..2f6abcccd8 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -56,6 +56,15 @@ class OrderedDict(dict): def clear(self): self.list = [] dict.clear(self) + + def toend(self, key): + # TODO: optimize this + try: + del self.list[self.list.index(key)] + self.list.append(key) + print "toend: " + repr(key) + except ValueError: + raise KeyError(key) def update(self, dict): for key in dict.keys(): @@ -337,6 +346,11 @@ class DependencySorter(object): self.children = HashSet() self.parent = None self.circular = False + def append(self, node): + if node.parent is not None: + del node.parent.children[node] + self.children.append(node) + node.parent = self def __str__(self): return self.safestr({}) def safestr(self, hash, indent = 0): @@ -381,12 +395,17 @@ class DependencySorter(object): # nope, so we have to move the child down from whereever # it currently is to a child of the parent if c is None: - for c in parentnode.children: - c.parent = root - root.children.append(c) - del parentnode.children[c] - root.parent = parentnode - parentnode.children.append(root) + if childnode.parent is None: + print "moving down " + str(childnode.item) + ", has no parent" + parentnode.append(childnode) + else: + print "item " + str(childnode.item) + " has a parent " + str(childnode.parent.item) + for c in parentnode.children: + c.parent = root + root.children.append(c) + del parentnode.children[c] + root.parent = parentnode + parentnode.children.append(root) # now we have a collection of subtrees which represent dependencies. # go through the collection root nodes wire them together into one tree diff --git a/test/dependency.py b/test/dependency.py index 7d02c9dceb..d08df45e93 100644 --- a/test/dependency.py +++ b/test/dependency.py @@ -61,15 +61,15 @@ class DependencySortTest(PersistTest): (node1, node2), (node3, node2) ] - head1 = util.DependencySorter(tuples, [node1, node2, node3]).sort() +# head1 = util.DependencySorter(tuples, [node1, node2, node3]).sort() head2 = util.DependencySorter(tuples, [node3, node1, node2]).sort() - head3 = util.DependencySorter(tuples, [node3, node2, node1]).sort() + # head3 = util.DependencySorter(tuples, [node3, node2, node1]).sort() # TODO: figure out a "node == node2" function #self.assert_(str(head1) == str(head2) == str(head3)) - print "\n" + str(head1) + # print "\n" + str(head1) print "\n" + str(head2) - print "\n" + str(head3) + # print "\n" + str(head3) def testsort4(self): node1 = thingy('keywords') -- 2.47.2