← Back to team overview

launchpad-reviewers team mailing list archive

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

 

Colin Watson has proposed merging ~cjwatson/launchpad:stormify-bugwatch into launchpad:master.

Commit message:
Convert BugWatch to Storm

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/436042
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-bugwatch into launchpad:master.
diff --git a/lib/lp/bugs/browser/tests/bugtask-adding-views.rst b/lib/lp/bugs/browser/tests/bugtask-adding-views.rst
index e092d2e..9c8e91b 100644
--- a/lib/lp/bugs/browser/tests/bugtask-adding-views.rst
+++ b/lib/lp/bugs/browser/tests/bugtask-adding-views.rst
@@ -361,7 +361,7 @@ linked to the new bug watch.
     >>> add_task_view = get_and_setup_view(
     ...     firefox_task, "+choose-affected-product", form
     ... )
-    ObjectCreatedEvent: <BugWatch at ...>
+    ObjectCreatedEvent: <...BugWatch object at ...>
     ObjectCreatedEvent: <BugTask ...>
 
     >>> for bugtask in bug_four.bugtasks:
@@ -389,7 +389,7 @@ and the bug watch will be added without any confirmation needed:
     >>> add_task_view = get_and_setup_view(
     ...     firefox_task, "+choose-affected-product", form
     ... )
-    ObjectCreatedEvent: <BugWatch at ...>
+    ObjectCreatedEvent: <...BugWatch object at ...>
     ObjectCreatedEvent: <BugTask ...>
 
     >>> print(add_task_view.notifications)
@@ -435,7 +435,7 @@ another bug links to the same bug.
     >>> add_task_view = get_and_setup_view(
     ...     bug_five_task, "+choose-affected-product", form
     ... )
-    ObjectCreatedEvent: <BugWatch at ...>
+    ObjectCreatedEvent: <...BugWatch object at ...>
     ObjectCreatedEvent: <BugTask ...>
 
     >>> add_task_view.request.response.getHeader("Location")
diff --git a/lib/lp/bugs/model/bug.py b/lib/lp/bugs/model/bug.py
index 18d6d7d..e9a6304 100644
--- a/lib/lp/bugs/model/bug.py
+++ b/lib/lp/bugs/model/bug.py
@@ -401,8 +401,10 @@ class Bug(SQLBase, InformationTypeMixin):
     bug_messages = ReferenceSet(
         "id", BugMessage.bug_id, order_by=BugMessage.index
     )
-    watches = SQLMultipleJoin(
-        "BugWatch", joinColumn="bug", orderBy=["bugtracker_id", "remotebug"]
+    watches = ReferenceSet(
+        "id",
+        BugWatch.bug_id,
+        order_by=(BugWatch.bugtracker_id, BugWatch.remotebug),
     )
     duplicates = SQLMultipleJoin("Bug", joinColumn="duplicateof", orderBy="id")
     linked_bugbranches = ReferenceSet(
@@ -811,7 +813,7 @@ class Bug(SQLBase, InformationTypeMixin):
         load_something("distribution_id", Distribution)
         load_something("distroseries_id", DistroSeries)
         load_something("sourcepackagename_id", SourcePackageName)
-        list(store.find(BugWatch, BugWatch.bugID == self.id))
+        list(store.find(BugWatch, BugWatch.bug == self))
         return sorted(tasks, key=bugtask_sort_key)
 
     @property
@@ -2122,11 +2124,16 @@ class Bug(SQLBase, InformationTypeMixin):
         # This matching is a bit fragile, since bugwatch.remotebug
         # is a user editable text string. We should improve the
         # matching so that for example '#42' matches '42' and so on.
-        return BugWatch.selectFirstBy(
-            bug=self,
-            bugtracker=bugtracker,
-            remotebug=str(remote_bug),
-            orderBy="id",
+        return (
+            IStore(BugWatch)
+            .find(
+                BugWatch,
+                bug=self,
+                bugtracker=bugtracker,
+                remotebug=str(remote_bug),
+            )
+            .order_by("id")
+            .first()
         )
 
     def setStatus(self, target, status, user):
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index c006618..ed816e8 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -2048,7 +2048,7 @@ class BugTaskSet:
                     Select(
                         1,
                         tables=[BugWatch],
-                        where=[BugWatch.bugID == BugTaskFlat.bug_id],
+                        where=[BugWatch.bug_id == BugTaskFlat.bug_id],
                     )
                 )
             ),
diff --git a/lib/lp/bugs/model/bugtracker.py b/lib/lp/bugs/model/bugtracker.py
index f589dc9..4fb96be 100644
--- a/lib/lp/bugs/model/bugtracker.py
+++ b/lib/lp/bugs/model/bugtracker.py
@@ -317,7 +317,7 @@ class BugTracker(StormBase):
             .find(
                 (BugWatch, Bug),
                 BugWatch.bugtracker == self,
-                BugWatch.bugID == Bug.id,
+                BugWatch.bug_id == Bug.id,
             )
             .order_by(Desc(BugWatch.datecreated)),
             result_decorator=itemgetter(0),
@@ -565,7 +565,7 @@ class BugTracker(StormBase):
             Store.of(self)
             .find(
                 Bug,
-                BugWatch.bugID == Bug.id,
+                BugWatch.bug_id == Bug.id,
                 BugWatch.bugtracker == self,
                 BugWatch.remotebug == remotebug,
             )
diff --git a/lib/lp/bugs/model/bugwatch.py b/lib/lp/bugs/model/bugwatch.py
index c617a24..9732f16 100644
--- a/lib/lp/bugs/model/bugwatch.py
+++ b/lib/lp/bugs/model/bugwatch.py
@@ -18,7 +18,7 @@ from lazr.lifecycle.snapshot import Snapshot
 from lazr.uri import find_uris_in_text
 from pytz import utc
 from storm.expr import Desc, Not
-from storm.locals import Int, Reference, Unicode
+from storm.locals import DateTime, Int, Reference, Unicode
 from storm.store import Store
 from zope.component import getUtility
 from zope.event import notify
@@ -43,15 +43,8 @@ from lp.bugs.model.bugtask import BugTask
 from lp.registry.interfaces.person import validate_public_person
 from lp.services.database import bulk
 from lp.services.database.constants import UTC_NOW
-from lp.services.database.datetimecol import UtcDateTimeCol
 from lp.services.database.enumcol import DBEnum
 from lp.services.database.interfaces import IStore
-from lp.services.database.sqlbase import SQLBase
-from lp.services.database.sqlobject import (
-    ForeignKey,
-    SQLObjectNotFound,
-    StringCol,
-)
 from lp.services.database.stormbase import StormBase
 from lp.services.helpers import shortlist
 from lp.services.messages.model.message import Message
@@ -100,27 +93,44 @@ class BugWatchDeletionError(Exception):
 
 
 @implementer(IBugWatch)
-class BugWatch(SQLBase):
+class BugWatch(StormBase):
     """See `IBugWatch`."""
 
-    _table = "BugWatch"
-    bug = ForeignKey(dbName="bug", foreignKey="Bug", notNull=True)
+    __storm_table__ = "BugWatch"
+    id = Int(primary=True)
+    bug_id = Int(name="bug", allow_none=False)
+    bug = Reference(bug_id, "Bug.id")
     bugtracker_id = Int(name="bugtracker", allow_none=False)
     bugtracker = Reference(bugtracker_id, "BugTracker.id")
-    remotebug = StringCol(notNull=True)
-    remotestatus = StringCol(notNull=False, default=None)
-    remote_importance = StringCol(notNull=False, default=None)
-    lastchanged = UtcDateTimeCol(notNull=False, default=None)
-    lastchecked = UtcDateTimeCol(notNull=False, default=None)
+    remotebug = Unicode(allow_none=False)
+    remotestatus = Unicode(allow_none=True, default=None)
+    remote_importance = Unicode(allow_none=True, default=None)
+    lastchanged = DateTime(allow_none=True, default=None, tzinfo=utc)
+    lastchecked = DateTime(allow_none=True, default=None, tzinfo=utc)
     last_error_type = DBEnum(enum=BugWatchActivityStatus, default=None)
-    datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW)
-    owner = ForeignKey(
-        dbName="owner",
-        foreignKey="Person",
-        storm_validator=validate_public_person,
-        notNull=True,
+    datecreated = DateTime(allow_none=False, default=UTC_NOW, tzinfo=utc)
+    owner_id = Int(
+        name="owner", validator=validate_public_person, allow_none=False
     )
-    next_check = UtcDateTimeCol()
+    owner = Reference(owner_id, "Person.id")
+    next_check = DateTime(tzinfo=utc)
+
+    def __init__(
+        self,
+        bug,
+        bugtracker,
+        remotebug,
+        owner,
+        datecreated=UTC_NOW,
+        lastchanged=None,
+    ):
+        super().__init__()
+        self.bug = bug
+        self.bugtracker = bugtracker
+        self.remotebug = remotebug
+        self.owner = owner
+        self.datecreated = datecreated
+        self.lastchanged = lastchanged
 
     @property
     def bugtasks(self):
@@ -173,9 +183,9 @@ class BugWatch(SQLBase):
         if self.remote_importance != remote_importance:
             self.remote_importance = remote_importance
             self.lastchanged = UTC_NOW
-            # Sync the object in order to convert the UTC_NOW sql
+            # Flush the object in order to convert the UTC_NOW sql
             # constant to a datetime value.
-            self.sync()
+            IStore(self).flush()
         for linked_bugtask in self.bugtasks_to_update:
             old_bugtask = Snapshot(
                 linked_bugtask, providing=providedBy(linked_bugtask)
@@ -198,9 +208,9 @@ class BugWatch(SQLBase):
         if self.remotestatus != remote_status:
             self.remotestatus = remote_status
             self.lastchanged = UTC_NOW
-            # Sync the object in order to convert the UTC_NOW sql
+            # Flush the object in order to convert the UTC_NOW sql
             # constant to a datetime value.
-            self.sync()
+            IStore(self).flush()
         for linked_bugtask in self.bugtasks_to_update:
             old_bugtask = Snapshot(
                 linked_bugtask, providing=providedBy(linked_bugtask)
@@ -231,11 +241,11 @@ class BugWatch(SQLBase):
             )
         # Remove any BugWatchActivity entries for this bug watch.
         self.activity.remove()
+        store = Store.of(self)
+        store.remove(self)
         # XXX 2010-09-29 gmb bug=647103
         #     We flush the store to make sure that errors bubble up and
         #     are caught by the OOPS machinery.
-        SQLBase.destroySelf(self)
-        store = Store.of(self)
         store.flush()
 
     @property
@@ -421,13 +431,13 @@ class BugWatchSet:
 
     def get(self, watch_id):
         """See `IBugWatch`Set."""
-        try:
-            return BugWatch.get(watch_id)
-        except SQLObjectNotFound:
+        watch = IStore(BugWatch).get(BugWatch, watch_id)
+        if watch is None:
             raise NotFoundError(watch_id)
+        return watch
 
     def search(self):
-        return BugWatch.select()
+        return IStore(BugWatch).find(BugWatch)
 
     def fromText(self, text, bug, owner):
         """See `IBugWatchSet`."""
@@ -489,7 +499,7 @@ class BugWatchSet:
 
     def createBugWatch(self, bug, owner, bugtracker, remotebug):
         """See `IBugWatchSet`."""
-        return BugWatch(
+        watch = BugWatch(
             bug=bug,
             owner=owner,
             datecreated=UTC_NOW,
@@ -497,6 +507,8 @@ class BugWatchSet:
             bugtracker=bugtracker,
             remotebug=remotebug,
         )
+        IStore(watch).flush()
+        return watch
 
     def parseBugzillaURL(self, scheme, host, path, query):
         """Extract the Bugzilla base URL and bug ID."""
@@ -828,7 +840,7 @@ class BugWatchActivity(StormBase):
     id = Int(primary=True)
     bug_watch_id = Int(name="bug_watch")
     bug_watch = Reference(bug_watch_id, BugWatch.id)
-    activity_date = UtcDateTimeCol(notNull=True)
+    activity_date = DateTime(allow_none=False, tzinfo=utc)
     result = DBEnum(enum=BugWatchActivityStatus, allow_none=True)
     message = Unicode()
     oops_id = Unicode()
diff --git a/lib/lp/bugs/vocabularies.py b/lib/lp/bugs/vocabularies.py
index 10a96f9..d6480bf 100644
--- a/lib/lp/bugs/vocabularies.py
+++ b/lib/lp/bugs/vocabularies.py
@@ -159,7 +159,7 @@ def project_products_using_malone_vocabulary_factory(context):
     )
 
 
-class BugWatchVocabulary(SQLObjectVocabularyBase):
+class BugWatchVocabulary(StormVocabularyBase):
     _table = BugWatch
 
     def __iter__(self):