Mercurial > p > roundup > code
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: |
