launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #04456
[Merge] lp:~stevenk/launchpad/pillarname-vocab into lp:launchpad
Steve Kowalik has proposed merging lp:~stevenk/launchpad/pillarname-vocab into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #541979 in Launchpad itself: "search project "ubuntu" returns nothing"
https://bugs.launchpad.net/launchpad/+bug/541979
For more details, see:
https://code.launchpad.net/~stevenk/launchpad/pillarname-vocab/+merge/70091
This branch firstly Storm-ifies the PillarNameBase vocab. Secondly, we limit the number of searches to 100. Thirdly, we change the order results are returned in, with an exact match returned first with a rank of 100. The rest of the results are rank 50 and are mostly unordered.
--
https://code.launchpad.net/~stevenk/launchpad/pillarname-vocab/+merge/70091
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/pillarname-vocab into lp:launchpad.
=== modified file 'lib/lp/registry/doc/vocabularies.txt'
--- lib/lp/registry/doc/vocabularies.txt 2011-07-13 05:31:42 +0000
+++ lib/lp/registry/doc/vocabularies.txt 2011-08-01 23:32:45 +0000
@@ -1170,7 +1170,7 @@
token/name.
>>> [term.token for term in vocab.searchForTerms(query='ubuntu')]
- ['kubuntu', 'ubuntu', 'ubuntutest']
+ ['ubuntu', 'kubuntu', 'ubuntutest']
>>> vocab.getTermByToken('ubuntu').token
'ubuntu'
=== modified file 'lib/lp/registry/tests/test_pillar_vocabularies.py'
--- lib/lp/registry/tests/test_pillar_vocabularies.py 2010-12-22 20:44:25 +0000
+++ lib/lp/registry/tests/test_pillar_vocabularies.py 2011-08-01 23:32:45 +0000
@@ -18,7 +18,7 @@
class TestPillarVocabularyBase(TestCaseWithFactory):
- """Test that the ProductVocabulary behaves as expected."""
+ """Test that the PillarVocabulary behaves as expected."""
layer = DatabaseFunctionalLayer
def setUp(self):
@@ -48,11 +48,11 @@
self.vocabulary.getTermByToken, 'does-notexist')
def test_order_by_name(self):
- # Results are ordered by name.
+ # Results are ordered by rank, with exact matches first.
terms = self.vocabulary.searchForTerms('snark')
result = [term.value for term in terms]
self.assertEqual(
- [self.project_group, self.product, self.distribution], result)
+ [self.product, self.distribution, self.project_group], result)
class TestDistributionOrProductVocabulary(TestCaseWithFactory):
@@ -106,7 +106,7 @@
self.product.active = False
terms = self.vocabulary.searchForTerms('snark')
result = [term.value for term in terms]
- self.assertEqual([self.project_group, self.distribution], result)
+ self.assertEqual([self.distribution, self.project_group], result)
self.assertFalse(self.product in self.vocabulary)
def test_inactive_product_groups_are_excluded(self):
=== modified file 'lib/lp/registry/vocabularies.py'
--- lib/lp/registry/vocabularies.py 2011-07-26 19:09:48 +0000
+++ lib/lp/registry/vocabularies.py 2011-08-01 23:32:45 +0000
@@ -1870,10 +1870,12 @@
"""Active `IPillar` objects vocabulary."""
displayname = 'Needs to be overridden'
_table = PillarName
- _orderBy = 'name'
+ _limit = 100
def toTerm(self, obj):
"""See `IVocabulary`."""
+ if type(obj) == int:
+ return self.toTerm(PillarName.get(obj))
if IPillarName.providedBy(obj):
assert obj.active, 'Inactive object %s %d' % (
obj.__class__.__name__, obj.id)
@@ -1894,23 +1896,35 @@
def __contains__(self, obj):
raise NotImplementedError
+ def searchForTerms(self, query=None):
+ if not query:
+ return self.emptySelectResults()
+ query = ensure_unicode(query).lower()
+ store = IStore(PillarName)
+ equal_clauses = [PillarName.name == query]
+ like_clauses = [
+ PillarName.name != query, PillarName.name.contains_string(query)]
+ equal_clauses.extend(self._filter)
+ like_clauses.extend(self._filter)
+ ranked_results = store.execute(
+ Union(
+ Select(
+ (PillarName.id, SQL('100 AS rank')),
+ tables=[PillarName],
+ where=And(*equal_clauses)),
+ Select(
+ (PillarName.id, SQL('50 AS rank')),
+ tables=[PillarName],
+ where=And(*like_clauses)),
+ limit=self._limit, order_by='rank', all=True))
+ results = [row[0] for row in list(ranked_results)]
+ return self.iterator(len(results), results, self.toTerm)
+
class DistributionOrProductVocabulary(PillarVocabularyBase):
"""Active `IDistribution` or `IProduct` objects vocabulary."""
displayname = 'Select a project'
- _filter = """
- -- An active product/distro.
- ((active IS TRUE
- AND (product IS NOT NULL OR distribution IS NOT NULL)
- )
- OR
- -- Or an alias for an active product/distro.
- (alias_for IN (
- SELECT id FROM PillarName
- WHERE active IS TRUE AND
- (product IS NOT NULL OR distribution IS NOT NULL))
- ))
- """
+ _filter = [PillarName.project == None, PillarName.active == True]
def __contains__(self, obj):
if IProduct.providedBy(obj):
@@ -1923,7 +1937,7 @@
class DistributionOrProductOrProjectGroupVocabulary(PillarVocabularyBase):
"""Active `IProduct`, `IProjectGroup` or `IDistribution` vocabulary."""
displayname = 'Select a project'
- _filter = PillarName.q.active == True
+ _filter = [PillarName.active == True]
def __contains__(self, obj):
if IProduct.providedBy(obj) or IProjectGroup.providedBy(obj):