From 88e6b573ecaf9be5744cae0274990ddffd3dfa5a Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 10 Jul 2002 00:19:48 +0000 Subject: [PATCH] Added explicit closing of backend database handles. git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@850 57a73879-2fb5-44c3-a270-3262357dd7e2 --- roundup/hyperdb.py | 170 +++++++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 74 deletions(-) diff --git a/roundup/hyperdb.py b/roundup/hyperdb.py index ce97cfb..8837db4 100644 --- a/roundup/hyperdb.py +++ b/roundup/hyperdb.py @@ -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 -- 2.30.2