]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
merge default branch
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 4 Apr 2010 14:38:29 +0000 (10:38 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 4 Apr 2010 14:38:29 +0000 (10:38 -0400)
1  2 
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/topological.py

index ac35ce49b7ac720844d4eb995d9a3363965ffd3f,56cb1ef4d56a59d24ddac3be019ec65624cded9a..fbb66a7dd27bcc88ebfc1a5edb0af55998cc915e
@@@ -1354,18 -1313,29 +1347,29 @@@ class Mapper(object)
                              "New instance %s with identity key %s conflicts "
                              "with persistent instance %s" % 
                              (state_str(state), instance_key, state_str(existing)))
-                             
                      self._log_debug(
-                         "detected row switch for identity %s.  will update %s, remove %s from "
-                         "transaction", instance_key, state_str(state), state_str(existing))
-                     
+                         "detected row switch for identity %s.  "
+                         "will update %s, remove %s from "
+                         "transaction", instance_key, 
+                         state_str(state), state_str(existing))
                      # remove the "delete" flag from the existing element
 -                    uowtransaction.set_row_switch(existing)
 +                    uowtransaction.remove_state_actions(existing)
-                     row_switches[state] = existing
-         
+                     row_switch = existing
+             tups.append(
+                 (state,
+                     mapper,
+                     conn,
+                     has_identity,
+                     instance_key,
+                     row_switch)
+             )
          table_to_mapper = self._sorted_tables
  
-         for table in table_to_mapper.iterkeys():
+         for table in table_to_mapper:
              insert = []
              update = []
  
Simple merge
index 8886bcbf7c3d6f41b6719a969a9294b7e09f213a,d061aec043b13fd84d6c9970b2dd0995ac1c7c1d..5fc982ae0debad0af95c9c3c33814f17fa92e9ac
@@@ -103,33 -215,82 +103,32 @@@ def sort(tuples, allitems)
              queue.append(childnode)
      return output
  
 -def _organize_as_tree(nodes):
 -    """Given a list of nodes from a topological sort, organize the
 -    nodes into a tree structure, with as many non-dependent nodes
 -    set as siblings to each other as possible.
 -    
 -    returns nodes as 3-tuples (item, cycles, children).
 -    """
 -
 -    if not nodes:
 -        return None
 -    # a list of all currently independent subtrees as a tuple of
 -    # (root_node, set_of_all_tree_nodes, set_of_all_cycle_nodes_in_tree)
 -    # order of the list has no semantics for the algorithmic
 -    independents = []
 -    # in reverse topological order
 -    for node in reversed(nodes):
 -        # nodes subtree and cycles contain the node itself
 -        subtree = set([node])
 -        if node.cycles is not None:
 -            cycles = set(node.cycles)
 -        else:
 -            cycles = set()
 -        # get a set of dependent nodes of node and its cycles
 -        nodealldeps = node.all_deps()
 -        if nodealldeps:
 -            # iterate over independent node indexes in reverse order so we can efficiently remove them
 -            for index in xrange(len(independents) - 1, -1, -1):
 -                child, childsubtree, childcycles = independents[index]
 -                # if there is a dependency between this node and an independent node
 -                if (childsubtree.intersection(nodealldeps) or childcycles.intersection(node.dependencies)):
 -                    # prepend child to nodes children
 -                    # (append should be fine, but previous implemetation used prepend)
 -                    node.children[0:0] = [(child.item, [n.item for n in child.cycles or []], child.children)]
 -                    # merge childs subtree and cycles
 -                    subtree.update(childsubtree)
 -                    cycles.update(childcycles)
 -                    # remove the child from list of independent subtrees
 -                    independents[index:index+1] = []
 -        # add node as a new independent subtree
 -        independents.append((node, subtree, cycles))
 -    # choose an arbitrary node from list of all independent subtrees
 -    head = independents.pop()[0]
 -    # add all other independent subtrees as a child of the chosen root
 -    # used prepend [0:0] instead of extend to maintain exact behaviour of previous implementation
 -    head.children[0:0] = [(i[0].item, [n.item for n in i[0].cycles or []], i[0].children) for i in independents]
 -    return (head.item, [n.item for n in head.cycles or []], head.children)
 -
 -def _find_cycles(edges):
 -    cycles = {}
 -
 -    def traverse(node, cycle, goal):
 -        for (n, key) in edges.edges_by_parent(node):
 -            if key in cycle:
 -                continue
 -            cycle.append(key)
 -            if key is goal:
 -                cycset = set(cycle)
 -                for x in cycle:
 -                    if x in cycles:
 -                        existing_set = cycles[x]
 -                        existing_set.update(cycset)
 -                        for y in existing_set:
 -                            cycles[y] = existing_set
 -                        cycset = existing_set
 -                    else:
 -                        cycles[x] = cycset
 -            else:
 -                traverse(key, cycle, goal)
 -            cycle.pop()
 -
 -    for parent in edges.get_parents():
 -        traverse(parent, [], parent)
 +def find_cycles(tuples, allitems):
 +    # straight from gvr with some mods
 +    todo = set(allitems)
 +    edges = _EdgeCollection()
  
 -    unique_cycles = set(tuple(s) for s in cycles.values())
 +    for t in tuples:
 +        todo.update(t)
 +        edges.add(t)
      
 -    for cycle in unique_cycles:
 -        edgecollection = [edge for edge in edges
 -                          if edge[0] in cycle and edge[1] in cycle]
 -        yield edgecollection
 +    output = set()
 +    
 +    while todo:
 +        node = todo.pop()
 +        stack = [node]
 +        while stack:
 +            top = stack[-1]
 +            for node in edges.outgoing(top):
 +                if node in stack:
 +                    cyc = stack[stack.index(node):]
 +                    todo.difference_update(cyc)
 +                    output.update(cyc)
 +                    
 +                if node in todo:
 +                    stack.append(node)
 +                    todo.remove(node)
 +                    break
 +            else:
 +                node = stack.pop()
 +    return output
-