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

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 982dca80e4da2851cfacbe25736acb841f331f65
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:stormify-bugwatch
Merge into: launchpad:master
Diff against target: 299 lines (+69/-50)
6 files modified
lib/lp/bugs/browser/tests/bugtask-adding-views.rst (+3/-3)
lib/lp/bugs/model/bug.py (+15/-8)
lib/lp/bugs/model/bugtask.py (+1/-1)
lib/lp/bugs/model/bugtracker.py (+2/-2)
lib/lp/bugs/model/bugwatch.py (+47/-35)
lib/lp/bugs/vocabularies.py (+1/-1)
Reviewer Review Type Date Requested Status
Guruprasad Approve
Review via email: mp+436042@code.launchpad.net

Commit message

Convert BugWatch to Storm

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/bugs/browser/tests/bugtask-adding-views.rst b/lib/lp/bugs/browser/tests/bugtask-adding-views.rst
2index e092d2e..9c8e91b 100644
3--- a/lib/lp/bugs/browser/tests/bugtask-adding-views.rst
4+++ b/lib/lp/bugs/browser/tests/bugtask-adding-views.rst
5@@ -361,7 +361,7 @@ linked to the new bug watch.
6 >>> add_task_view = get_and_setup_view(
7 ... firefox_task, "+choose-affected-product", form
8 ... )
9- ObjectCreatedEvent: <BugWatch at ...>
10+ ObjectCreatedEvent: <...BugWatch object at ...>
11 ObjectCreatedEvent: <BugTask ...>
12
13 >>> for bugtask in bug_four.bugtasks:
14@@ -389,7 +389,7 @@ and the bug watch will be added without any confirmation needed:
15 >>> add_task_view = get_and_setup_view(
16 ... firefox_task, "+choose-affected-product", form
17 ... )
18- ObjectCreatedEvent: <BugWatch at ...>
19+ ObjectCreatedEvent: <...BugWatch object at ...>
20 ObjectCreatedEvent: <BugTask ...>
21
22 >>> print(add_task_view.notifications)
23@@ -435,7 +435,7 @@ another bug links to the same bug.
24 >>> add_task_view = get_and_setup_view(
25 ... bug_five_task, "+choose-affected-product", form
26 ... )
27- ObjectCreatedEvent: <BugWatch at ...>
28+ ObjectCreatedEvent: <...BugWatch object at ...>
29 ObjectCreatedEvent: <BugTask ...>
30
31 >>> add_task_view.request.response.getHeader("Location")
32diff --git a/lib/lp/bugs/model/bug.py b/lib/lp/bugs/model/bug.py
33index 18d6d7d..e9a6304 100644
34--- a/lib/lp/bugs/model/bug.py
35+++ b/lib/lp/bugs/model/bug.py
36@@ -401,8 +401,10 @@ class Bug(SQLBase, InformationTypeMixin):
37 bug_messages = ReferenceSet(
38 "id", BugMessage.bug_id, order_by=BugMessage.index
39 )
40- watches = SQLMultipleJoin(
41- "BugWatch", joinColumn="bug", orderBy=["bugtracker_id", "remotebug"]
42+ watches = ReferenceSet(
43+ "id",
44+ BugWatch.bug_id,
45+ order_by=(BugWatch.bugtracker_id, BugWatch.remotebug),
46 )
47 duplicates = SQLMultipleJoin("Bug", joinColumn="duplicateof", orderBy="id")
48 linked_bugbranches = ReferenceSet(
49@@ -811,7 +813,7 @@ class Bug(SQLBase, InformationTypeMixin):
50 load_something("distribution_id", Distribution)
51 load_something("distroseries_id", DistroSeries)
52 load_something("sourcepackagename_id", SourcePackageName)
53- list(store.find(BugWatch, BugWatch.bugID == self.id))
54+ list(store.find(BugWatch, BugWatch.bug == self))
55 return sorted(tasks, key=bugtask_sort_key)
56
57 @property
58@@ -2122,11 +2124,16 @@ class Bug(SQLBase, InformationTypeMixin):
59 # This matching is a bit fragile, since bugwatch.remotebug
60 # is a user editable text string. We should improve the
61 # matching so that for example '#42' matches '42' and so on.
62- return BugWatch.selectFirstBy(
63- bug=self,
64- bugtracker=bugtracker,
65- remotebug=str(remote_bug),
66- orderBy="id",
67+ return (
68+ IStore(BugWatch)
69+ .find(
70+ BugWatch,
71+ bug=self,
72+ bugtracker=bugtracker,
73+ remotebug=str(remote_bug),
74+ )
75+ .order_by("id")
76+ .first()
77 )
78
79 def setStatus(self, target, status, user):
80diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
81index c006618..ed816e8 100644
82--- a/lib/lp/bugs/model/bugtask.py
83+++ b/lib/lp/bugs/model/bugtask.py
84@@ -2048,7 +2048,7 @@ class BugTaskSet:
85 Select(
86 1,
87 tables=[BugWatch],
88- where=[BugWatch.bugID == BugTaskFlat.bug_id],
89+ where=[BugWatch.bug_id == BugTaskFlat.bug_id],
90 )
91 )
92 ),
93diff --git a/lib/lp/bugs/model/bugtracker.py b/lib/lp/bugs/model/bugtracker.py
94index f589dc9..4fb96be 100644
95--- a/lib/lp/bugs/model/bugtracker.py
96+++ b/lib/lp/bugs/model/bugtracker.py
97@@ -317,7 +317,7 @@ class BugTracker(StormBase):
98 .find(
99 (BugWatch, Bug),
100 BugWatch.bugtracker == self,
101- BugWatch.bugID == Bug.id,
102+ BugWatch.bug_id == Bug.id,
103 )
104 .order_by(Desc(BugWatch.datecreated)),
105 result_decorator=itemgetter(0),
106@@ -565,7 +565,7 @@ class BugTracker(StormBase):
107 Store.of(self)
108 .find(
109 Bug,
110- BugWatch.bugID == Bug.id,
111+ BugWatch.bug_id == Bug.id,
112 BugWatch.bugtracker == self,
113 BugWatch.remotebug == remotebug,
114 )
115diff --git a/lib/lp/bugs/model/bugwatch.py b/lib/lp/bugs/model/bugwatch.py
116index c617a24..9732f16 100644
117--- a/lib/lp/bugs/model/bugwatch.py
118+++ b/lib/lp/bugs/model/bugwatch.py
119@@ -18,7 +18,7 @@ from lazr.lifecycle.snapshot import Snapshot
120 from lazr.uri import find_uris_in_text
121 from pytz import utc
122 from storm.expr import Desc, Not
123-from storm.locals import Int, Reference, Unicode
124+from storm.locals import DateTime, Int, Reference, Unicode
125 from storm.store import Store
126 from zope.component import getUtility
127 from zope.event import notify
128@@ -43,15 +43,8 @@ from lp.bugs.model.bugtask import BugTask
129 from lp.registry.interfaces.person import validate_public_person
130 from lp.services.database import bulk
131 from lp.services.database.constants import UTC_NOW
132-from lp.services.database.datetimecol import UtcDateTimeCol
133 from lp.services.database.enumcol import DBEnum
134 from lp.services.database.interfaces import IStore
135-from lp.services.database.sqlbase import SQLBase
136-from lp.services.database.sqlobject import (
137- ForeignKey,
138- SQLObjectNotFound,
139- StringCol,
140-)
141 from lp.services.database.stormbase import StormBase
142 from lp.services.helpers import shortlist
143 from lp.services.messages.model.message import Message
144@@ -100,27 +93,44 @@ class BugWatchDeletionError(Exception):
145
146
147 @implementer(IBugWatch)
148-class BugWatch(SQLBase):
149+class BugWatch(StormBase):
150 """See `IBugWatch`."""
151
152- _table = "BugWatch"
153- bug = ForeignKey(dbName="bug", foreignKey="Bug", notNull=True)
154+ __storm_table__ = "BugWatch"
155+ id = Int(primary=True)
156+ bug_id = Int(name="bug", allow_none=False)
157+ bug = Reference(bug_id, "Bug.id")
158 bugtracker_id = Int(name="bugtracker", allow_none=False)
159 bugtracker = Reference(bugtracker_id, "BugTracker.id")
160- remotebug = StringCol(notNull=True)
161- remotestatus = StringCol(notNull=False, default=None)
162- remote_importance = StringCol(notNull=False, default=None)
163- lastchanged = UtcDateTimeCol(notNull=False, default=None)
164- lastchecked = UtcDateTimeCol(notNull=False, default=None)
165+ remotebug = Unicode(allow_none=False)
166+ remotestatus = Unicode(allow_none=True, default=None)
167+ remote_importance = Unicode(allow_none=True, default=None)
168+ lastchanged = DateTime(allow_none=True, default=None, tzinfo=utc)
169+ lastchecked = DateTime(allow_none=True, default=None, tzinfo=utc)
170 last_error_type = DBEnum(enum=BugWatchActivityStatus, default=None)
171- datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW)
172- owner = ForeignKey(
173- dbName="owner",
174- foreignKey="Person",
175- storm_validator=validate_public_person,
176- notNull=True,
177+ datecreated = DateTime(allow_none=False, default=UTC_NOW, tzinfo=utc)
178+ owner_id = Int(
179+ name="owner", validator=validate_public_person, allow_none=False
180 )
181- next_check = UtcDateTimeCol()
182+ owner = Reference(owner_id, "Person.id")
183+ next_check = DateTime(tzinfo=utc)
184+
185+ def __init__(
186+ self,
187+ bug,
188+ bugtracker,
189+ remotebug,
190+ owner,
191+ datecreated=UTC_NOW,
192+ lastchanged=None,
193+ ):
194+ super().__init__()
195+ self.bug = bug
196+ self.bugtracker = bugtracker
197+ self.remotebug = remotebug
198+ self.owner = owner
199+ self.datecreated = datecreated
200+ self.lastchanged = lastchanged
201
202 @property
203 def bugtasks(self):
204@@ -173,9 +183,9 @@ class BugWatch(SQLBase):
205 if self.remote_importance != remote_importance:
206 self.remote_importance = remote_importance
207 self.lastchanged = UTC_NOW
208- # Sync the object in order to convert the UTC_NOW sql
209+ # Flush the object in order to convert the UTC_NOW sql
210 # constant to a datetime value.
211- self.sync()
212+ IStore(self).flush()
213 for linked_bugtask in self.bugtasks_to_update:
214 old_bugtask = Snapshot(
215 linked_bugtask, providing=providedBy(linked_bugtask)
216@@ -198,9 +208,9 @@ class BugWatch(SQLBase):
217 if self.remotestatus != remote_status:
218 self.remotestatus = remote_status
219 self.lastchanged = UTC_NOW
220- # Sync the object in order to convert the UTC_NOW sql
221+ # Flush the object in order to convert the UTC_NOW sql
222 # constant to a datetime value.
223- self.sync()
224+ IStore(self).flush()
225 for linked_bugtask in self.bugtasks_to_update:
226 old_bugtask = Snapshot(
227 linked_bugtask, providing=providedBy(linked_bugtask)
228@@ -231,11 +241,11 @@ class BugWatch(SQLBase):
229 )
230 # Remove any BugWatchActivity entries for this bug watch.
231 self.activity.remove()
232+ store = Store.of(self)
233+ store.remove(self)
234 # XXX 2010-09-29 gmb bug=647103
235 # We flush the store to make sure that errors bubble up and
236 # are caught by the OOPS machinery.
237- SQLBase.destroySelf(self)
238- store = Store.of(self)
239 store.flush()
240
241 @property
242@@ -421,13 +431,13 @@ class BugWatchSet:
243
244 def get(self, watch_id):
245 """See `IBugWatch`Set."""
246- try:
247- return BugWatch.get(watch_id)
248- except SQLObjectNotFound:
249+ watch = IStore(BugWatch).get(BugWatch, watch_id)
250+ if watch is None:
251 raise NotFoundError(watch_id)
252+ return watch
253
254 def search(self):
255- return BugWatch.select()
256+ return IStore(BugWatch).find(BugWatch)
257
258 def fromText(self, text, bug, owner):
259 """See `IBugWatchSet`."""
260@@ -489,7 +499,7 @@ class BugWatchSet:
261
262 def createBugWatch(self, bug, owner, bugtracker, remotebug):
263 """See `IBugWatchSet`."""
264- return BugWatch(
265+ watch = BugWatch(
266 bug=bug,
267 owner=owner,
268 datecreated=UTC_NOW,
269@@ -497,6 +507,8 @@ class BugWatchSet:
270 bugtracker=bugtracker,
271 remotebug=remotebug,
272 )
273+ IStore(watch).flush()
274+ return watch
275
276 def parseBugzillaURL(self, scheme, host, path, query):
277 """Extract the Bugzilla base URL and bug ID."""
278@@ -828,7 +840,7 @@ class BugWatchActivity(StormBase):
279 id = Int(primary=True)
280 bug_watch_id = Int(name="bug_watch")
281 bug_watch = Reference(bug_watch_id, BugWatch.id)
282- activity_date = UtcDateTimeCol(notNull=True)
283+ activity_date = DateTime(allow_none=False, tzinfo=utc)
284 result = DBEnum(enum=BugWatchActivityStatus, allow_none=True)
285 message = Unicode()
286 oops_id = Unicode()
287diff --git a/lib/lp/bugs/vocabularies.py b/lib/lp/bugs/vocabularies.py
288index 10a96f9..d6480bf 100644
289--- a/lib/lp/bugs/vocabularies.py
290+++ b/lib/lp/bugs/vocabularies.py
291@@ -159,7 +159,7 @@ def project_products_using_malone_vocabulary_factory(context):
292 )
293
294
295-class BugWatchVocabulary(SQLObjectVocabularyBase):
296+class BugWatchVocabulary(StormVocabularyBase):
297 _table = BugWatch
298
299 def __iter__(self):

Subscribers

People subscribed via source and target branches

to status/vote changes: