Merge ~cjwatson/launchpad:stormify-languagepack into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 4b893d1a62645aa69ea558080931fdf74a145f02
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:stormify-languagepack
Merge into: launchpad:master
Diff against target: 306 lines (+98/-78)
3 files modified
lib/lp/registry/model/distroseries.py (+26/-17)
lib/lp/translations/model/languagepack.py (+34/-24)
lib/lp/translations/vocabularies.py (+38/-37)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+394938@code.launchpad.net

Commit message

Convert LanguagePack to Storm

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
2index 2811a42..464c197 100644
3--- a/lib/lp/registry/model/distroseries.py
4+++ b/lib/lp/registry/model/distroseries.py
5@@ -35,7 +35,12 @@ from storm.expr import (
6 Or,
7 SQL,
8 )
9-from storm.locals import JSON
10+from storm.locals import (
11+ Int,
12+ JSON,
13+ Reference,
14+ ReferenceSet,
15+ )
16 from storm.store import Store
17 from zope.component import getUtility
18 from zope.interface import implementer
19@@ -245,20 +250,22 @@ class DistroSeries(SQLBase, BugTargetBase, HasSpecificationsMixin,
20 sourcecount = IntCol(notNull=True, default=DEFAULT)
21 defer_translation_imports = BoolCol(notNull=True, default=True)
22 hide_all_translations = BoolCol(notNull=True, default=True)
23- language_pack_base = ForeignKey(
24- foreignKey="LanguagePack", dbName="language_pack_base", notNull=False,
25- default=None)
26- language_pack_delta = ForeignKey(
27- foreignKey="LanguagePack", dbName="language_pack_delta",
28- notNull=False, default=None)
29- language_pack_proposed = ForeignKey(
30- foreignKey="LanguagePack", dbName="language_pack_proposed",
31- notNull=False, default=None)
32+ language_pack_base_id = Int(
33+ name="language_pack_base", allow_none=True, default=None)
34+ language_pack_base = Reference(language_pack_base_id, "LanguagePack.id")
35+ language_pack_delta_id = Int(
36+ name="language_pack_delta", allow_none=True, default=None)
37+ language_pack_delta = Reference(language_pack_delta_id, "LanguagePack.id")
38+ language_pack_proposed_id = Int(
39+ name="language_pack_proposed", allow_none=True, default=None)
40+ language_pack_proposed = Reference(
41+ language_pack_proposed_id, "LanguagePack.id")
42 language_pack_full_export_requested = BoolCol(notNull=True, default=False)
43 publishing_options = JSON("publishing_options")
44
45- language_packs = SQLMultipleJoin(
46- 'LanguagePack', joinColumn='distroseries', orderBy='-date_exported')
47+ language_packs = ReferenceSet(
48+ 'id', 'LanguagePack.distroseries_id',
49+ order_by=Desc('LanguagePack.date_exported'))
50 sections = SQLRelatedJoin(
51 'Section', joinColumn='distroseries', otherColumn='section',
52 intermediateTable='SectionSelection')
53@@ -794,15 +801,17 @@ class DistroSeries(SQLBase, BugTargetBase, HasSpecificationsMixin,
54
55 @property
56 def last_full_language_pack_exported(self):
57- return LanguagePack.selectFirstBy(
58- distroseries=self, type=LanguagePackType.FULL,
59- orderBy='-date_exported')
60+ language_packs = IStore(LanguagePack).find(
61+ LanguagePack, distroseries=self, type=LanguagePackType.FULL)
62+ return language_packs.order_by(LanguagePack.date_exported).last()
63
64 @property
65 def last_delta_language_pack_exported(self):
66- return LanguagePack.selectFirstBy(
67+ language_packs = IStore(LanguagePack).find(
68+ LanguagePack,
69 distroseries=self, type=LanguagePackType.DELTA,
70- updates=self.language_pack_base, orderBy='-date_exported')
71+ updates=self.language_pack_base)
72+ return language_packs.order_by(LanguagePack.date_exported).last()
73
74 @property
75 def backports_not_automatic(self):
76diff --git a/lib/lp/translations/model/languagepack.py b/lib/lp/translations/model/languagepack.py
77index 6de50f7..caa5a68 100644
78--- a/lib/lp/translations/model/languagepack.py
79+++ b/lib/lp/translations/model/languagepack.py
80@@ -1,4 +1,4 @@
81-# Copyright 2009 Canonical Ltd. This software is licensed under the
82+# Copyright 2009-2020 Canonical Ltd. This software is licensed under the
83 # GNU Affero General Public License version 3 (see the file LICENSE).
84
85 """Language pack store."""
86@@ -10,16 +10,17 @@ __all__ = [
87 'LanguagePackSet',
88 ]
89
90-from sqlobject import ForeignKey
91+import pytz
92+from storm.locals import (
93+ DateTime,
94+ Int,
95+ Reference,
96+ )
97 from zope.interface import implementer
98
99 from lp.services.database.constants import UTC_NOW
100-from lp.services.database.datetimecol import UtcDateTimeCol
101-from lp.services.database.enumcol import EnumCol
102-from lp.services.database.sqlbase import (
103- SQLBase,
104- sqlvalues,
105- )
106+from lp.services.database.enumcol import DBEnum
107+from lp.services.database.stormbase import StormBase
108 from lp.translations.enums import LanguagePackType
109 from lp.translations.interfaces.languagepack import (
110 ILanguagePack,
111@@ -28,24 +29,34 @@ from lp.translations.interfaces.languagepack import (
112
113
114 @implementer(ILanguagePack)
115-class LanguagePack(SQLBase):
116+class LanguagePack(StormBase):
117+
118+ __storm_table__ = 'LanguagePack'
119+
120+ id = Int(primary=True)
121
122- _table = 'LanguagePack'
123+ file_id = Int(name='file', allow_none=False)
124+ file = Reference(file_id, 'LibraryFileAlias.id')
125
126- file = ForeignKey(
127- foreignKey='LibraryFileAlias', dbName='file', notNull=True)
128+ date_exported = DateTime(
129+ tzinfo=pytz.UTC, allow_none=False, default=UTC_NOW)
130
131- date_exported = UtcDateTimeCol(notNull=True, default=UTC_NOW)
132+ distroseries_id = Int(name='distroseries', allow_none=False)
133+ distroseries = Reference(distroseries_id, 'DistroSeries.id')
134
135- distroseries = ForeignKey(
136- foreignKey='DistroSeries', dbName='distroseries', notNull=True)
137+ type = DBEnum(
138+ enum=LanguagePackType, allow_none=False, default=LanguagePackType.FULL)
139
140- type = EnumCol(
141- enum=LanguagePackType, notNull=True, default=LanguagePackType.FULL)
142+ updates_id = Int(name='updates', allow_none=True, default=None)
143+ updates = Reference(updates_id, 'LanguagePack.id')
144
145- updates = ForeignKey(
146- foreignKey='LanguagePack', dbName='updates',
147- notNull=False, default=None)
148+ def __init__(self, file, date_exported, distroseries, type, updates=None):
149+ super(LanguagePack, self).__init__()
150+ self.file = file
151+ self.date_exported = date_exported
152+ self.distroseries = distroseries
153+ self.type = type
154+ self.updates = updates
155
156
157 @implementer(ILanguagePackSet)
158@@ -57,11 +68,10 @@ class LanguagePackSet:
159 'Unknown language pack type: %s' % type.name)
160
161 if (type == LanguagePackType.DELTA and
162- distroseries.language_pack_base is None):
163+ distroseries.language_pack_base is None):
164 raise AssertionError(
165- "There is no base language pack available for %s's %s to get"
166- " deltas from." % sqlvalues(
167- distroseries.distribution.name, distroseries.name))
168+ "There is no base language pack available for %s to get"
169+ " deltas from." % distroseries)
170
171 updates = None
172 if type == LanguagePackType.DELTA:
173diff --git a/lib/lp/translations/vocabularies.py b/lib/lp/translations/vocabularies.py
174index 0da0c5f..99d54b3 100644
175--- a/lib/lp/translations/vocabularies.py
176+++ b/lib/lp/translations/vocabularies.py
177@@ -1,4 +1,4 @@
178-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the GNU
179+# Copyright 2009-2020 Canonical Ltd. This software is licensed under the GNU
180 # Affero General Public License version 3 (see the file LICENSE).
181
182 """Translations vocabularies."""
183@@ -16,13 +16,18 @@ __all__ = [
184 ]
185
186 from sqlobject import AND
187+from storm.locals import (
188+ Desc,
189+ Not,
190+ Or,
191+ )
192 from zope.schema.vocabulary import SimpleTerm
193
194 from lp.registry.interfaces.distroseries import IDistroSeries
195-from lp.services.database.sqlbase import sqlvalues
196 from lp.services.webapp.vocabulary import (
197 NamedSQLObjectVocabulary,
198 SQLObjectVocabularyBase,
199+ StormVocabularyBase,
200 )
201 from lp.services.worlddata.interfaces.language import ILanguage
202 from lp.services.worlddata.vocabularies import LanguageVocabulary
203@@ -119,53 +124,48 @@ class TranslationTemplateVocabulary(SQLObjectVocabularyBase):
204 return SimpleTerm(obj, obj.id, obj.name)
205
206
207-class FilteredLanguagePackVocabularyBase(SQLObjectVocabularyBase):
208+class FilteredLanguagePackVocabularyBase(StormVocabularyBase):
209 """Base vocabulary class to retrieve language packs for a distroseries."""
210 _table = LanguagePack
211- _orderBy = '-date_exported'
212+ _order_by = Desc(LanguagePack.date_exported)
213+
214+ def __init__(self, context=None):
215+ if not IDistroSeries.providedBy(context):
216+ raise AssertionError(
217+ "%s is only useful from a DistroSeries context." %
218+ self.__class__.__name__)
219+ super(FilteredLanguagePackVocabularyBase, self).__init__(context)
220
221 def toTerm(self, obj):
222 return SimpleTerm(
223 obj, obj.id, '%s' % obj.date_exported.strftime('%F %T %Z'))
224
225- def _baseQueryList(self):
226- """Return a list of sentences that defines the specific filtering.
227-
228- That list will be linked with an ' AND '.
229- """
230- raise NotImplementedError
231-
232- def __iter__(self):
233- if not IDistroSeries.providedBy(self.context):
234- # This vocabulary is only useful from a DistroSeries context.
235- return
236-
237- query = self._baseQueryList()
238- query.append('distroseries = %s' % sqlvalues(self.context))
239- language_packs = self._table.select(
240- ' AND '.join(query), orderBy=self._orderBy)
241-
242- for language_pack in language_packs:
243- yield self.toTerm(language_pack)
244+ @property
245+ def _clauses(self):
246+ return [LanguagePack.distroseries == self.context]
247
248
249 class FilteredFullLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
250 """Full export Language Pack for a distribution series."""
251 displayname = 'Select a full export language pack'
252
253- def _baseQueryList(self):
254- """See `FilteredLanguagePackVocabularyBase`."""
255- return ['type = %s' % sqlvalues(LanguagePackType.FULL)]
256+ @property
257+ def _clauses(self):
258+ return (
259+ super(FilteredFullLanguagePackVocabulary, self)._clauses +
260+ [LanguagePack.type == LanguagePackType.FULL])
261
262
263 class FilteredDeltaLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
264 """Delta export Language Pack for a distribution series."""
265 displayname = 'Select a delta export language pack'
266
267- def _baseQueryList(self):
268- """See `FilteredLanguagePackVocabularyBase`."""
269- return ['(type = %s AND updates = %s)' % sqlvalues(
270- LanguagePackType.DELTA, self.context.language_pack_base)]
271+ @property
272+ def _clauses(self):
273+ return (
274+ super(FilteredDeltaLanguagePackVocabulary, self)._clauses +
275+ [LanguagePack.type == LanguagePackType.DELTA,
276+ LanguagePack.updates == self.context.language_pack_base])
277
278
279 class FilteredLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
280@@ -176,8 +176,8 @@ class FilteredLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
281 obj, obj.id, '%s (%s)' % (
282 obj.date_exported.strftime('%F %T %Z'), obj.type.title))
283
284- def _baseQueryList(self):
285- """See `FilteredLanguagePackVocabularyBase`."""
286+ @property
287+ def _clauses(self):
288 # We are interested on any full language pack or language pack
289 # that is a delta of the current base lanuage pack type,
290 # except the ones already used.
291@@ -186,9 +186,10 @@ class FilteredLanguagePackVocabulary(FilteredLanguagePackVocabularyBase):
292 used_lang_packs.append(self.context.language_pack_base.id)
293 if self.context.language_pack_delta is not None:
294 used_lang_packs.append(self.context.language_pack_delta.id)
295- query = []
296+ clauses = []
297 if used_lang_packs:
298- query.append('id NOT IN %s' % sqlvalues(used_lang_packs))
299- query.append('(updates is NULL OR updates = %s)' % sqlvalues(
300- self.context.language_pack_base))
301- return query
302+ clauses.append(Not(LanguagePack.id.is_in(used_lang_packs)))
303+ clauses.append(Or(
304+ LanguagePack.updates == None,
305+ LanguagePack.updates == self.context.language_pack_base))
306+ return super(FilteredLanguagePackVocabulary, self)._clauses + clauses

Subscribers

People subscribed via source and target branches

to status/vote changes: