Code

Added explicit closing of backend database handles.
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 10 Jul 2002 00:19:48 +0000 (00:19 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 10 Jul 2002 00:19:48 +0000 (00:19 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@850 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/hyperdb.py

index ce97cfba6a0c6640ca302e99364b2741d4d8c0b2..8837db4fc483cba523cfc03d11f2235d91ddc881 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: hyperdb.py,v 1.72 2002-07-09 21:53:38 gmcm Exp $
+# $Id: hyperdb.py,v 1.73 2002-07-10 00:19:48 richard Exp $
 
 __doc__ = """
 Hyperdatabase implementation, especially field types.
@@ -775,12 +775,16 @@ class Class:
         otherwise a KeyError is raised.
         """
         cldb = self.db.getclassdb(self.classname)
-        for nodeid in self.db.getnodeids(self.classname, cldb):
-            node = self.db.getnode(self.classname, nodeid, cldb)
-            if node.has_key(self.db.RETIRED_FLAG):
-                continue
-            if node[self.key] == keyvalue:
-                return nodeid
+        try:
+            for nodeid in self.db.getnodeids(self.classname, cldb):
+                node = self.db.getnode(self.classname, nodeid, cldb)
+                if node.has_key(self.db.RETIRED_FLAG):
+                    continue
+                if node[self.key] == keyvalue:
+                    cldb.close()
+                    return nodeid
+        finally:
+            cldb.close()
         raise KeyError, keyvalue
 
     # XXX: change from spec - allows multiple props to match
@@ -811,30 +815,33 @@ class Class:
         # ok, now do the find
         cldb = self.db.getclassdb(self.classname)
         l = []
-        for id in self.db.getnodeids(self.classname, db=cldb):
-            node = self.db.getnode(self.classname, id, db=cldb)
-            if node.has_key(self.db.RETIRED_FLAG):
-                continue
-            for propname, nodeids in propspec:
-                # can't test if the node doesn't have this property
-                if not node.has_key(propname):
+        try:
+            for id in self.db.getnodeids(self.classname, db=cldb):
+                node = self.db.getnode(self.classname, id, db=cldb)
+                if node.has_key(self.db.RETIRED_FLAG):
                     continue
-                if type(nodeids) is type(''):
-                    nodeids = {nodeids:1}
-                prop = self.properties[propname]
-                value = node[propname]
-                if isinstance(prop, Link) and nodeids.has_key(value):
-                    l.append(id)
-                    break
-                elif isinstance(prop, Multilink):
-                    hit = 0
-                    for v in value:
-                        if nodeids.has_key(v):
-                            l.append(id)
-                            hit = 1
-                            break
-                    if hit:
+                for propname, nodeids in propspec:
+                    # can't test if the node doesn't have this property
+                    if not node.has_key(propname):
+                        continue
+                    if type(nodeids) is type(''):
+                        nodeids = {nodeids:1}
+                    prop = self.properties[propname]
+                    value = node[propname]
+                    if isinstance(prop, Link) and nodeids.has_key(value):
+                        l.append(id)
                         break
+                    elif isinstance(prop, Multilink):
+                        hit = 0
+                        for v in value:
+                            if nodeids.has_key(v):
+                                l.append(id)
+                                hit = 1
+                                break
+                        if hit:
+                            break
+        except:
+            cldb.close()
         return l
 
     def stringFind(self, **requirements):
@@ -852,15 +859,18 @@ class Class:
             requirements[propname] = requirements[propname].lower()
         l = []
         cldb = self.db.getclassdb(self.classname)
-        for nodeid in self.db.getnodeids(self.classname, cldb):
-            node = self.db.getnode(self.classname, nodeid, cldb)
-            if node.has_key(self.db.RETIRED_FLAG):
-                continue
-            for key, value in requirements.items():
-                if node[key] and node[key].lower() != value:
-                    break
-            else:
-                l.append(nodeid)
+        try:
+            for nodeid in self.db.getnodeids(self.classname, cldb):
+                node = self.db.getnode(self.classname, nodeid, cldb)
+                if node.has_key(self.db.RETIRED_FLAG):
+                    continue
+                for key, value in requirements.items():
+                    if node[key] and node[key].lower() != value:
+                        break
+                else:
+                    l.append(nodeid)
+        finally:
+            cldb.close()
         return l
 
     def list(self):
@@ -868,11 +878,14 @@ class Class:
         l = []
         cn = self.classname
         cldb = self.db.getclassdb(cn)
-        for nodeid in self.db.getnodeids(cn, cldb):
-            node = self.db.getnode(cn, nodeid, cldb)
-            if node.has_key(self.db.RETIRED_FLAG):
-                continue
-            l.append(nodeid)
+        try:
+            for nodeid in self.db.getnodeids(cn, cldb):
+                node = self.db.getnode(cn, nodeid, cldb)
+                if node.has_key(self.db.RETIRED_FLAG):
+                    continue
+                l.append(nodeid)
+        finally:
+            cldb.close()
         l.sort()
         return l
 
@@ -935,37 +948,40 @@ class Class:
         # now, find all the nodes that are active and pass filtering
         l = []
         cldb = self.db.getclassdb(cn)
-        for nodeid in self.db.getnodeids(cn, cldb):
-            node = self.db.getnode(cn, nodeid, cldb)
-            if node.has_key(self.db.RETIRED_FLAG):
-                continue
-            # apply filter
-            for t, k, v in filterspec:
-                # this node doesn't have this property, so reject it
-                if not node.has_key(k): break
-
-                if t == 0 and node[k] not in v:
-                    # link - if this node'd property doesn't appear in the
-                    # filterspec's nodeid list, skip it
-                    break
-                elif t == 1:
-                    # multilink - if any of the nodeids required by the
-                    # filterspec aren't in this node's property, then skip
-                    # it
-                    for value in v:
-                        if value not in node[k]:
-                            break
-                    else:
-                        continue
-                    break
-                elif t == 2 and (node[k] is None or not v.search(node[k])):
-                    # RE search
-                    break
-                elif t == 6 and node[k] != v:
-                    # straight value comparison for the other types
-                    break
-            else:
-                l.append((nodeid, node))
+        try:
+            for nodeid in self.db.getnodeids(cn, cldb):
+                node = self.db.getnode(cn, nodeid, cldb)
+                if node.has_key(self.db.RETIRED_FLAG):
+                    continue
+                # apply filter
+                for t, k, v in filterspec:
+                    # this node doesn't have this property, so reject it
+                    if not node.has_key(k): break
+
+                    if t == 0 and node[k] not in v:
+                        # link - if this node'd property doesn't appear in the
+                        # filterspec's nodeid list, skip it
+                        break
+                    elif t == 1:
+                        # multilink - if any of the nodeids required by the
+                        # filterspec aren't in this node's property, then skip
+                        # it
+                        for value in v:
+                            if value not in node[k]:
+                                break
+                        else:
+                            continue
+                        break
+                    elif t == 2 and (node[k] is None or not v.search(node[k])):
+                        # RE search
+                        break
+                    elif t == 6 and node[k] != v:
+                        # straight value comparison for the other types
+                        break
+                else:
+                    l.append((nodeid, node))
+        finally:
+            cldb.close()
         l.sort()
 
         # filter based on full text search
@@ -1199,6 +1215,12 @@ def Choice(name, db, *options):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.72  2002/07/09 21:53:38  gmcm
+# Optimize Class.find so that the propspec can contain a set of ids to match.
+# This is used by indexer.search so it can do just one find for all the index matches.
+# This was already confusing code, but for common terms (lots of index matches),
+# it is enormously faster.
+#
 # Revision 1.71  2002/07/09 03:02:52  richard
 # More indexer work:
 # - all String properties may now be indexed too. Currently there's a bit of