]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- OrderedDict shouldn't send None to update, never know who might be watching
authorJason Kirtland <jek@discorporate.us>
Thu, 28 Jun 2007 20:04:52 +0000 (20:04 +0000)
committerJason Kirtland <jek@discorporate.us>
Thu, 28 Jun 2007 20:04:52 +0000 (20:04 +0000)
  (breaks use as a collection class)
- Update MapperExtension in byroot_tree example, finish updates for new
  collections.

examples/adjacencytree/byroot_tree.py
lib/sqlalchemy/util.py

index a56df7465741526e6363c7bd399435c192c39f05..bc187ff62554a12d1c13269cea49e8aa6d9ecd88 100644 (file)
@@ -4,6 +4,7 @@ advantage of a custom MapperExtension to assemble incoming nodes into their corr
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
+from sqlalchemy.orm.collections import MappedCollection, collection_adapter
 from sqlalchemy.util import OrderedDict
 
 engine = create_engine('sqlite:///:memory:', echo=True)
@@ -29,14 +30,13 @@ treedata = Table(
 )
 
 
-class NodeList(OrderedDict):
-    """subclasses OrderedDict to allow usage as a list-based property."""
-    
-    def append(self, node):
-        self[node.name] = node
-    def remove(self, node):
-        del self[node.name]
-        
+class NodeList(OrderedDict, MappedCollection):
+    """Mix OrderedDict and MappedCollection to create a dict-like collection class that keys off node names."""
+
+    def __init__(self, *args, **kw):
+        MappedCollection.__init__(self, keyfunc=lambda node: node.name)
+        OrderedDict.__init__(self, *args, **kw)
+
 class TreeNode(object):
     """a hierarchical Tree class, which adds the concept of a "root node".  The root is 
     the topmost node in a tree, or in other words a node whose parent ID is NULL.  
@@ -55,7 +55,7 @@ class TreeNode(object):
 
     def _set_root(self, root):
         self.root = root
-        for c in self.children:
+        for c in self.children.values():
             c._set_root(root)
 
     def append(self, node):
@@ -92,19 +92,21 @@ class TreeLoader(MapperExtension):
             connection.execute(mapper.mapped_table.update(TreeNode.c.id==instance.id, values=dict(root_node_id=instance.id)))
             instance.root_id = instance.id
 
-    def append_result(self, mapper, selectcontext, row, instance, identitykey, result, isnew):
+    def append_result(self, mapper, selectcontext, row, instance, result, **flags):
         """runs as results from a SELECT statement are processed, and newly created or already-existing
         instances that correspond to each row are appended to result lists.  This method will only
         append root nodes to the result list, and will attach child nodes to their appropriate parent
         node as they arrive from the select results.  This allows a SELECT statement which returns
         both root and child nodes in one query to return a list of "roots"."""
 
+        isnew = flags.get('isnew', False)
+
         if instance.parent_id is None:
             result.append(instance)
         else:
             if isnew or selectcontext.populate_existing:
                 parentnode = selectcontext.identity_map[mapper.identity_key(instance.parent_id)]
-                parentnode.children.append_without_event(instance)
+                collection_adapter(parentnode.children).append_without_event(instance)
         # fire off lazy loader before the instance is part of the session
         instance.children
         return False
index ee51c076e56cf1a53e3e7b772f146ba99c6e6c1d..9047d5c4149e9b0c4769ff2db751b7ecbfd20b55 100644 (file)
@@ -260,7 +260,10 @@ class OrderedDict(dict):
 
     def __init__(self, d=None, **kwargs):
         self._list = []
-        self.update(d, **kwargs)
+        if d is None:
+            self.update(**kwargs)
+        else:
+            self.update(d, **kwargs)
 
     def keys(self):
         return list(self._list)