Mercurial > p > roundup > code
comparison roundup/hyperdb.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 | a15c15510e99 |
comparison
equal
deleted
inserted
replaced
| 3634:57c66056ffe4 | 3635:53987aa153d2 |
|---|---|
| 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.121 2006-07-08 18:28:18 schlatterbeck Exp $ | 18 # $Id: hyperdb.py,v 1.122 2006-07-13 10:14:56 schlatterbeck Exp $ |
| 19 | 19 |
| 20 """Hyperdatabase implementation, especially field types. | 20 """Hyperdatabase implementation, especially field types. |
| 21 """ | 21 """ |
| 22 __docformat__ = 'restructuredtext' | 22 __docformat__ = 'restructuredtext' |
| 23 | 23 |
| 711 """For some backends this implements the non-transitive | 711 """For some backends this implements the non-transitive |
| 712 search, for more information see the filter method. | 712 search, for more information see the filter method. |
| 713 """ | 713 """ |
| 714 raise NotImplementedError | 714 raise NotImplementedError |
| 715 | 715 |
| 716 def _proptree (self, filterspec) : | 716 def _proptree (self, filterspec): |
| 717 """Build a tree of all transitive properties in the given | 717 """Build a tree of all transitive properties in the given |
| 718 filterspec. | 718 filterspec. |
| 719 """ | 719 """ |
| 720 proptree = Proptree (self.db, self, '', self.getprops ()) | 720 proptree = Proptree (self.db, self, '', self.getprops ()) |
| 721 for key, v in filterspec.iteritems () : | 721 for key, v in filterspec.iteritems (): |
| 722 keys = key.split ('.') | 722 keys = key.split ('.') |
| 723 p = proptree | 723 p = proptree |
| 724 for k in keys : | 724 for k in keys: |
| 725 p = p.append (k) | 725 p = p.append (k) |
| 726 p.val = v | 726 p.val = v |
| 727 return proptree | 727 return proptree |
| 728 | 728 |
| 729 def _propsearch (self, search_matches, proptree, sort, group) : | 729 def _propsearch (self, search_matches, proptree, sort, group): |
| 730 """ Recursively search for the given properties in proptree. | 730 """ Recursively search for the given properties in proptree. |
| 731 Once all properties are non-transitive, the search generates a | 731 Once all properties are non-transitive, the search generates a |
| 732 simple _filter call which does the real work | 732 simple _filter call which does the real work |
| 733 """ | 733 """ |
| 734 for p in proptree.children : | 734 for p in proptree.children: |
| 735 if not p.children : continue | 735 if not p.children: |
| 736 continue | |
| 736 p.val = p.cls._propsearch (None, p, (None, None), (None, None)) | 737 p.val = p.cls._propsearch (None, p, (None, None), (None, None)) |
| 737 filterspec = dict ([(p.name, p.val) for p in proptree.children]) | 738 filterspec = dict ([(p.name, p.val) for p in proptree.children]) |
| 738 return self._filter (search_matches, filterspec, sort, group) | 739 return self._filter (search_matches, filterspec, sort, group) |
| 740 | |
| 741 def get_transitive_prop (self, propname_path, default = None) : | |
| 742 """Expand a transitive property (individual property names | |
| 743 separated by '.' into a new property at the end of the path. If | |
| 744 one of the names does not refer to a valid property, we return | |
| 745 None. | |
| 746 Example propname_path (for class issue): "messages.author" | |
| 747 """ | |
| 748 props = self.db.getclass(self.classname).getprops() | |
| 749 for k in propname_path.split('.'): | |
| 750 try : | |
| 751 prop = props[k] | |
| 752 except KeyError, TypeError: | |
| 753 return default | |
| 754 cl = getattr (prop, 'classname', None) | |
| 755 props = None | |
| 756 if cl: | |
| 757 props = self.db.getclass (cl).getprops() | |
| 758 return prop | |
| 739 | 759 |
| 740 def filter(self, search_matches, filterspec, sort=(None,None), | 760 def filter(self, search_matches, filterspec, sort=(None,None), |
| 741 group=(None,None)): | 761 group=(None,None)): |
| 742 """Return a list of the ids of the active nodes in this class that | 762 """Return a list of the ids of the active nodes in this class that |
| 743 match the 'filter' spec, sorted by the group spec and then the | 763 match the 'filter' spec, sorted by the group spec and then the |
