1515# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717#
18- # $Id: hyperdb.py,v 1.72 2002-07-09 21:53:38 gmcm Exp $
18+ # $Id: hyperdb.py,v 1.73 2002-07-10 00:19:48 richard Exp $
1919
2020__doc__ = """
2121Hyperdatabase implementation, especially field types.
@@ -775,12 +775,16 @@ def lookup(self, keyvalue):
775775 otherwise a KeyError is raised.
776776 """
777777 cldb = self .db .getclassdb (self .classname )
778- for nodeid in self .db .getnodeids (self .classname , cldb ):
779- node = self .db .getnode (self .classname , nodeid , cldb )
780- if node .has_key (self .db .RETIRED_FLAG ):
781- continue
782- if node [self .key ] == keyvalue :
783- return nodeid
778+ try :
779+ for nodeid in self .db .getnodeids (self .classname , cldb ):
780+ node = self .db .getnode (self .classname , nodeid , cldb )
781+ if node .has_key (self .db .RETIRED_FLAG ):
782+ continue
783+ if node [self .key ] == keyvalue :
784+ cldb .close ()
785+ return nodeid
786+ finally :
787+ cldb .close ()
784788 raise KeyError , keyvalue
785789
786790 # XXX: change from spec - allows multiple props to match
@@ -811,30 +815,33 @@ def find(self, **propspec):
811815 # ok, now do the find
812816 cldb = self .db .getclassdb (self .classname )
813817 l = []
814- for id in self .db .getnodeids (self .classname , db = cldb ):
815- node = self .db .getnode (self .classname , id , db = cldb )
816- if node .has_key (self .db .RETIRED_FLAG ):
817- continue
818- for propname , nodeids in propspec :
819- # can't test if the node doesn't have this property
820- if not node .has_key (propname ):
818+ try :
819+ for id in self .db .getnodeids (self .classname , db = cldb ):
820+ node = self .db .getnode (self .classname , id , db = cldb )
821+ if node .has_key (self .db .RETIRED_FLAG ):
821822 continue
822- if type (nodeids ) is type ('' ):
823- nodeids = {nodeids :1 }
824- prop = self .properties [propname ]
825- value = node [propname ]
826- if isinstance (prop , Link ) and nodeids .has_key (value ):
827- l .append (id )
828- break
829- elif isinstance (prop , Multilink ):
830- hit = 0
831- for v in value :
832- if nodeids .has_key (v ):
833- l .append (id )
834- hit = 1
835- break
836- if hit :
823+ for propname , nodeids in propspec :
824+ # can't test if the node doesn't have this property
825+ if not node .has_key (propname ):
826+ continue
827+ if type (nodeids ) is type ('' ):
828+ nodeids = {nodeids :1 }
829+ prop = self .properties [propname ]
830+ value = node [propname ]
831+ if isinstance (prop , Link ) and nodeids .has_key (value ):
832+ l .append (id )
837833 break
834+ elif isinstance (prop , Multilink ):
835+ hit = 0
836+ for v in value :
837+ if nodeids .has_key (v ):
838+ l .append (id )
839+ hit = 1
840+ break
841+ if hit :
842+ break
843+ except :
844+ cldb .close ()
838845 return l
839846
840847 def stringFind (self , ** requirements ):
@@ -852,27 +859,33 @@ def stringFind(self, **requirements):
852859 requirements [propname ] = requirements [propname ].lower ()
853860 l = []
854861 cldb = self .db .getclassdb (self .classname )
855- for nodeid in self .db .getnodeids (self .classname , cldb ):
856- node = self .db .getnode (self .classname , nodeid , cldb )
857- if node .has_key (self .db .RETIRED_FLAG ):
858- continue
859- for key , value in requirements .items ():
860- if node [key ] and node [key ].lower () != value :
861- break
862- else :
863- l .append (nodeid )
862+ try :
863+ for nodeid in self .db .getnodeids (self .classname , cldb ):
864+ node = self .db .getnode (self .classname , nodeid , cldb )
865+ if node .has_key (self .db .RETIRED_FLAG ):
866+ continue
867+ for key , value in requirements .items ():
868+ if node [key ] and node [key ].lower () != value :
869+ break
870+ else :
871+ l .append (nodeid )
872+ finally :
873+ cldb .close ()
864874 return l
865875
866876 def list (self ):
867877 """Return a list of the ids of the active nodes in this class."""
868878 l = []
869879 cn = self .classname
870880 cldb = self .db .getclassdb (cn )
871- for nodeid in self .db .getnodeids (cn , cldb ):
872- node = self .db .getnode (cn , nodeid , cldb )
873- if node .has_key (self .db .RETIRED_FLAG ):
874- continue
875- l .append (nodeid )
881+ try :
882+ for nodeid in self .db .getnodeids (cn , cldb ):
883+ node = self .db .getnode (cn , nodeid , cldb )
884+ if node .has_key (self .db .RETIRED_FLAG ):
885+ continue
886+ l .append (nodeid )
887+ finally :
888+ cldb .close ()
876889 l .sort ()
877890 return l
878891
@@ -935,37 +948,40 @@ def filter(self, search_matches, filterspec, sort, group,
935948 # now, find all the nodes that are active and pass filtering
936949 l = []
937950 cldb = self .db .getclassdb (cn )
938- for nodeid in self .db .getnodeids (cn , cldb ):
939- node = self .db .getnode (cn , nodeid , cldb )
940- if node .has_key (self .db .RETIRED_FLAG ):
941- continue
942- # apply filter
943- for t , k , v in filterspec :
944- # this node doesn't have this property, so reject it
945- if not node .has_key (k ): break
946-
947- if t == 0 and node [k ] not in v :
948- # link - if this node'd property doesn't appear in the
949- # filterspec's nodeid list, skip it
950- break
951- elif t == 1 :
952- # multilink - if any of the nodeids required by the
953- # filterspec aren't in this node's property, then skip
954- # it
955- for value in v :
956- if value not in node [k ]:
957- break
958- else :
959- continue
960- break
961- elif t == 2 and (node [k ] is None or not v .search (node [k ])):
962- # RE search
963- break
964- elif t == 6 and node [k ] != v :
965- # straight value comparison for the other types
966- break
967- else :
968- l .append ((nodeid , node ))
951+ try :
952+ for nodeid in self .db .getnodeids (cn , cldb ):
953+ node = self .db .getnode (cn , nodeid , cldb )
954+ if node .has_key (self .db .RETIRED_FLAG ):
955+ continue
956+ # apply filter
957+ for t , k , v in filterspec :
958+ # this node doesn't have this property, so reject it
959+ if not node .has_key (k ): break
960+
961+ if t == 0 and node [k ] not in v :
962+ # link - if this node'd property doesn't appear in the
963+ # filterspec's nodeid list, skip it
964+ break
965+ elif t == 1 :
966+ # multilink - if any of the nodeids required by the
967+ # filterspec aren't in this node's property, then skip
968+ # it
969+ for value in v :
970+ if value not in node [k ]:
971+ break
972+ else :
973+ continue
974+ break
975+ elif t == 2 and (node [k ] is None or not v .search (node [k ])):
976+ # RE search
977+ break
978+ elif t == 6 and node [k ] != v :
979+ # straight value comparison for the other types
980+ break
981+ else :
982+ l .append ((nodeid , node ))
983+ finally :
984+ cldb .close ()
969985 l .sort ()
970986
971987 # filter based on full text search
@@ -1199,6 +1215,12 @@ def Choice(name, db, *options):
11991215
12001216#
12011217# $Log: not supported by cvs2svn $
1218+ # Revision 1.72 2002/07/09 21:53:38 gmcm
1219+ # Optimize Class.find so that the propspec can contain a set of ids to match.
1220+ # This is used by indexer.search so it can do just one find for all the index matches.
1221+ # This was already confusing code, but for common terms (lots of index matches),
1222+ # it is enormously faster.
1223+ #
12021224# Revision 1.71 2002/07/09 03:02:52 richard
12031225# More indexer work:
12041226# - all String properties may now be indexed too. Currently there's a bit of
0 commit comments