← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~twom/launchpad:questions-about-that-storm-porting into launchpad:master

 

Tom Wardill has proposed merging ~twom/launchpad:questions-about-that-storm-porting into launchpad:master.

Commit message:
Fix other references to Question now it's Storm ported

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~twom/launchpad/+git/launchpad/+merge/394836

FAQ, Question.get, statistics, and closeaccount all needed more fixes.
Also fix various unicode and SQL lookups in tests.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~twom/launchpad:questions-about-that-storm-porting into launchpad:master.
diff --git a/lib/lp/answers/model/faq.py b/lib/lp/answers/model/faq.py
index 70f4648..74b133c 100644
--- a/lib/lp/answers/model/faq.py
+++ b/lib/lp/answers/model/faq.py
@@ -96,7 +96,7 @@ class FAQ(SQLBase):
             return self.distribution
 
     def destroySelf(self):
-        if self.related_questions:
+        if not self.related_questions.is_empty():
             raise CannotDeleteFAQ(
                "Cannot delete FAQ: questions must be unlinked first.")
         super(FAQ, self).destroySelf()
diff --git a/lib/lp/answers/model/question.py b/lib/lp/answers/model/question.py
index f2fa7f4..f03ed40 100644
--- a/lib/lp/answers/model/question.py
+++ b/lib/lp/answers/model/question.py
@@ -841,8 +841,11 @@ class QuestionSet:
 
     def get(self, question_id, default=None):
         """See `IQuestionSet`."""
-        store = IStore(Question)
-        question = store.get(Question, question_id)
+        # search views produce strings, not integers
+        question_id = int(question_id)
+        question = IStore(Question).find(
+            Question,
+            Question.id == question_id).one()
         return question or default
 
     def getOpenQuestionCountByPackages(self, packages):
diff --git a/lib/lp/bugs/model/bug.py b/lib/lp/bugs/model/bug.py
index 12f9e72..b20d9bc 100644
--- a/lib/lp/bugs/model/bug.py
+++ b/lib/lp/bugs/model/bug.py
@@ -1534,7 +1534,7 @@ class Bug(SQLBase, InformationTypeMixin):
     @cachedproperty
     def _question_from_bug(self):
         for question in self.questions:
-            if (question.ownerID == self.ownerID
+            if (question.owner_id == self.ownerID
                 and question.datecreated == self.datecreated):
                 return question
         return None
diff --git a/lib/lp/coop/answersbugs/tests/test_doc.py b/lib/lp/coop/answersbugs/tests/test_doc.py
index b1bdc5d..dac74e4 100644
--- a/lib/lp/coop/answersbugs/tests/test_doc.py
+++ b/lib/lp/coop/answersbugs/tests/test_doc.py
@@ -52,8 +52,8 @@ def _createUbuntuBugTaskLinkedToQuestion():
     ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
     ubuntu.addAnswerContact(ubuntu_team, ubuntu_team.teamowner)
     ubuntu_question = ubuntu.newQuestion(
-        sample_person, "Can't install Ubuntu",
-        "I insert the install CD in the CD-ROM drive, but it won't boot.")
+        sample_person, u"Can't install Ubuntu",
+        u"I insert the install CD in the CD-ROM drive, but it won't boot.")
     no_priv = getUtility(IPersonSet).getByEmail('no-priv@xxxxxxxxxxxxx')
     params = CreateBugParams(
         owner=no_priv, title="Installer fails on a Mac PPC",
diff --git a/lib/lp/registry/scripts/closeaccount.py b/lib/lp/registry/scripts/closeaccount.py
index 9949b95..208c3e7 100644
--- a/lib/lp/registry/scripts/closeaccount.py
+++ b/lib/lp/registry/scripts/closeaccount.py
@@ -240,9 +240,10 @@ def close_account(username, log):
     # Reassign questions assigned to the user, and close all their questions
     # in non-final states since nobody else can.
     table_notification('Question')
-    store.find(Question, Question.assigneeID == person.id).set(assigneeID=None)
+    store.find(Question, Question.assignee_id == person.id).set(
+        assignee_id=None)
     owned_non_final_questions = store.find(
-        Question, Question.ownerID == person.id,
+        Question, Question.owner_id == person.id,
         Question.status.is_in([
             QuestionStatus.OPEN, QuestionStatus.NEEDSINFO,
             QuestionStatus.ANSWERED,
@@ -250,7 +251,7 @@ def close_account(username, log):
     owned_non_final_questions.set(
         status=QuestionStatus.SOLVED,
         whiteboard=(
-            'Closed by Launchpad due to owner requesting account removal'))
+            u'Closed by Launchpad due to owner requesting account removal'))
     skip.add(('question', 'owner'))
 
     # Remove rows from tables in simple cases in the given order
diff --git a/lib/lp/registry/tests/test_distribution.py b/lib/lp/registry/tests/test_distribution.py
index a053738..0b9f712 100644
--- a/lib/lp/registry/tests/test_distribution.py
+++ b/lib/lp/registry/tests/test_distribution.py
@@ -805,7 +805,7 @@ class TestDistributionWebservice(TestCaseWithFactory):
         with person_logged_in(self.person):
             distro = self.factory.makeDistribution()
             self.factory.makeQuestion(
-                title="Crash with %s" % oopsid, target=distro)
+                title=u"Crash with %s" % oopsid, target=distro)
             distro_url = api_url(distro)
 
         now = datetime.datetime.now(tz=pytz.utc)
@@ -830,7 +830,7 @@ class TestDistributionWebservice(TestCaseWithFactory):
         # check the filter is tight enough - other contexts should not work.
         oopsid = "OOPS-abcdef1234"
         with person_logged_in(self.person):
-            self.factory.makeQuestion(title="Crash with %s" % oopsid)
+            self.factory.makeQuestion(title=u"Crash with %s" % oopsid)
             distro = self.factory.makeDistribution()
             distro_url = api_url(distro)
         now = datetime.datetime.now(tz=pytz.utc)
diff --git a/lib/lp/registry/tests/test_oopsreferences.py b/lib/lp/registry/tests/test_oopsreferences.py
index 8633b9e..54e8514 100644
--- a/lib/lp/registry/tests/test_oopsreferences.py
+++ b/lib/lp/registry/tests/test_oopsreferences.py
@@ -92,7 +92,7 @@ class TestOopsReferences(TestCaseWithFactory):
 
     def test_oops_in_question_title(self):
         oopsid = "OOPS-abcdef1234"
-        question = self.factory.makeQuestion(title="Crash with %s" % oopsid)
+        question = self.factory.makeQuestion(title=u"Crash with %s" % oopsid)
         self.store.flush()
         now = datetime.now(tz=utc)
         day = timedelta(days=1)
@@ -107,7 +107,7 @@ class TestOopsReferences(TestCaseWithFactory):
 
     def test_oops_in_question_wrong_context(self):
         oopsid = "OOPS-abcdef1234"
-        question = self.factory.makeQuestion(title="Crash with %s" % oopsid)
+        question = self.factory.makeQuestion(title=u"Crash with %s" % oopsid)
         self.store.flush()
         now = datetime.now(tz=utc)
         day = timedelta(days=1)
@@ -120,7 +120,7 @@ class TestOopsReferences(TestCaseWithFactory):
     def test_oops_in_question_description(self):
         oopsid = "OOPS-abcdef1234"
         question = self.factory.makeQuestion(
-            description="Crash with %s" % oopsid)
+            description=u"Crash with %s" % oopsid)
         self.store.flush()
         now = datetime.now(tz=utc)
         day = timedelta(days=1)
@@ -137,7 +137,7 @@ class TestOopsReferences(TestCaseWithFactory):
         oopsid = "OOPS-abcdef1234"
         question = self.factory.makeQuestion()
         with person_logged_in(question.owner):
-            question.whiteboard = "Crash with %s" % oopsid
+            question.whiteboard = u"Crash with %s" % oopsid
             self.store.flush()
         now = datetime.now(tz=utc)
         day = timedelta(days=1)
@@ -155,7 +155,7 @@ class TestOopsReferences(TestCaseWithFactory):
         distro = self.factory.makeDistribution()
         question = self.factory.makeQuestion(target=distro)
         with person_logged_in(question.owner):
-            question.whiteboard = "Crash with %s" % oopsid
+            question.whiteboard = u"Crash with %s" % oopsid
             self.store.flush()
         now = datetime.now(tz=utc)
         day = timedelta(days=1)
diff --git a/lib/lp/registry/tests/test_product.py b/lib/lp/registry/tests/test_product.py
index f34be9d..bf64c64 100644
--- a/lib/lp/registry/tests/test_product.py
+++ b/lib/lp/registry/tests/test_product.py
@@ -2145,7 +2145,7 @@ class TestWebService(WebServiceTestCase):
         # The product layer provides the context restriction, so we need to
         # check we can access context filtered references - e.g. on question.
         oopsid = "OOPS-abcdef1234"
-        question = self.factory.makeQuestion(title="Crash with %s" % oopsid)
+        question = self.factory.makeQuestion(title=u"Crash with %s" % oopsid)
         product = question.product
         transaction.commit()
         ws_product = self.wsObject(product, product.owner)
@@ -2163,7 +2163,7 @@ class TestWebService(WebServiceTestCase):
         # The product layer provides the context restriction, so we need to
         # check the filter is tight enough - other contexts should not work.
         oopsid = "OOPS-abcdef1234"
-        self.factory.makeQuestion(title="Crash with %s" % oopsid)
+        self.factory.makeQuestion(title=u"Crash with %s" % oopsid)
         product = self.factory.makeProduct()
         transaction.commit()
         ws_product = self.wsObject(product, product.owner)
diff --git a/lib/lp/services/database/doc/textsearching.txt b/lib/lp/services/database/doc/textsearching.txt
index e5feb20..0cb4d67 100644
--- a/lib/lp/services/database/doc/textsearching.txt
+++ b/lib/lp/services/database/doc/textsearching.txt
@@ -689,9 +689,12 @@ rows will be excluded from the final search.
 
 More than 50% of the questions matches firefox:
 
-    >>> question_count = Question.select().count()
-    >>> firefox_questions = Question.select(
-    ...     'fti @@ ftq(%s)' % quote('firefox')).count()
+    >>> from lp.services.database.interfaces import IStore
+    >>> from lp.services.database.stormexpr import fti_search
+    >>> question_count = IStore(Question).find(Question).count()
+    >>> firefox_questions = IStore(Question).find(
+    ...     Question,
+    ...     fti_search(Question, "firefox")).count()
     >>> float(firefox_questions) / question_count > 0.50
     True
 
@@ -732,10 +735,11 @@ considered a stop word by tsearch2).
     >>> from lp.registry.model.product import Product
     >>> firefox_product = getUtility(IProductSet).getByName('firefox')
 
-    >>> firefox_count = Question.select(
-    ...     'product = %s' % firefox_product.id).count()
-    >>> get_questions = Question.select(
-    ...     'fti @@ ftq(%s)' % quote('get')).count()
+    >>> firefox_count = IStore(Question).find(
+    ...     Question, Question.product_id == firefox_product.id).count()
+    >>> get_questions = IStore(Question).find(
+    ...     Question,
+    ...     fti_search(Question, "get")).count()
     >>> float(get_questions) / firefox_count > 0.50
     True
 
@@ -754,7 +758,7 @@ string:
 When there are no candidate rows, only stemming and stop words removal
 is done.
 
-    >>> Question.select('product = -1').count()
+    >>> IStore(Question).find(Question, Question.product_id == -1).count()
     0
     >>> nl_phrase_search('firefox is very slow on flickr', Question,
     ...                  [Question.product == -1])
@@ -776,16 +780,19 @@ mozilla-firefox source package.
     >>> from lp.registry.interfaces.distribution import IDistributionSet
     >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
     >>> firefox_package = ubuntu.getSourcePackage('mozilla-firefox')
-    >>> firefox_package_questions = Question.select(
-    ...     'distribution = %s AND sourcepackagename = %s' % sqlvalues(
-    ...     ubuntu, firefox_package.sourcepackagename))
+    >>> firefox_package_id =firefox_package.sourcepackagename.id
+    >>> firefox_package_questions = IStore(Question).find(
+    ...     Question,
+    ...     Question.distribution_id == ubuntu.id,
+    ...     Question.sourcepackagename_id == firefox_package_id)
     >>> firefox_package_questions.count() < 5
     True
 
 And more than half of these contain the keyword "firefox" in them:
 
-    >>> firefox_questions = Question.select(
-    ...     'fti @@ ftq(%s)' % quote('firefox')).count()
+    >>> firefox_questions = IStore(Question).find(
+    ...     Question,
+    ...     fti_search(Question, "firefox"))
     >>> float(get_questions) / firefox_package_questions.count() > 0.50
     True
 
diff --git a/lib/lp/services/statistics/model/statistics.py b/lib/lp/services/statistics/model/statistics.py
index 7cbb6cb..40c7dec 100644
--- a/lib/lp/services/statistics/model/statistics.py
+++ b/lib/lp/services/statistics/model/statistics.py
@@ -207,19 +207,20 @@ class LaunchpadStatisticSet:
         ztm.commit()
 
     def _updateQuestionStatistics(self, ztm):
-        self.update('question_count', Question.select().count())
+        store = IStore(Question)
+        self.update('question_count', store.find(Question).count())
         ztm.commit()
 
         self.update(
             'answered_question_count',
-            Question.select(
-              'status = %s' % sqlvalues(QuestionStatus.ANSWERED)).count())
+            store.find(
+                Question, Question.status == QuestionStatus.ANSWERED).count())
         ztm.commit()
 
         self.update(
             'solved_question_count',
-            Question.select(
-              'status = %s' % sqlvalues(QuestionStatus.SOLVED)).count())
+            store.find(
+                Question, Question.status == QuestionStatus.SOLVED).count())
         ztm.commit()
 
         cur = cursor()