comparison roundup/support.py @ 3635:53987aa153d2

Transitive-property support. - Fixed some of the pet-peeves from pep8 - Better parameter names for new _subselect method - use new-style class for support.Proptree but needed a new-style class for the property I introduced anyway. - Fix a bug where searching did the wrong thing (interestingly enough the same wrong thing for all backends): A search for {'messages': ['1'], 'messages.author': ['2']} would ignore the 'messages' part (messages being non-leaf node in proptree). Fixed and added a regression test for this. - Added the transitive searching to the SearchAction. New method get_transitive_prop introduced in hyperdb that does the transitive version of getprops()[name]. Fixed two tests to use the (faked) method instead of getprop. Now searching for transitive props via the web-interface works for me. Thanks to alexander smishlajev for pointing me at the coding style. Sorry for stepping on the peeves -- I'm using a different coding style in most other projects I'm doing ...
author Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
date Thu, 13 Jul 2006 10:14:56 +0000
parents 57c66056ffe4
children fa7becc62534
comparison
equal deleted inserted replaced
3634:57c66056ffe4 3635:53987aa153d2
4 4
5 __docformat__ = 'restructuredtext' 5 __docformat__ = 'restructuredtext'
6 6
7 import os, time, sys 7 import os, time, sys
8 import hyperdb 8 import hyperdb
9
10 from sets import Set
9 11
10 class TruthDict: 12 class TruthDict:
11 '''Returns True for valid keys, False for others. 13 '''Returns True for valid keys, False for others.
12 ''' 14 '''
13 def __init__(self, keys): 15 def __init__(self, keys):
30 32
31 Currently only implements method 'append' and iteration from a 33 Currently only implements method 'append' and iteration from a
32 full list interface. 34 full list interface.
33 Implementation: We manage a "sorted" status and sort on demand. 35 Implementation: We manage a "sorted" status and sort on demand.
34 Appending to the list will require re-sorting before use. 36 Appending to the list will require re-sorting before use.
35 >>> p = PrioList () 37 >>> p = PrioList()
36 >>> for i in 5,7,1,-1 : 38 >>> for i in 5,7,1,-1:
37 ... p.append (i) 39 ... p.append(i)
38 ... 40 ...
39 >>> for k in p : 41 >>> for k in p:
40 ... print k 42 ... print k
41 ... 43 ...
42 -1 44 -1
43 1 45 1
44 5 46 5
48 def __init__(self): 50 def __init__(self):
49 self.list = [] 51 self.list = []
50 self.sorted = True 52 self.sorted = True
51 53
52 def append(self, item): 54 def append(self, item):
53 self.list.append (item) 55 self.list.append(item)
54 self.sorted = False 56 self.sorted = False
55 57
56 def __iter__(self): 58 def __iter__(self):
57 if not self.sorted : 59 if not self.sorted:
58 self.list.sort () 60 self.list.sort()
59 self.sorted = True 61 self.sorted = True
60 return iter (self.list) 62 return iter(self.list)
61 63
62 class Progress: 64 class Progress:
63 '''Progress display for console applications. 65 '''Progress display for console applications.
64 66
65 See __main__ block at end of file for sample usage. 67 See __main__ block at end of file for sample usage.
117 else: 119 else:
118 s = '%s %d done'%(self.info, self.num) 120 s = '%s %d done'%(self.info, self.num)
119 sys.stdout.write(s + ' '*(75-len(s)) + '\r') 121 sys.stdout.write(s + ' '*(75-len(s)) + '\r')
120 sys.stdout.flush() 122 sys.stdout.flush()
121 123
122 class Proptree : 124 class Proptree(object):
123 ''' Simple tree data structure for optimizing searching of properties 125 ''' Simple tree data structure for optimizing searching of properties
124 ''' 126 '''
125 127
126 def __init__ (self, db, cls, name, props, parent = None, val = None) : 128 def __init__(self, db, cls, name, props, parent = None, val = None):
127 self.db = db 129 self.db = db
128 self.name = name 130 self.name = name
129 self.props = props 131 self.props = props
130 self.parent = parent 132 self.parent = parent
131 self.val = val 133 self._val = val
132 self.cls = cls 134 self.cls = cls
133 self.classname = None 135 self.classname = None
134 self.uniqname = None 136 self.uniqname = None
135 self.children = [] 137 self.children = []
136 self.propnames = {} 138 self.propnames = {}
137 if parent : 139 if parent:
138 self.root = parent.root 140 self.root = parent.root
139 self.prcls = self.parent.props [name] 141 self.prcls = self.parent.props [name]
140 else : 142 else:
141 self.root = self 143 self.root = self
142 self.seqno = 1 144 self.seqno = 1
143 self.id = self.root.seqno 145 self.id = self.root.seqno
144 self.root.seqno += 1 146 self.root.seqno += 1
145 if self.cls : 147 if self.cls:
146 self.classname = self.cls.classname 148 self.classname = self.cls.classname
147 self.uniqname = '%s%s' % (self.cls.classname, self.id) 149 self.uniqname = '%s%s' % (self.cls.classname, self.id)
148 if not self.parent : 150 if not self.parent:
149 self.uniqname = self.cls.classname 151 self.uniqname = self.cls.classname
150 152
151 def append (self, name) : 153 def append(self, name):
152 if name in self.propnames : 154 """Append a property to self.children. Will create a new
155 propclass for the child.
156 """
157 if name in self.propnames:
153 return self.propnames [name] 158 return self.propnames [name]
154 propclass = self.props [name] 159 propclass = self.props [name]
155 cls = None 160 cls = None
156 props = None 161 props = None
157 if isinstance (propclass, (hyperdb.Link, hyperdb.Multilink)) : 162 if isinstance(propclass, (hyperdb.Link, hyperdb.Multilink)):
158 cls = self.db.getclass (propclass.classname) 163 cls = self.db.getclass(propclass.classname)
159 props = cls.getprops () 164 props = cls.getprops()
160 child = self.__class__ (self.db, cls, name, props, parent = self) 165 child = self.__class__(self.db, cls, name, props, parent = self)
161 self.children.append (child) 166 self.children.append(child)
162 self.propnames [name] = child 167 self.propnames [name] = child
163 return child 168 return child
164 169
165 def __iter__ (self) : 170 def _set_val(self, val):
171 """Check if self._val is already defined. If yes, we compute the
172 intersection of the old and the new value(s)
173 """
174 if self._val:
175 v = self._val
176 if not isinstance(self._val, type([])):
177 v = [self._val]
178 vals = Set(v)
179 vals.intersection_update(val)
180 self._val = [v for v in vals]
181 else:
182 self._val = val
183
184 val = property(lambda self: self._val, _set_val)
185
186 def __iter__(self):
166 """ Yield nodes in depth-first order -- visited nodes first """ 187 """ Yield nodes in depth-first order -- visited nodes first """
167 for p in self.children : 188 for p in self.children:
168 yield p 189 yield p
169 for c in p : 190 for c in p:
170 yield c 191 yield c
171 192
172 # vim: set et sts=4 sw=4 : 193 # vim: set et sts=4 sw=4 :

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