launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #30386
[Merge] ~cjwatson/launchpad:stormify-productseries into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:stormify-productseries into launchpad:master.
Commit message:
Convert ProductSeries to Storm
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/448908
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-productseries into launchpad:master.
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index c8cc080..6752c85 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -864,11 +864,11 @@ class BugTask(StormBase):
break
elif self.product:
assert (
- self.product.development_focusID is not None
+ self.product.development_focus_id is not None
), "A product should always have a development series."
- devel_focusID = self.product.development_focusID
+ devel_focus_id = self.product.development_focus_id
for bugtask in bugtasks:
- if bugtask.productseries_id == devel_focusID:
+ if bugtask.productseries_id == devel_focus_id:
conjoined_primary = bugtask
break
@@ -1978,7 +1978,10 @@ class BugTaskSet:
) AS subquery
GROUP BY status
"""
- query %= dict(series=quote(product_series), privacy=bug_privacy_filter)
+ query %= {
+ "series": quote(product_series.id),
+ "privacy": bug_privacy_filter,
+ }
cur = cursor()
cur.execute(query)
return {
@@ -2114,7 +2117,7 @@ class BugTaskSet:
LeftJoin(
Product,
Product.id.is_in(
- (BugTaskFlat.product_id, ProductSeries.productID)
+ (BugTaskFlat.product_id, ProductSeries.product_id)
),
),
),
@@ -2312,7 +2315,7 @@ class BugTaskSet:
distro_series_ids.add(task.distroseries_id)
product_ids.add(task.product_id)
if task.productseries:
- product_ids.add(task.productseries.productID)
+ product_ids.add(task.productseries.product_id)
product_series_ids.add(task.productseries_id)
distro_ids.discard(None)
diff --git a/lib/lp/bugs/model/bugtasksearch.py b/lib/lp/bugs/model/bugtasksearch.py
index f7a0fe1..222d404 100644
--- a/lib/lp/bugs/model/bugtasksearch.py
+++ b/lib/lp/bugs/model/bugtasksearch.py
@@ -1142,7 +1142,7 @@ def _build_exclude_conjoined_clause(milestone):
And(
ConjoinedPrimary.bug_id == BugTaskFlat.bug_id,
ConjoinedPrimary.productseries_id
- == Product.development_focusID,
+ == Product.development_focus_id,
Not(
ConjoinedPrimary._status.is_in(
BugTask._NON_CONJOINED_STATUSES
@@ -1154,7 +1154,7 @@ def _build_exclude_conjoined_clause(milestone):
# join.right is the table name.
join_tables = [(join.right, join) for join in joins]
elif milestone.product is not None:
- dev_focus_id = milestone.product.development_focusID
+ dev_focus_id = milestone.product.development_focus_id
join = LeftJoin(
ConjoinedPrimary,
And(
diff --git a/lib/lp/bugs/vocabularies.py b/lib/lp/bugs/vocabularies.py
index ecf92ef..fd7fd08 100644
--- a/lib/lp/bugs/vocabularies.py
+++ b/lib/lp/bugs/vocabularies.py
@@ -55,7 +55,7 @@ from lp.services.webapp.interfaces import ILaunchBag
from lp.services.webapp.vocabulary import (
CountableIterator,
IHugeVocabulary,
- NamedSQLObjectVocabulary,
+ NamedStormVocabulary,
StormVocabularyBase,
)
@@ -255,7 +255,7 @@ def BugNominatableSeriesVocabulary(context=None):
)
-class BugNominatableSeriesVocabularyBase(NamedSQLObjectVocabulary):
+class BugNominatableSeriesVocabularyBase(NamedStormVocabulary):
"""Base vocabulary class for series for which a bug can be nominated."""
def __iter__(self):
@@ -265,6 +265,15 @@ class BugNominatableSeriesVocabularyBase(NamedSQLObjectVocabulary):
if bug.canBeNominatedFor(series):
yield self.toTerm(series)
+ def __contains__(self, obj):
+ # NamedStormVocabulary implements this using a database query, but
+ # we need to go through __iter__ so that we filter the available
+ # series properly.
+ for term in self:
+ if term.value == obj:
+ return True
+ return False
+
def toTerm(self, obj):
return SimpleTerm(obj, obj.name, obj.name.capitalize())
@@ -292,7 +301,7 @@ class BugNominatableProductSeriesVocabulary(
_table = ProductSeries
def __init__(self, context, product):
- BugNominatableSeriesVocabularyBase.__init__(self, context)
+ super().__init__(context)
self.product = product
def _getNominatableObjects(self):
@@ -310,7 +319,7 @@ class BugNominatableDistroSeriesVocabulary(BugNominatableSeriesVocabularyBase):
_table = DistroSeries
def __init__(self, context, distribution):
- BugNominatableSeriesVocabularyBase.__init__(self, context)
+ super().__init__(context)
self.distribution = distribution
def _getNominatableObjects(self):
diff --git a/lib/lp/registry/interfaces/product.py b/lib/lp/registry/interfaces/product.py
index 429e26f..790f77d 100644
--- a/lib/lp/registry/interfaces/product.py
+++ b/lib/lp/registry/interfaces/product.py
@@ -894,7 +894,7 @@ class IProductView(
),
)
)
- development_focusID = Attribute("The development focus ID.")
+ development_focus_id = Attribute("The development focus ID.")
releases = exported(
doNotSnapshot(
diff --git a/lib/lp/registry/interfaces/productseries.py b/lib/lp/registry/interfaces/productseries.py
index 391b8a1..83b1120 100644
--- a/lib/lp/registry/interfaces/productseries.py
+++ b/lib/lp/registry/interfaces/productseries.py
@@ -141,7 +141,7 @@ class IProductSeriesLimitedView(Interface):
),
exported_as="project",
)
- productID = Attribute("The product ID.")
+ product_id = Attribute("The product ID.")
class IProductSeriesView(
diff --git a/lib/lp/registry/model/person.py b/lib/lp/registry/model/person.py
index c0d94ca..1aa22bc 100644
--- a/lib/lp/registry/model/person.py
+++ b/lib/lp/registry/model/person.py
@@ -1746,7 +1746,7 @@ class Person(
productseries = task.productseries
distroseries = task.distroseries
if productseries is not None and task.product is None:
- dev_focus_id = productseries.product.development_focusID
+ dev_focus_id = productseries.product.development_focus_id
if (
productseries.id == dev_focus_id
and task.status not in BugTask._NON_CONJOINED_STATUSES
diff --git a/lib/lp/registry/model/product.py b/lib/lp/registry/model/product.py
index 87291df..aee58b0 100644
--- a/lib/lp/registry/model/product.py
+++ b/lib/lp/registry/model/product.py
@@ -31,7 +31,7 @@ from storm.expr import (
Or,
Select,
)
-from storm.locals import Int, List, Reference, Store, Unicode
+from storm.locals import Int, List, Reference, ReferenceSet, Store, Unicode
from zope.component import getUtility
from zope.event import notify
from zope.interface import implementer
@@ -151,7 +151,6 @@ from lp.services.database.sqlbase import SQLBase, sqlvalues
from lp.services.database.sqlobject import (
BoolCol,
ForeignKey,
- SQLMultipleJoin,
SQLObjectNotFound,
StringCol,
)
@@ -344,12 +343,10 @@ class Product(
enum=TranslationPermission,
default=TranslationPermission.OPEN,
)
- translation_focus = ForeignKey(
- dbName="translation_focus",
- foreignKey="ProductSeries",
- notNull=False,
- default=None,
+ translation_focus_id = Int(
+ name="translation_focus", allow_none=True, default=None
)
+ translation_focus = Reference(translation_focus_id, "ProductSeries.id")
bugtracker_id = Int(name="bugtracker", allow_none=True, default=None)
bugtracker = Reference(bugtracker_id, "BugTracker.id")
official_answers = BoolCol(
@@ -675,12 +672,10 @@ class Product(
# While the interface defines this field as required, we need to
# allow it to be NULL so we can create new product records before
# the corresponding series records.
- development_focus = ForeignKey(
- foreignKey="ProductSeries",
- dbName="development_focus",
- notNull=False,
- default=None,
+ development_focus_id = Int(
+ name="development_focus", allow_none=True, default=None
)
+ development_focus = Reference(development_focus_id, "ProductSeries.id")
bug_reporting_guidelines = StringCol(default=None)
bug_reported_acknowledgement = StringCol(default=None)
enable_bugfiling_duplicate_search = BoolCol(notNull=True, default=True)
@@ -1020,8 +1015,8 @@ class Product(
"""Customize `search_params` for this product.."""
search_params.setProduct(self)
- _series = SQLMultipleJoin(
- "ProductSeries", joinColumn="product", orderBy="name"
+ _series = ReferenceSet(
+ "id", "ProductSeries.product_id", order_by="ProductSeries.name"
)
@cachedproperty
@@ -1437,16 +1432,17 @@ class Product(
def getSeries(self, name):
"""See `IProduct`."""
- return ProductSeries.selectOneBy(product=self, name=name)
+ return (
+ IStore(ProductSeries)
+ .find(ProductSeries, product=self, name=name)
+ .one()
+ )
def newSeries(
self, owner, name, summary, branch=None, releasefileglob=None
):
- # XXX: jamesh 2008-04-11
- # Set the ID of the new ProductSeries to avoid flush order
- # loops in ProductSet.createProduct()
series = ProductSeries(
- productID=self.id,
+ product=self,
owner=owner,
name=name,
summary=summary,
@@ -1457,6 +1453,7 @@ class Product(
# The user is a product driver, and should be the driver of this
# series to make them the release manager.
series.driver = owner
+ Store.of(series).flush()
return series
def getRelease(self, version):
@@ -1675,14 +1672,14 @@ def get_precached_products(
if need_series:
series_caches = {}
for series in IStore(ProductSeries).find(
- ProductSeries, ProductSeries.productID.is_in(product_ids)
+ ProductSeries, ProductSeries.product_id.is_in(product_ids)
):
series_cache = get_property_cache(series)
if need_releases and not hasattr(series_cache, "_cached_releases"):
series_cache._cached_releases = []
series_caches[series.id] = series_cache
- cache = caches[series.productID]
+ cache = caches[series.product_id]
cache.series.append(series)
if need_releases:
release_caches = {}
@@ -1721,7 +1718,7 @@ def get_precached_products(
ProjectGroup, products_by_id.values(), ["projectgroupID"]
)
bulk.load_related(
- ProductSeries, products_by_id.values(), ["development_focusID"]
+ ProductSeries, products_by_id.values(), ["development_focus_id"]
)
if role_names is not None:
person_ids = set()
@@ -1760,11 +1757,11 @@ def get_milestones_and_releases(products):
store = IStore(Product)
product_ids = [product.id for product in products]
result = store.find(
- (Milestone, ProductRelease, ProductSeries.productID),
+ (Milestone, ProductRelease, ProductSeries.product_id),
And(
ProductRelease.milestone == Milestone.id,
Milestone.productseries == ProductSeries.id,
- ProductSeries.productID.is_in(product_ids),
+ ProductSeries.product_id.is_in(product_ids),
),
)
return result.order_by(
@@ -1787,8 +1784,8 @@ def get_distro_sourcepackages(products):
]
product_ids = [product.id for product in products]
result = store.using(*origin).find(
- (SourcePackageName, Distribution, ProductSeries.productID),
- ProductSeries.productID.is_in(product_ids),
+ (SourcePackageName, Distribution, ProductSeries.product_id),
+ ProductSeries.product_id.is_in(product_ids),
)
result = result.order_by(SourcePackageName.name, Distribution.name)
result.config(distinct=True)
@@ -2216,7 +2213,7 @@ class ProductSet:
.find(
(Product, Person),
Product.active == True,
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
POTemplate.productseries_id == ProductSeries.id,
Product.translations_usage == ServiceUsage.LAUNCHPAD,
Person.id == Product._ownerID,
diff --git a/lib/lp/registry/model/productseries.py b/lib/lp/registry/model/productseries.py
index 9f09770..e231439 100644
--- a/lib/lp/registry/model/productseries.py
+++ b/lib/lp/registry/model/productseries.py
@@ -14,7 +14,15 @@ from operator import itemgetter
from lazr.delegates import delegate_to
from storm.expr import Max, Sum
-from storm.locals import And, Desc, Int, Reference, ReferenceSet
+from storm.locals import (
+ And,
+ DateTime,
+ Desc,
+ Int,
+ Reference,
+ ReferenceSet,
+ Unicode,
+)
from storm.store import Store
from zope.component import getUtility
from zope.interface import implementer
@@ -49,16 +57,10 @@ from lp.registry.model.milestone import HasMilestonesMixin, Milestone
from lp.registry.model.productrelease import ProductRelease
from lp.registry.model.series import SeriesMixin
from lp.services.database.constants import UTC_NOW
-from lp.services.database.datetimecol import UtcDateTimeCol
from lp.services.database.decoratedresultset import DecoratedResultSet
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.propertycache import cachedproperty
from lp.services.webapp.publisher import canonical_url
from lp.services.webapp.sorting import sorted_dotted_numbers
@@ -95,7 +97,7 @@ def landmark_key(landmark):
@delegate_to(ISpecificationTarget, context="product")
@implementer(IBugSummaryDimension, IProductSeries, ISeriesBugTarget)
class ProductSeries(
- SQLBase,
+ StormBase,
SeriesMixin,
BugTargetBase,
HasMilestonesMixin,
@@ -106,28 +108,25 @@ class ProductSeries(
):
"""A series of product releases."""
- _table = "ProductSeries"
+ __storm_table__ = "ProductSeries"
- product = ForeignKey(dbName="product", foreignKey="Product", notNull=True)
+ id = Int(primary=True)
+ product_id = Int(name="product", allow_none=False)
+ product = Reference(product_id, "Product.id")
status = DBEnum(
allow_none=False, enum=SeriesStatus, default=SeriesStatus.DEVELOPMENT
)
- name = StringCol(notNull=True)
- datecreated = UtcDateTimeCol(notNull=True, default=UTC_NOW)
- owner = ForeignKey(
- dbName="owner",
- foreignKey="Person",
- storm_validator=validate_person,
- notNull=True,
+ name = Unicode(allow_none=False)
+ datecreated = DateTime(
+ allow_none=False, default=UTC_NOW, tzinfo=datetime.timezone.utc
)
+ owner_id = Int(name="owner", validator=validate_person, allow_none=False)
+ owner = Reference(owner_id, "Person.id")
- driver = ForeignKey(
- dbName="driver",
- foreignKey="Person",
- storm_validator=validate_person,
- notNull=False,
- default=None,
+ driver_id = Int(
+ name="driver", validator=validate_person, allow_none=True, default=None
)
+ driver = Reference(driver_id, "Person.id")
branch_id = Int(name="branch", default=None)
branch = Reference(branch_id, "Branch.id")
@@ -156,13 +155,24 @@ class ProductSeries(
)
translations_branch = Reference(translations_branch_id, "Branch.id")
# where are the tarballs released from this branch placed?
- releasefileglob = StringCol(default=None)
- releaseverstyle = StringCol(default=None)
+ releasefileglob = Unicode(default=None)
+ releaseverstyle = Unicode(default=None)
packagings = ReferenceSet(
"id", "Packaging.productseries_id", order_by=Desc("Packaging.id")
)
+ def __init__(
+ self, product, name, owner, summary, branch=None, releasefileglob=None
+ ):
+ super().__init__()
+ self.product = product
+ self.name = name
+ self.owner = owner
+ self.summary = summary
+ self.branch = branch
+ self.releasefileglob = releasefileglob
+
@property
def pillar(self):
"""See `IBugTarget`."""
@@ -623,13 +633,13 @@ class ProductSeries(
If the series isn't found, the product task is better than others.
"""
- seriesID = self.id
- productID = self.productID
+ series_id = self.id
+ product_id = self.product_id
def weight_function(bugtask):
- if bugtask.productseries_id == seriesID:
+ if bugtask.productseries_id == series_id:
return OrderedBugTask(1, bugtask.id, bugtask)
- elif bugtask.product_id == productID:
+ elif bugtask.product_id == product_id:
return OrderedBugTask(2, bugtask.id, bugtask)
else:
return OrderedBugTask(3, bugtask.id, bugtask)
@@ -670,10 +680,10 @@ class ProductSeriesSet:
def get(self, series_id, default=None):
"""See IProductSeriesSet."""
- try:
- return ProductSeries.get(series_id)
- except SQLObjectNotFound:
+ series = IStore(ProductSeries).get(ProductSeries, series_id)
+ if series is None:
return default
+ return series
def findByTranslationsImportBranch(
self, branch, force_translations_upload=False
diff --git a/lib/lp/registry/model/projectgroup.py b/lib/lp/registry/model/projectgroup.py
index dfc4609..47be66b 100644
--- a/lib/lp/registry/model/projectgroup.py
+++ b/lib/lp/registry/model/projectgroup.py
@@ -65,7 +65,6 @@ from lp.services.database.enumcol import DBEnum
from lp.services.database.interfaces import IStore
from lp.services.database.sqlbase import SQLBase, sqlvalues
from lp.services.database.sqlobject import (
- AND,
BoolCol,
ForeignKey,
SQLObjectNotFound,
@@ -221,7 +220,7 @@ class ProjectGroup(
store = Store.of(self)
origin = [
Product,
- Join(ProductSeries, Product.id == ProductSeries.productID),
+ Join(ProductSeries, Product.id == ProductSeries.product_id),
Join(POTemplate, ProductSeries.id == POTemplate.productseries_id),
]
return (
@@ -533,13 +532,16 @@ class ProjectGroup(
def getSeries(self, series_name):
"""See `IProjectGroup.`"""
- has_series = ProductSeries.selectFirst(
- AND(
- ProductSeries.q.productID == Product.q.id,
- ProductSeries.q.name == series_name,
- Product.q.projectgroupID == self.id,
- ),
- orderBy="id",
+ has_series = (
+ IStore(ProductSeries)
+ .find(
+ ProductSeries,
+ ProductSeries.product_id == Product.id,
+ ProductSeries.name == series_name,
+ Product.projectgroup == self,
+ )
+ .order_by(ProductSeries.id)
+ .first()
)
if has_series is None:
diff --git a/lib/lp/registry/model/series.py b/lib/lp/registry/model/series.py
index c65dff3..0de9426 100644
--- a/lib/lp/registry/model/series.py
+++ b/lib/lp/registry/model/series.py
@@ -10,11 +10,11 @@ __all__ = [
from operator import attrgetter
+from storm.locals import Unicode
from zope.interface import implementer
from lp.registry.interfaces.series import ISeriesMixin, SeriesStatus
from lp.registry.model.hasdrivers import HasDriversMixin
-from lp.services.database.sqlobject import StringCol
ACTIVE_STATUSES = [
SeriesStatus.DEVELOPMENT,
@@ -28,7 +28,7 @@ ACTIVE_STATUSES = [
class SeriesMixin(HasDriversMixin):
"""See `ISeriesMixin`."""
- summary = StringCol(notNull=True)
+ summary = Unicode(allow_none=False)
@property
def active(self):
diff --git a/lib/lp/registry/scripts/productreleasefinder/finder.py b/lib/lp/registry/scripts/productreleasefinder/finder.py
index 2271655..802c80e 100644
--- a/lib/lp/registry/scripts/productreleasefinder/finder.py
+++ b/lib/lp/registry/scripts/productreleasefinder/finder.py
@@ -119,7 +119,7 @@ class ProductReleaseFinder:
ProductSeries.name,
ProductSeries.releasefileglob,
),
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
Product.active == True,
ProductSeries.status != SeriesStatus.OBSOLETE,
ProductSeries.releasefileglob != None,
@@ -170,7 +170,7 @@ class ProductReleaseFinder:
found_names = IStore(Product).find(
LibraryFileAlias.filename,
Product.name == product_name,
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
Milestone.productseries_id == ProductSeries.id,
ProductRelease.milestone_id == Milestone.id,
ProductReleaseFile.productrelease_id == ProductRelease.id,
diff --git a/lib/lp/registry/tests/test_product.py b/lib/lp/registry/tests/test_product.py
index d356ed1..895ee15 100644
--- a/lib/lp/registry/tests/test_product.py
+++ b/lib/lp/registry/tests/test_product.py
@@ -997,7 +997,7 @@ class TestProduct(TestCaseWithFactory):
"datecreated",
"description",
"development_focus",
- "development_focusID",
+ "development_focus_id",
"direct_answer_contacts",
"distrosourcepackages",
"downloadurl",
diff --git a/lib/lp/registry/tests/test_productseries.py b/lib/lp/registry/tests/test_productseries.py
index e222af3..1188c19 100644
--- a/lib/lp/registry/tests/test_productseries.py
+++ b/lib/lp/registry/tests/test_productseries.py
@@ -672,7 +672,7 @@ class ProductSeriesSecurityAdaperTestCase(TestCaseWithFactory):
"name",
"parent_subscription_target",
"product",
- "productID",
+ "product_id",
"series",
},
"launchpad.View": {
diff --git a/lib/lp/registry/vocabularies.py b/lib/lp/registry/vocabularies.py
index 566e9f7..1c1c5f4 100644
--- a/lib/lp/registry/vocabularies.py
+++ b/lib/lp/registry/vocabularies.py
@@ -1213,7 +1213,7 @@ class ProductReleaseVocabulary(StormVocabularyBase):
_clauses = [
ProductRelease.milestone_id == Milestone.id,
Milestone.productseries_id == ProductSeries.id,
- ProductSeries.productID == Product.id,
+ ProductSeries.product_id == Product.id,
]
def toTerm(self, obj):
@@ -1249,7 +1249,7 @@ class ProductReleaseVocabulary(StormVocabularyBase):
ProductRelease,
ProductRelease.milestone_id == Milestone.id,
Milestone.productseries_id == ProductSeries.id,
- ProductSeries.productID == Product.id,
+ ProductSeries.product_id == Product.id,
Product.name == productname,
ProductSeries.name == productseriesname,
)
@@ -1272,7 +1272,7 @@ class ProductReleaseVocabulary(StormVocabularyBase):
self._table,
ProductRelease.milestone_id == Milestone.id,
Milestone.productseries_id == ProductSeries.id,
- ProductSeries.productID == Product.id,
+ ProductSeries.product_id == Product.id,
Or(
Product.name.contains_string(query),
ProductSeries.name.contains_string(query),
@@ -1283,14 +1283,14 @@ class ProductReleaseVocabulary(StormVocabularyBase):
@implementer(IHugeVocabulary)
-class ProductSeriesVocabulary(SQLObjectVocabularyBase):
+class ProductSeriesVocabulary(StormVocabularyBase):
"""All `IProductSeries` objects vocabulary."""
displayname = "Select a Release Series"
step_title = "Search"
_table = ProductSeries
_order_by = [Product.name, ProductSeries.name]
- _clauseTables = ["Product"]
+ _clauses = [ProductSeries.product == Product.id]
def toTerm(self, obj):
"""See `IVocabulary`."""
@@ -1334,17 +1334,17 @@ class ProductSeriesVocabulary(SQLObjectVocabularyBase):
if "/" in query:
product_query, series_query = query.split("/", 1)
substring_search = And(
- CONTAINSSTRING(Product.name, product_query),
- CONTAINSSTRING(ProductSeries.name, series_query),
+ Product.name.contains_string(product_query),
+ ProductSeries.name.contains_string(series_query),
)
else:
substring_search = Or(
- CONTAINSSTRING(Product.name, query),
- CONTAINSSTRING(ProductSeries.name, query),
+ Product.name.contains_string(query),
+ ProductSeries.name.contains_string(query),
)
result = IStore(self._table).find(
self._table,
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
substring_search,
privacy_filter,
)
@@ -1376,11 +1376,11 @@ class FilteredDistroSeriesVocabulary(SQLObjectVocabularyBase):
yield self.toTerm(series)
-class FilteredProductSeriesVocabulary(SQLObjectVocabularyBase):
+class FilteredProductSeriesVocabulary(StormVocabularyBase):
"""Describes ProductSeries of a particular product."""
_table = ProductSeries
- _orderBy = ["product", "name"]
+ _order_by = ["product", "name"]
def toTerm(self, obj):
"""See `IVocabulary`."""
diff --git a/lib/lp/translations/browser/potemplate.py b/lib/lp/translations/browser/potemplate.py
index 12a684f..78d8a83 100644
--- a/lib/lp/translations/browser/potemplate.py
+++ b/lib/lp/translations/browser/potemplate.py
@@ -1036,7 +1036,7 @@ class BaseSeriesTemplatesView(LaunchpadView):
.joinOuter(
Product,
And(
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
Or(
Product.translations_usage == ServiceUsage.LAUNCHPAD,
Product.translations_usage == ServiceUsage.EXTERNAL,
diff --git a/lib/lp/translations/doc/potemplate.rst b/lib/lp/translations/doc/potemplate.rst
index 25b03a2..d9e4e26 100644
--- a/lib/lp/translations/doc/potemplate.rst
+++ b/lib/lp/translations/doc/potemplate.rst
@@ -90,7 +90,8 @@ This method gives us the IPOTemplate that belongs to this subset and its
name is the given one.
>>> from lp.registry.model.productseries import ProductSeries
- >>> productseries = ProductSeries.get(3)
+ >>> from lp.services.database.interfaces import IStore
+ >>> productseries = IStore(ProductSeries).get(ProductSeries, 3)
>>> potemplatesubset = potemplate_set.getSubset(
... productseries=productseries
... )
@@ -137,7 +138,7 @@ To do this test, first we check the evolution product, it has two
potemplates in the same path and thus, this method should not get any
value.
- >>> productseries = ProductSeries.get(3)
+ >>> productseries = IStore(ProductSeries).get(ProductSeries, 3)
>>> potemplatesubset = potemplate_set.getSubset(
... productseries=productseries
... )
@@ -153,7 +154,7 @@ value.
Now, we move to the NetApplet product, we should detect it.
- >>> productseries = ProductSeries.get(5)
+ >>> productseries = IStore(ProductSeries).get(ProductSeries, 5)
>>> potemplatesubset = potemplate_set.getSubset(
... productseries=productseries
... )
@@ -181,7 +182,6 @@ POTemplate
POTemplate is an object with all strings that must be translated for a
concrete context.
- >>> from lp.services.database.interfaces import IStore
>>> from lp.testing import verifyObject
>>> from lp.translations.interfaces.potemplate import IPOTemplate
>>> from lp.translations.model.potemplate import POTemplate
diff --git a/lib/lp/translations/doc/translationimportqueue.rst b/lib/lp/translations/doc/translationimportqueue.rst
index edf81ad..e8f0793 100644
--- a/lib/lp/translations/doc/translationimportqueue.rst
+++ b/lib/lp/translations/doc/translationimportqueue.rst
@@ -82,7 +82,7 @@ Login as a user without privileges.
First, we are going to try to do the guess against the Evolution product. That
means that we are going to use the ProductSeries.id = 3
- >>> evolution_productseries = ProductSeries.get(3)
+ >>> evolution_productseries = IStore(ProductSeries).get(ProductSeries, 3)
Attach the file to the product series, without associating it with any
potemplate.
@@ -1022,7 +1022,7 @@ was added to the queue.
We need to attach a new entry to play with:
- >>> productseries = ProductSeries.get(1)
+ >>> productseries = IStore(ProductSeries).get(ProductSeries, 1)
>>> entry = translationimportqueue.addOrUpdateEntry(
... "foo/bar.po",
... b"foo content",
diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py
index 58d73cb..22fa91a 100644
--- a/lib/lp/translations/model/potemplate.py
+++ b/lib/lp/translations/model/potemplate.py
@@ -1531,7 +1531,7 @@ class POTemplateSet:
from lp.registry.model.productseries import ProductSeries
pses = load_related(ProductSeries, templates, ["productseries_id"])
- load_related(Product, pses, ["productID"])
+ load_related(Product, pses, ["product_id"])
load_related(SourcePackageName, templates, ["sourcepackagename_id"])
def wipeSuggestivePOTemplatesCache(self):
@@ -1694,7 +1694,7 @@ class POTemplateSharingSubset:
DistroSeries.distributionID == Location.distribution_id,
),
LeftJoin(
- ProductSeries, ProductSeries.productID == Location.product_id
+ ProductSeries, ProductSeries.product_id == Location.product_id
),
Join(
POTemplate,
diff --git a/lib/lp/translations/model/translationimportqueue.py b/lib/lp/translations/model/translationimportqueue.py
index 3565e27..af10e15 100644
--- a/lib/lp/translations/model/translationimportqueue.py
+++ b/lib/lp/translations/model/translationimportqueue.py
@@ -924,7 +924,7 @@ def list_product_request_targets(user, status_condition):
products = IStore(Product).find(
Product,
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
Product.active == True,
ProductSeries.id.is_in(
Select(
diff --git a/lib/lp/translations/model/translationsperson.py b/lib/lp/translations/model/translationsperson.py
index 96529b1..b8e0cc4 100644
--- a/lib/lp/translations/model/translationsperson.py
+++ b/lib/lp/translations/model/translationsperson.py
@@ -336,7 +336,7 @@ class TranslationsPerson:
Join(
Product,
And(
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
Product.translations_usage
== ServiceUsage.LAUNCHPAD,
Product.active == True,
@@ -409,7 +409,7 @@ class TranslationsPerson:
ProductJoin = LeftJoin(
Product,
And(
- Product.id == ProductSeries.productID,
+ Product.id == ProductSeries.product_id,
Product.translations_usage == ServiceUsage.LAUNCHPAD,
Product.active == True,
),
diff --git a/lib/lp/translations/scripts/migrate_current_flag.py b/lib/lp/translations/scripts/migrate_current_flag.py
index ced0c6a..8a6f430 100644
--- a/lib/lp/translations/scripts/migrate_current_flag.py
+++ b/lib/lp/translations/scripts/migrate_current_flag.py
@@ -134,7 +134,7 @@ class MigrateCurrentFlagProcess:
self.store.find(
Product,
POTemplate.productseries_id == ProductSeries.id,
- ProductSeries.productID == Product.id,
+ ProductSeries.product_id == Product.id,
)
.group_by(Product)
.having(Count(POTemplate.id) > 0)
@@ -152,7 +152,7 @@ class MigrateCurrentFlagProcess:
),
TranslationTemplateItem.potemplate_id == POTemplate.id,
POTemplate.productseries_id == ProductSeries.id,
- ProductSeries.productID == product.id,
+ ProductSeries.product_id == product.id,
).config(distinct=True)
def run(self):
diff --git a/lib/lp/translations/scripts/scrub_pofiletranslator.py b/lib/lp/translations/scripts/scrub_pofiletranslator.py
index 5536710..99048e0 100644
--- a/lib/lp/translations/scripts/scrub_pofiletranslator.py
+++ b/lib/lp/translations/scripts/scrub_pofiletranslator.py
@@ -256,7 +256,7 @@ def preload_work_items(work_items):
productseries = load_related(
ProductSeries, templates, ["productseries_id"]
)
- load_related(Product, productseries, ["productID"])
+ load_related(Product, productseries, ["product_id"])
return {pofile.id: pofile for pofile in pofiles}