Merge ~cjwatson/launchpad:remove-sqlobjectvocabulary into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: f3d2c00c8e93149236beb15919a6e307412b3032
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:remove-sqlobjectvocabulary
Merge into: launchpad:master
Diff against target: 336 lines (+14/-192)
6 files modified
lib/lp/blueprints/vocabularies/specificationdependency.py (+1/-1)
lib/lp/registry/vocabularies.py (+3/-3)
lib/lp/services/webapp/marshallers.py (+2/-3)
lib/lp/services/webapp/vocabulary.py (+1/-164)
lib/lp/services/webservice/configure.zcml (+0/-14)
lib/lp/services/webservice/doc/webservice-marshallers.rst (+7/-7)
Reviewer Review Type Date Requested Status
Guruprasad Approve
Review via email: mp+451684@code.launchpad.net

Commit message

Remove SQLObjectVocabularyBase and NamedSQLObjectVocabulary

Description of the change

Superseded by `StormVocabularyBase` and `NamedStormVocabulary` respectively.

To post a comment you must log in.
Revision history for this message
Guruprasad (lgp171188) wrote :

LGTM 👍

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/blueprints/vocabularies/specificationdependency.py b/lib/lp/blueprints/vocabularies/specificationdependency.py
2index d458c05..f6edb5f 100644
3--- a/lib/lp/blueprints/vocabularies/specificationdependency.py
4+++ b/lib/lp/blueprints/vocabularies/specificationdependency.py
5@@ -168,7 +168,7 @@ class SpecificationDepCandidatesVocabulary(StormVocabularyBase):
6 raise LookupError(token)
7
8 def search(self, query, vocab_filter=None):
9- """See `SQLObjectVocabularyBase.search`.
10+ """See `StormVocabularyBase.search`.
11
12 We find specs where query is in the text of name or title, or matches
13 the full text index and then filter out ineligible specs using
14diff --git a/lib/lp/registry/vocabularies.py b/lib/lp/registry/vocabularies.py
15index 0104a33..4f4a761 100644
16--- a/lib/lp/registry/vocabularies.py
17+++ b/lib/lp/registry/vocabularies.py
18@@ -272,7 +272,7 @@ class ProductVocabulary(StormVocabularyBase):
19 return self.toTerm(product)
20
21 def search(self, query, vocab_filter=None):
22- """See `SQLObjectVocabularyBase`.
23+ """See `StormVocabularyBase`.
24
25 Returns products where the product name, displayname, title,
26 summary, or description contain the given query. Returns an empty list
27@@ -338,7 +338,7 @@ class ProjectGroupVocabulary(StormVocabularyBase):
28 return self.toTerm(project)
29
30 def search(self, query, vocab_filter=None):
31- """See `SQLObjectVocabularyBase`.
32+ """See `StormVocabularyBase`.
33
34 Returns projects where the project name, displayname, title,
35 summary, or description contain the given query. Returns an empty list
36@@ -1570,7 +1570,7 @@ class CommercialProjectsVocabulary(NamedStormVocabulary):
37 raise LookupError(token)
38
39 def searchForTerms(self, query=None, vocab_filter=None):
40- """See `SQLObjectVocabularyBase`."""
41+ """See `StormVocabularyBase`."""
42 results = self._doSearch(query)
43 num = results.count()
44 return CountableIterator(num, results, self.toTerm)
45diff --git a/lib/lp/services/webapp/marshallers.py b/lib/lp/services/webapp/marshallers.py
46index 7f13a36..48ab7ea 100644
47--- a/lib/lp/services/webapp/marshallers.py
48+++ b/lib/lp/services/webapp/marshallers.py
49@@ -6,14 +6,13 @@ __all__ = ["choiceMarshallerError"]
50
51 def choiceMarshallerError(field, request, vocabulary=None):
52 # We don't support marshalling a normal Choice field with a
53- # SQLObjectVocabularyBase/StormVocabularyBase-based vocabulary.
54+ # StormVocabularyBase-based vocabulary.
55 # Normally for this kind of use case, one returns None and
56 # lets the Zope machinery alert the user that the lookup has gone wrong.
57 # However, we want to be more helpful, so we make an assertion,
58 # with a comment on how to make things better.
59 raise AssertionError(
60- "You exported %s as an IChoice based on an "
61- "SQLObjectVocabularyBase/StormVocabularyBase; you "
62+ "You exported %s as an IChoice based on a StormVocabularyBase; you "
63 "should use lazr.restful.fields.ReferenceChoice "
64 "instead." % field.__name__
65 )
66diff --git a/lib/lp/services/webapp/vocabulary.py b/lib/lp/services/webapp/vocabulary.py
67index 535588c..b13b797 100644
68--- a/lib/lp/services/webapp/vocabulary.py
69+++ b/lib/lp/services/webapp/vocabulary.py
70@@ -13,20 +13,17 @@ __all__ = [
71 "FilteredVocabularyBase",
72 "ForgivingSimpleVocabulary",
73 "IHugeVocabulary",
74- "NamedSQLObjectVocabulary",
75 "NamedStormHugeVocabulary",
76 "NamedStormVocabulary",
77- "SQLObjectVocabularyBase",
78 "StormVocabularyBase",
79 "VocabularyFilter",
80 ]
81
82 from collections import namedtuple
83-from typing import Optional, Union
84+from typing import Optional
85
86 import six
87 from storm.base import Storm # noqa: B1
88-from storm.expr import Expr
89 from storm.store import EmptyResultSet
90 from zope.interface import Attribute, Interface, implementer
91 from zope.schema.interfaces import IVocabularyTokenized
92@@ -34,8 +31,6 @@ from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
93 from zope.security.proxy import isinstance as zisinstance
94
95 from lp.services.database.interfaces import IStore
96-from lp.services.database.sqlbase import SQLBase
97-from lp.services.database.sqlobject import AND, CONTAINSSTRING
98
99
100 class ForgivingSimpleVocabulary(SimpleVocabulary):
101@@ -266,164 +261,6 @@ class FilteredVocabularyBase:
102
103
104 @implementer(IVocabularyTokenized)
105-class SQLObjectVocabularyBase(FilteredVocabularyBase):
106- """A base class for widgets that are rendered to collect values
107- for attributes that are SQLObjects, e.g. ForeignKey.
108-
109- So if a content class behind some form looks like:
110-
111- class Foo(SQLObject):
112- id = IntCol(...)
113- bar = ForeignKey(...)
114- ...
115-
116- Then the vocabulary for the widget that captures a value for bar
117- should derive from SQLObjectVocabularyBase.
118- """
119-
120- _orderBy = None # type: Optional[str]
121- _filter = None # type: Optional[Union[Expr, bool]]
122- _clauseTables = None
123-
124- def __init__(self, context=None):
125- self.context = context
126-
127- # XXX kiko 2007-01-16: note that the method searchForTerms is part of
128- # IHugeVocabulary, and so should not necessarily need to be
129- # implemented here; however, many of our vocabularies depend on
130- # searchForTerms for popup functionality so I have chosen to just do
131- # that. It is possible that a better solution would be to have the
132- # search functionality produce a new vocabulary restricted to the
133- # desired subset.
134- def searchForTerms(self, query=None, vocab_filter=None):
135- results = self.search(query, vocab_filter)
136- return CountableIterator(results.count(), results, self.toTerm)
137-
138- def search(self, query, vocab_filter=None):
139- # This default implementation of searchForTerms glues together
140- # the legacy API of search() with the toTerm method. If you
141- # don't reimplement searchForTerms you will need to at least
142- # provide your own search() method.
143- raise NotImplementedError
144-
145- def toTerm(self, obj):
146- # This default implementation assumes that your object has a
147- # title attribute. If it does not you will need to reimplement
148- # toTerm, or reimplement the whole searchForTerms.
149- return SimpleTerm(obj, obj.id, obj.title)
150-
151- def __iter__(self):
152- """Return an iterator which provides the terms from the vocabulary."""
153- params = {}
154- if self._orderBy is not None:
155- params["orderBy"] = self._orderBy
156- if self._clauseTables is not None:
157- params["clauseTables"] = self._clauseTables
158- for obj in self._table.select(self._filter, **params):
159- yield self.toTerm(obj)
160-
161- def __len__(self):
162- return len(list(iter(self)))
163-
164- def __contains__(self, obj):
165- # Sometimes this method is called with an SQLBase instance, but
166- # z3 form machinery sends through integer ids. This might be due
167- # to a bug somewhere.
168- if zisinstance(obj, (SQLBase, Storm)): # noqa: B1
169- clause = self._table.id == obj.id
170- if self._filter:
171- # XXX kiko 2007-01-16: this code is untested.
172- clause = AND(clause, self._filter)
173- found_obj = IStore(self._table).find(self._table, clause).one()
174- return found_obj is not None and found_obj == obj
175- else:
176- clause = self._table.id == int(obj)
177- if self._filter:
178- # XXX kiko 2007-01-16: this code is untested.
179- clause = AND(clause, self._filter)
180- found_obj = IStore(self._table).find(self._table, clause).one()
181- return found_obj is not None
182-
183- def getTerm(self, value):
184- # Short circuit. There is probably a design problem here since
185- # we sometimes get the id and sometimes an SQLBase instance.
186- if zisinstance(value, SQLBase):
187- return self.toTerm(value)
188-
189- try:
190- value = int(value)
191- except ValueError:
192- raise LookupError(value)
193-
194- clause = self._table.q.id == value
195- if self._filter:
196- clause = AND(clause, self._filter)
197- try:
198- obj = self._table.selectOne(clause)
199- except ValueError:
200- raise LookupError(value)
201-
202- if obj is None:
203- raise LookupError(value)
204-
205- return self.toTerm(obj)
206-
207- def getTermByToken(self, token):
208- return self.getTerm(token)
209-
210- def emptySelectResults(self):
211- """Return a SelectResults object without any elements.
212-
213- This is to be used when no search string is given to the search()
214- method of subclasses, in order to be consistent and always return
215- a SelectResults object.
216- """
217- return self._table.select("1 = 2")
218-
219-
220-class NamedSQLObjectVocabulary(SQLObjectVocabularyBase):
221- """A SQLObjectVocabulary base for database tables that have a unique
222- *and* ASCII name column.
223-
224- Provides all methods required by IHugeVocabulary, although it
225- doesn't actually specify this interface since it may not actually
226- be huge and require the custom widgets.
227- """
228-
229- _orderBy = "name"
230-
231- def toTerm(self, obj):
232- """See SQLObjectVocabularyBase.
233-
234- This implementation uses name as a token instead of the object's
235- ID, and tries to be smart about deciding to present an object's
236- title if it has one.
237- """
238- if getattr(obj, "title", None) is None:
239- return SimpleTerm(obj, obj.name, obj.name)
240- else:
241- return SimpleTerm(obj, obj.name, obj.title)
242-
243- def getTermByToken(self, token):
244- clause = self._table.q.name == token
245- if self._filter:
246- clause = AND(clause, self._filter)
247- objs = list(self._table.select(clause))
248- if not objs:
249- raise LookupError(token)
250- return self.toTerm(objs[0])
251-
252- def search(self, query, vocab_filter=None):
253- """Return terms where query is a substring of the name."""
254- if query:
255- clause = CONTAINSSTRING(self._table.q.name, six.ensure_text(query))
256- if self._filter:
257- clause = AND(clause, self._filter)
258- return self._table.select(clause, orderBy=self._orderBy)
259- return self.emptySelectResults()
260-
261-
262-@implementer(IVocabularyTokenized)
263 class StormVocabularyBase(FilteredVocabularyBase):
264 """A base class for widgets that are rendered to collect values
265 for attributes that are Storm references.
266diff --git a/lib/lp/services/webservice/configure.zcml b/lib/lp/services/webservice/configure.zcml
267index d3136b5..5e27c1f 100644
268--- a/lib/lp/services/webservice/configure.zcml
269+++ b/lib/lp/services/webservice/configure.zcml
270@@ -60,13 +60,6 @@
271 <adapter
272 for="zope.schema.interfaces.IChoice
273 zope.publisher.interfaces.http.IHTTPRequest
274- lp.services.webapp.vocabulary.SQLObjectVocabularyBase"
275- provides="lazr.restful.interfaces.IFieldMarshaller"
276- factory="lp.services.webapp.marshallers.choiceMarshallerError"
277- />
278- <adapter
279- for="zope.schema.interfaces.IChoice
280- zope.publisher.interfaces.http.IHTTPRequest
281 lp.services.webapp.vocabulary.StormVocabularyBase"
282 provides="lazr.restful.interfaces.IFieldMarshaller"
283 factory="lp.services.webapp.marshallers.choiceMarshallerError"
284@@ -74,13 +67,6 @@
285 <adapter
286 for="lazr.restful.interfaces.IReferenceChoice
287 zope.publisher.interfaces.http.IHTTPRequest
288- lp.services.webapp.vocabulary.SQLObjectVocabularyBase"
289- provides="lazr.restful.interfaces.IFieldMarshaller"
290- factory="lazr.restful.marshallers.ObjectLookupFieldMarshaller"
291- />
292- <adapter
293- for="lazr.restful.interfaces.IReferenceChoice
294- zope.publisher.interfaces.http.IHTTPRequest
295 lp.services.webapp.vocabulary.StormVocabularyBase"
296 provides="lazr.restful.interfaces.IFieldMarshaller"
297 factory="lazr.restful.marshallers.ObjectLookupFieldMarshaller"
298diff --git a/lib/lp/services/webservice/doc/webservice-marshallers.rst b/lib/lp/services/webservice/doc/webservice-marshallers.rst
299index 6dedcee..f49a033 100644
300--- a/lib/lp/services/webservice/doc/webservice-marshallers.rst
301+++ b/lib/lp/services/webservice/doc/webservice-marshallers.rst
302@@ -25,10 +25,10 @@ application root.
303 >>> getUtility(IOpenLaunchBag).add(root)
304
305
306-Choice of SQLObjectVocabularyBase
307-.................................
308+Choice of StormVocabularyBase
309+.............................
310
311-For vocabularies based on SQLObjectVocabularyBase, the values are
312+For vocabularies based on StormVocabularyBase, the values are
313 interpreted as URLs referencing objects on the web service. If the given
314 string is a URL corresponding to a vocabulary item, the marshaller
315 returns that item. Otherwise it raises a ValueError.
316@@ -94,7 +94,7 @@ resource and not a random string.
317 >>> print(marshaller.representation_name)
318 some_person_link
319
320-If you export a Choice that uses an SQLObjectVocabularyBase then you
321+If you export a Choice that uses a StormVocabularyBase then you
322 get an error, as you should be using a ReferenceChoice instead to
323 ensure that the resulting wadl matches lazr.restful conventions.
324
325@@ -104,9 +104,9 @@ ensure that the resulting wadl matches lazr.restful conventions.
326 ... # doctest: +NORMALIZE_WHITESPACE
327 Traceback (most recent call last):
328 ...
329- AssertionError: You exported some_person as an IChoice based on an
330- SQLObjectVocabularyBase/StormVocabularyBase; you should use
331- lazr.restful.fields.ReferenceChoice instead.
332+ AssertionError: You exported some_person as an IChoice based on a
333+ StormVocabularyBase; you should use lazr.restful.fields.ReferenceChoice
334+ instead.
335
336 Cleanup.
337

Subscribers

People subscribed via source and target branches

to status/vote changes: