comparison roundup/hyperdb.py @ 836:bf55b2b800b9

Added explicit closing of backend database handles.
author Richard Jones <richard@users.sourceforge.net>
date Wed, 10 Jul 2002 00:19:48 +0000
parents 568eed5fb4fd
children 234996e85699
comparison
equal deleted inserted replaced
835:255bdcf39e8c 836:bf55b2b800b9
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17 # 17 #
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 $
19 19
20 __doc__ = """ 20 __doc__ = """
21 Hyperdatabase implementation, especially field types. 21 Hyperdatabase implementation, especially field types.
22 """ 22 """
23 23
773 'keyvalue' matches one of the values for the key property among 773 'keyvalue' matches one of the values for the key property among
774 the nodes in this class, the matching node's id is returned; 774 the nodes in this class, the matching node's id is returned;
775 otherwise a KeyError is raised. 775 otherwise a KeyError is raised.
776 """ 776 """
777 cldb = self.db.getclassdb(self.classname) 777 cldb = self.db.getclassdb(self.classname)
778 for nodeid in self.db.getnodeids(self.classname, cldb): 778 try:
779 node = self.db.getnode(self.classname, nodeid, cldb) 779 for nodeid in self.db.getnodeids(self.classname, cldb):
780 if node.has_key(self.db.RETIRED_FLAG): 780 node = self.db.getnode(self.classname, nodeid, cldb)
781 continue 781 if node.has_key(self.db.RETIRED_FLAG):
782 if node[self.key] == keyvalue: 782 continue
783 return nodeid 783 if node[self.key] == keyvalue:
784 cldb.close()
785 return nodeid
786 finally:
787 cldb.close()
784 raise KeyError, keyvalue 788 raise KeyError, keyvalue
785 789
786 # XXX: change from spec - allows multiple props to match 790 # XXX: change from spec - allows multiple props to match
787 def find(self, **propspec): 791 def find(self, **propspec):
788 """Get the ids of nodes in this class which link to the given nodes. 792 """Get the ids of nodes in this class which link to the given nodes.
809 # raise ValueError, '%s has no node %s'%(prop.classname, nodeid) 813 # raise ValueError, '%s has no node %s'%(prop.classname, nodeid)
810 814
811 # ok, now do the find 815 # ok, now do the find
812 cldb = self.db.getclassdb(self.classname) 816 cldb = self.db.getclassdb(self.classname)
813 l = [] 817 l = []
814 for id in self.db.getnodeids(self.classname, db=cldb): 818 try:
815 node = self.db.getnode(self.classname, id, db=cldb) 819 for id in self.db.getnodeids(self.classname, db=cldb):
816 if node.has_key(self.db.RETIRED_FLAG): 820 node = self.db.getnode(self.classname, id, db=cldb)
817 continue 821 if node.has_key(self.db.RETIRED_FLAG):
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):
821 continue 822 continue
822 if type(nodeids) is type(''): 823 for propname, nodeids in propspec:
823 nodeids = {nodeids:1} 824 # can't test if the node doesn't have this property
824 prop = self.properties[propname] 825 if not node.has_key(propname):
825 value = node[propname] 826 continue
826 if isinstance(prop, Link) and nodeids.has_key(value): 827 if type(nodeids) is type(''):
827 l.append(id) 828 nodeids = {nodeids:1}
828 break 829 prop = self.properties[propname]
829 elif isinstance(prop, Multilink): 830 value = node[propname]
830 hit = 0 831 if isinstance(prop, Link) and nodeids.has_key(value):
831 for v in value: 832 l.append(id)
832 if nodeids.has_key(v): 833 break
833 l.append(id) 834 elif isinstance(prop, Multilink):
834 hit = 1 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:
835 break 842 break
836 if hit: 843 except:
837 break 844 cldb.close()
838 return l 845 return l
839 846
840 def stringFind(self, **requirements): 847 def stringFind(self, **requirements):
841 """Locate a particular node by matching a set of its String 848 """Locate a particular node by matching a set of its String
842 properties in a caseless search. 849 properties in a caseless search.
850 if isinstance(not prop, String): 857 if isinstance(not prop, String):
851 raise TypeError, "'%s' not a String property"%propname 858 raise TypeError, "'%s' not a String property"%propname
852 requirements[propname] = requirements[propname].lower() 859 requirements[propname] = requirements[propname].lower()
853 l = [] 860 l = []
854 cldb = self.db.getclassdb(self.classname) 861 cldb = self.db.getclassdb(self.classname)
855 for nodeid in self.db.getnodeids(self.classname, cldb): 862 try:
856 node = self.db.getnode(self.classname, nodeid, cldb) 863 for nodeid in self.db.getnodeids(self.classname, cldb):
857 if node.has_key(self.db.RETIRED_FLAG): 864 node = self.db.getnode(self.classname, nodeid, cldb)
858 continue 865 if node.has_key(self.db.RETIRED_FLAG):
859 for key, value in requirements.items(): 866 continue
860 if node[key] and node[key].lower() != value: 867 for key, value in requirements.items():
861 break 868 if node[key] and node[key].lower() != value:
862 else: 869 break
863 l.append(nodeid) 870 else:
871 l.append(nodeid)
872 finally:
873 cldb.close()
864 return l 874 return l
865 875
866 def list(self): 876 def list(self):
867 """Return a list of the ids of the active nodes in this class.""" 877 """Return a list of the ids of the active nodes in this class."""
868 l = [] 878 l = []
869 cn = self.classname 879 cn = self.classname
870 cldb = self.db.getclassdb(cn) 880 cldb = self.db.getclassdb(cn)
871 for nodeid in self.db.getnodeids(cn, cldb): 881 try:
872 node = self.db.getnode(cn, nodeid, cldb) 882 for nodeid in self.db.getnodeids(cn, cldb):
873 if node.has_key(self.db.RETIRED_FLAG): 883 node = self.db.getnode(cn, nodeid, cldb)
874 continue 884 if node.has_key(self.db.RETIRED_FLAG):
875 l.append(nodeid) 885 continue
886 l.append(nodeid)
887 finally:
888 cldb.close()
876 l.sort() 889 l.sort()
877 return l 890 return l
878 891
879 # XXX not in spec 892 # XXX not in spec
880 def filter(self, search_matches, filterspec, sort, group, 893 def filter(self, search_matches, filterspec, sort, group,
933 filterspec = l 946 filterspec = l
934 947
935 # now, find all the nodes that are active and pass filtering 948 # now, find all the nodes that are active and pass filtering
936 l = [] 949 l = []
937 cldb = self.db.getclassdb(cn) 950 cldb = self.db.getclassdb(cn)
938 for nodeid in self.db.getnodeids(cn, cldb): 951 try:
939 node = self.db.getnode(cn, nodeid, cldb) 952 for nodeid in self.db.getnodeids(cn, cldb):
940 if node.has_key(self.db.RETIRED_FLAG): 953 node = self.db.getnode(cn, nodeid, cldb)
941 continue 954 if node.has_key(self.db.RETIRED_FLAG):
942 # apply filter 955 continue
943 for t, k, v in filterspec: 956 # apply filter
944 # this node doesn't have this property, so reject it 957 for t, k, v in filterspec:
945 if not node.has_key(k): break 958 # this node doesn't have this property, so reject it
946 959 if not node.has_key(k): break
947 if t == 0 and node[k] not in v: 960
948 # link - if this node'd property doesn't appear in the 961 if t == 0 and node[k] not in v:
949 # filterspec's nodeid list, skip it 962 # link - if this node'd property doesn't appear in the
950 break 963 # filterspec's nodeid list, skip it
951 elif t == 1: 964 break
952 # multilink - if any of the nodeids required by the 965 elif t == 1:
953 # filterspec aren't in this node's property, then skip 966 # multilink - if any of the nodeids required by the
954 # it 967 # filterspec aren't in this node's property, then skip
955 for value in v: 968 # it
956 if value not in node[k]: 969 for value in v:
957 break 970 if value not in node[k]:
958 else: 971 break
959 continue 972 else:
960 break 973 continue
961 elif t == 2 and (node[k] is None or not v.search(node[k])): 974 break
962 # RE search 975 elif t == 2 and (node[k] is None or not v.search(node[k])):
963 break 976 # RE search
964 elif t == 6 and node[k] != v: 977 break
965 # straight value comparison for the other types 978 elif t == 6 and node[k] != v:
966 break 979 # straight value comparison for the other types
967 else: 980 break
968 l.append((nodeid, node)) 981 else:
982 l.append((nodeid, node))
983 finally:
984 cldb.close()
969 l.sort() 985 l.sort()
970 986
971 # filter based on full text search 987 # filter based on full text search
972 if search_matches is not None: 988 if search_matches is not None:
973 k = [] 989 k = []
1197 cl.create(name=options[i], order=i) 1213 cl.create(name=options[i], order=i)
1198 return hyperdb.Link(name) 1214 return hyperdb.Link(name)
1199 1215
1200 # 1216 #
1201 # $Log: not supported by cvs2svn $ 1217 # $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 #
1202 # Revision 1.71 2002/07/09 03:02:52 richard 1224 # Revision 1.71 2002/07/09 03:02:52 richard
1203 # More indexer work: 1225 # More indexer work:
1204 # - all String properties may now be indexed too. Currently there's a bit of 1226 # - all String properties may now be indexed too. Currently there's a bit of
1205 # "issue" specific code in the actual searching which needs to be 1227 # "issue" specific code in the actual searching which needs to be
1206 # addressed. In a nutshell: 1228 # addressed. In a nutshell:

Roundup Issue Tracker: http://roundup-tracker.org/