← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

Commit message:
Convert CustomLanguageCode to Storm

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

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

Since I had to write a constructor anyway, I took the opportunity to make its signature more convenient.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-customlanguagecode into launchpad:master.
diff --git a/lib/lp/registry/model/distributionsourcepackage.py b/lib/lp/registry/model/distributionsourcepackage.py
index 2dd3121..9e40f02 100644
--- a/lib/lp/registry/model/distributionsourcepackage.py
+++ b/lib/lp/registry/model/distributionsourcepackage.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2016 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2020 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Classes to represent source packages in a distribution."""
@@ -498,13 +498,6 @@ class DistributionSourcePackage(BugTargetBase,
             CustomLanguageCode.distribution == self.distribution,
             CustomLanguageCode.sourcepackagename == self.sourcepackagename)
 
-    def createCustomLanguageCode(self, language_code, language):
-        """See `IHasCustomLanguageCodes`."""
-        return CustomLanguageCode(
-            distribution=self.distribution,
-            sourcepackagename=self.sourcepackagename,
-            language_code=language_code, language=language)
-
     @classmethod
     def _get(cls, distribution, sourcepackagename):
         return DistributionSourcePackageInDatabase.get(
diff --git a/lib/lp/registry/model/product.py b/lib/lp/registry/model/product.py
index 3a0acf0..ae43ede 100644
--- a/lib/lp/registry/model/product.py
+++ b/lib/lp/registry/model/product.py
@@ -1409,11 +1409,6 @@ class Product(SQLBase, BugTargetBase, MakesAnnouncements,
         """See `HasCustomLanguageCodesMixin`."""
         return CustomLanguageCode.product == self
 
-    def createCustomLanguageCode(self, language_code, language):
-        """See `IHasCustomLanguageCodes`."""
-        return CustomLanguageCode(
-            product=self, language_code=language_code, language=language)
-
     def userCanEdit(self, user):
         """See `IProduct`."""
         if user is None:
diff --git a/lib/lp/translations/interfaces/customlanguagecode.py b/lib/lp/translations/interfaces/customlanguagecode.py
index 5eceea6..5f01176 100644
--- a/lib/lp/translations/interfaces/customlanguagecode.py
+++ b/lib/lp/translations/interfaces/customlanguagecode.py
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2020 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 """Custom language code."""
 
@@ -56,7 +56,7 @@ class ICustomLanguageCode(Interface):
 class IHasCustomLanguageCodes(Interface):
     """A context that can have custom language codes attached.
 
-    Implemented by `Product` and `SourcePackage`.
+    Implemented by `Product` and `DistributionSourcePackage`.
     """
     custom_language_codes = Set(
         title=_("Custom language codes"),
diff --git a/lib/lp/translations/model/customlanguagecode.py b/lib/lp/translations/model/customlanguagecode.py
index 5ab9c5c..d6f5965 100644
--- a/lib/lp/translations/model/customlanguagecode.py
+++ b/lib/lp/translations/model/customlanguagecode.py
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2020 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Database class for `ICustomLanguageCode`."""
@@ -10,36 +10,62 @@ __all__ = [
     'HasCustomLanguageCodesMixin',
     ]
 
-
-from sqlobject import (
-    ForeignKey,
-    StringCol,
+from storm.locals import (
+    And,
+    Int,
+    Reference,
+    Unicode,
     )
-from storm.expr import And
 from zope.interface import implementer
 
+from lp.registry.interfaces.distributionsourcepackage import (
+    IDistributionSourcePackage,
+    )
+from lp.registry.interfaces.product import IProduct
 from lp.services.database.interfaces import IStore
-from lp.services.database.sqlbase import SQLBase
+from lp.services.database.stormbase import StormBase
 from lp.translations.interfaces.customlanguagecode import ICustomLanguageCode
 
 
 @implementer(ICustomLanguageCode)
-class CustomLanguageCode(SQLBase):
+class CustomLanguageCode(StormBase):
     """See `ICustomLanguageCode`."""
 
-    _table = 'CustomLanguageCode'
+    __storm_table__ = 'CustomLanguageCode'
+
+    id = Int(primary=True)
+
+    product_id = Int(name='product', allow_none=True, default=None)
+    product = Reference(product_id, 'Product.id')
+
+    distribution_id = Int(name='distribution', allow_none=True, default=None)
+    distribution = Reference(distribution_id, 'Distribution.id')
 
-    product = ForeignKey(
-        dbName='product', foreignKey='Product', notNull=False, default=None)
-    distribution = ForeignKey(
-        dbName='distribution', foreignKey='Distribution', notNull=False,
-        default=None)
-    sourcepackagename = ForeignKey(
-        dbName='sourcepackagename', foreignKey='SourcePackageName',
-        notNull=False, default=None)
-    language_code = StringCol(dbName='language_code', notNull=True)
-    language = ForeignKey(
-        dbName='language', foreignKey='Language', notNull=False, default=None)
+    sourcepackagename_id = Int(
+        name='sourcepackagename', allow_none=True, default=None)
+    sourcepackagename = Reference(sourcepackagename_id, 'SourcePackageName.id')
+
+    language_code = Unicode(name='language_code', allow_none=False)
+
+    language_id = Int(name='language', allow_none=True, default=None)
+    language = Reference(language_id, 'Language.id')
+
+    def __init__(self, translation_target, language_code, language=None):
+        super(CustomLanguageCode, self).__init__()
+        self.product = None
+        self.distribution = None
+        self.sourcepackagename = None
+        if IProduct.providedBy(translation_target):
+            self.product = translation_target
+        elif IDistributionSourcePackage.providedBy(translation_target):
+            self.distribution = translation_target.distribution
+            self.sourcepackagename = translation_target.sourcepackagename
+        else:
+            raise ValueError(
+                "Expected IProduct or IDistributionSourcePackage, got %r" %
+                translation_target)
+        self.language_code = language_code
+        self.language = language
 
     @property
     def translation_target(self):
@@ -66,8 +92,10 @@ class HasCustomLanguageCodesMixin:
         raise NotImplementedError("composeCustomLanguageCodeMatch")
 
     def createCustomLanguageCode(self, language_code, language):
-        """Define in child.  See `IHasCustomLanguageCodes`."""
-        raise NotImplementedError("createCustomLanguageCode")
+        """See `IHasCustomLanguageCodes`."""
+        return CustomLanguageCode(
+            translation_target=self,
+            language_code=language_code, language=language)
 
     def _queryCustomLanguageCodes(self, language_code=None):
         """Query `CustomLanguageCodes` belonging to `self`.
diff --git a/lib/lp/translations/tests/test_autoapproval.py b/lib/lp/translations/tests/test_autoapproval.py
index e1005e0..bae2319 100644
--- a/lib/lp/translations/tests/test_autoapproval.py
+++ b/lib/lp/translations/tests/test_autoapproval.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2020 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Unit tests for translation import queue auto-approval.
@@ -91,25 +91,25 @@ class TestCustomLanguageCode(TestCaseWithFactory):
 
         # Map "es_ES" to "no language."
         self.product_codes['es_ES'] = CustomLanguageCode(
-            product=self.product, language_code='es_ES')
+            translation_target=self.product, language_code='es_ES')
 
         # Map "pt_PT" to "pt."
         self.product_codes['pt_PT'] = CustomLanguageCode(
-            product=self.product, language_code='pt_PT',
+            translation_target=self.product, language_code='pt_PT',
             language=Language.byCode('pt'))
 
         self.distro = Distribution.byName('ubuntu')
         self.sourcepackagename = SourcePackageName.byName('evolution')
         self.package_codes['Brazilian'] = CustomLanguageCode(
-            distribution=self.distro,
-            sourcepackagename=self.sourcepackagename,
+            translation_target=self.distro.getSourcePackage(
+                self.sourcepackagename),
             language_code='Brazilian',
             language=Language.byCode('pt_BR'))
 
     def test_ICustomLanguageCode(self):
         # Does CustomLanguageCode conform to ICustomLanguageCode?
         custom_language_code = CustomLanguageCode(
-            language_code='sux', product=self.product)
+            language_code='sux', translation_target=self.product)
         verifyObject(ICustomLanguageCode, custom_language_code)
 
     def test_NoCustomLanguageCode(self):
@@ -202,9 +202,9 @@ class TestGuessPOFileCustomLanguageCode(TestCaseWithFactory,
         else:
             language = Language.byCode(target_language_code)
         customcode = CustomLanguageCode(
-            product=self.product, language_code=language_code,
+            translation_target=self.product, language_code=language_code,
             language=language)
-        customcode.syncUpdate()
+        Store.of(customcode).flush()
 
     def test_MatchWithoutCustomLanguageCode(self):
         # Of course matching will work without custom language codes.