Colin Watson has proposed merging ~cjwatson/launchpad:stormify-distroseries into launchpad:master.
Commit message: Convert DistroSeries to Storm Requested reviews: Launchpad code reviewers (launchpad-reviewers) For more details, see: https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/450381 -- Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-distroseries into launchpad:master.
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py index 6752c85..d66c62a 100644 --- a/lib/lp/bugs/model/bugtask.py +++ b/lib/lp/bugs/model/bugtask.py @@ -1282,7 +1282,7 @@ class BugTask(StormBase): BugTask, BugTask.bug_id == self.bug_id, BugTask.distroseries_id == DistroSeries.id, - DistroSeries.distributionID.is_in( + DistroSeries.distribution_id.is_in( distro.id for distro in distros if distro ), ) @@ -2131,7 +2131,7 @@ class BugTaskSet: Distribution.id.is_in( ( BugTaskFlat.distribution_id, - DistroSeries.distributionID, + DistroSeries.distribution_id, ) ), ), diff --git a/lib/lp/bugs/model/bugtasksearch.py b/lib/lp/bugs/model/bugtasksearch.py index 9f6e248..8de8c55 100644 --- a/lib/lp/bugs/model/bugtasksearch.py +++ b/lib/lp/bugs/model/bugtasksearch.py @@ -548,7 +548,7 @@ def _build_query(params): # distroseries. We only include these when we need to. if params.distroseries is not None: distroseries_id = params.distroseries.id - parent_distro_id = params.distroseries.distributionID + parent_distro_id = params.distroseries.distribution_id else: distroseries_id = 0 parent_distro_id = 0 diff --git a/lib/lp/charms/model/charmrecipebuild.py b/lib/lp/charms/model/charmrecipebuild.py index 998994e..6024b31 100644 --- a/lib/lp/charms/model/charmrecipebuild.py +++ b/lib/lp/charms/model/charmrecipebuild.py @@ -527,7 +527,7 @@ class CharmRecipeBuildSet(SpecificBuildFarmJobSourceMixin): distroserieses = load_related( DistroSeries, distroarchserieses, ["distroseries_id"] ) - load_related(Distribution, distroserieses, ["distributionID"]) + load_related(Distribution, distroserieses, ["distribution_id"]) recipes = load_related(CharmRecipe, builds, ["recipe_id"]) getUtility(ICharmRecipeSet).preloadDataForRecipes(recipes) build_ids = set(map(attrgetter("id"), builds)) diff --git a/lib/lp/code/model/cibuild.py b/lib/lp/code/model/cibuild.py index d157ccb..8c32605 100644 --- a/lib/lp/code/model/cibuild.py +++ b/lib/lp/code/model/cibuild.py @@ -908,7 +908,7 @@ class CIBuildSet(SpecificBuildFarmJobSourceMixin): distroseries = load_related( DistroSeries, distroarchseries, ["distroseries_id"] ) - load_related(Distribution, distroseries, ["distributionID"]) + load_related(Distribution, distroseries, ["distribution_id"]) def getByBuildFarmJobs(self, build_farm_jobs): """See `ISpecificBuildFarmJobSource`.""" diff --git a/lib/lp/code/model/sourcepackagerecipebuild.py b/lib/lp/code/model/sourcepackagerecipebuild.py index c75ed36..1ec64c9 100644 --- a/lib/lp/code/model/sourcepackagerecipebuild.py +++ b/lib/lp/code/model/sourcepackagerecipebuild.py @@ -330,7 +330,7 @@ class SourcePackageRecipeBuild( archives = load_related(Archive, builds, ["archive_id"]) load_related(Person, archives, ["ownerID"]) distroseries = load_related(DistroSeries, builds, ["distroseries_id"]) - load_related(Distribution, distroseries, ["distributionID"]) + load_related(Distribution, distroseries, ["distribution_id"]) sprs = load_related(SourcePackageRecipe, builds, ["recipe_id"]) SourcePackageRecipe.preLoadDataForSourcePackageRecipes(sprs) diff --git a/lib/lp/code/vocabularies/sourcepackagerecipe.py b/lib/lp/code/vocabularies/sourcepackagerecipe.py index f500190..2c6b8b6 100644 --- a/lib/lp/code/vocabularies/sourcepackagerecipe.py +++ b/lib/lp/code/vocabularies/sourcepackagerecipe.py @@ -17,16 +17,13 @@ from lp.registry.interfaces.distroseries import IDistroSeriesSet from lp.registry.model.distroseries import DistroSeries from lp.services.webapp.interfaces import ILaunchBag from lp.services.webapp.sorting import sorted_dotted_numbers -from lp.services.webapp.vocabulary import ( - IHugeVocabulary, - SQLObjectVocabularyBase, -) +from lp.services.webapp.vocabulary import IHugeVocabulary, StormVocabularyBase from lp.soyuz.interfaces.archive import IArchiveSet from lp.soyuz.vocabularies import make_archive_vocabulary @implementer(IHugeVocabulary) -class BuildableDistroSeries(SQLObjectVocabularyBase): +class BuildableDistroSeries(StormVocabularyBase): _table = DistroSeries def toTerm(self, obj): diff --git a/lib/lp/registry/doc/distroseries.rst b/lib/lp/registry/doc/distroseries.rst index 532db53..0317c68 100644 --- a/lib/lp/registry/doc/distroseries.rst +++ b/lib/lp/registry/doc/distroseries.rst @@ -86,8 +86,9 @@ And IHasTranslationImports: To search the set of IDistroSeriess, use IDistroSeriesSet.search: + >>> from storm.expr import Desc >>> ubuntu_releases = distroseriesset.search( - ... distribution=ubuntu, isreleased=True, orderBy="-datereleased" + ... distribution=ubuntu, isreleased=True, orderBy=Desc("datereleased") ... ) >>> for release in ubuntu_releases: ... print(release.name) diff --git a/lib/lp/registry/doc/sourcepackage.rst b/lib/lp/registry/doc/sourcepackage.rst index ca27efe..6441d5d 100644 --- a/lib/lp/registry/doc/sourcepackage.rst +++ b/lib/lp/registry/doc/sourcepackage.rst @@ -278,8 +278,8 @@ First, let's get some useful objects from the db. >>> pmount = sourcepackagenameset["pmount"] >>> from lp.registry.model.distroseries import DistroSeries - >>> warty = DistroSeries.get(1) - >>> hoary = DistroSeries.get(3) + >>> warty = IStore(DistroSeries).get(DistroSeries, 1) + >>> hoary = IStore(DistroSeries).get(DistroSeries, 3) Now let's make sure that we can see a productseries for a source package. diff --git a/lib/lp/registry/interfaces/distroseries.py b/lib/lp/registry/interfaces/distroseries.py index 1e33102..bcb5a24 100644 --- a/lib/lp/registry/interfaces/distroseries.py +++ b/lib/lp/registry/interfaces/distroseries.py @@ -273,7 +273,7 @@ class IDistroSeriesPublic( description=_("The distribution for which this is a series."), ) ) - distributionID = Attribute("The distribution ID.") + distribution_id = Attribute("The distribution ID.") named_version = Attribute("The combined display name and version.") parent = Attribute("The structural parent of this series - the distro") components = Attribute("The series components.") diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py index 8abb04f..23fdb69 100644 --- a/lib/lp/registry/model/distribution.py +++ b/lib/lp/registry/model/distribution.py @@ -752,12 +752,10 @@ class Distribution( enable_bug_expiration = BoolCol( dbName="enable_bug_expiration", notNull=True, default=False ) - translation_focus = ForeignKey( - dbName="translation_focus", - foreignKey="DistroSeries", - notNull=False, - default=None, + translation_focus_id = Int( + name="translation_focus", allow_none=True, default=None ) + translation_focus = Reference(translation_focus_id, "DistroSeries.id") date_created = UtcDateTimeCol(notNull=False, default=UTC_NOW) language_pack_admin = ForeignKey( dbName="language_pack_admin", @@ -1001,16 +999,16 @@ class Distribution( """See `IDistribution`.""" ParentDistroSeries = ClassAlias(DistroSeries) # XXX rvb 2011-04-08 bug=754750: The clause - # 'DistroSeries.distributionID!=self.id' is only required + # 'DistroSeries.distribution_id!=self.id' is only required # because the previous_series attribute has been (mis-)used # to denote other relations than proper derivation # relationships. We should be rid of this condition once # the bug is fixed. ret = Store.of(self).find( DistroSeries, - ParentDistroSeries.id == DistroSeries.previous_seriesID, - ParentDistroSeries.distributionID == self.id, - DistroSeries.distributionID != self.id, + ParentDistroSeries.id == DistroSeries.previous_series_id, + ParentDistroSeries.distribution_id == self.id, + DistroSeries.distribution_id != self.id, ) return ret.config(distinct=True).order_by( Desc(DistroSeries.date_created) @@ -1067,7 +1065,7 @@ class Distribution( ds_ids = Select( DistroSeries.id, tables=[DistroSeries], - where=DistroSeries.distributionID == self.id, + where=DistroSeries.distribution_id == self.id, ) clauses = [ DistroSeries.id.is_in(ds_ids), @@ -2093,6 +2091,7 @@ class Distribution( # RBC 20100816. del get_property_cache(self).series + IStore(series).flush() return series @property @@ -2461,7 +2460,7 @@ class DistributionSet: SourcePackagePublishingHistory.distroseries_id == DistroSeries.id ], - DistroSeries.distributionID, + DistroSeries.distribution_id, ) result = {} for spr, distro_id in releases: @@ -2478,9 +2477,9 @@ class DistributionSet: IStore(DistroSeries) .find( Distribution, - Distribution.id == DistroSeries.distributionID, + Distribution.id == DistroSeries.distribution_id, DistroSeries.id == DistroSeriesParent.derived_series_id, - DistroSeries.distributionID != ubuntu_id, + DistroSeries.distribution_id != ubuntu_id, ) .config(distinct=True) ) diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py index 2b43af8..22d2895 100644 --- a/lib/lp/registry/model/distroseries.py +++ b/lib/lp/registry/model/distroseries.py @@ -11,6 +11,7 @@ __all__ = [ ] import collections +from datetime import timezone from io import BytesIO from operator import itemgetter from typing import List @@ -18,7 +19,15 @@ from typing import List import apt_pkg from lazr.delegates import delegate_to from storm.expr import SQL, And, Column, Desc, Is, Join, Not, Or, Select, Table -from storm.locals import JSON, Int, Reference, ReferenceSet +from storm.locals import ( + JSON, + Bool, + DateTime, + Int, + Reference, + ReferenceSet, + Unicode, +) from storm.store import Store from zope.component import getUtility from zope.interface import implementer @@ -67,17 +76,11 @@ from lp.registry.model.series import SeriesMixin from lp.registry.model.sourcepackage import SourcePackage from lp.registry.model.sourcepackagename import SourcePackageName from lp.services.database.constants import DEFAULT, 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, sqlvalues -from lp.services.database.sqlobject import ( - BoolCol, - ForeignKey, - IntCol, - StringCol, -) +from lp.services.database.sqlbase import sqlvalues +from lp.services.database.stormbase import StormBase from lp.services.database.stormexpr import WithMaterialized, fti_search from lp.services.librarian.interfaces import ILibraryFileAliasSet from lp.services.librarian.model import LibraryFileAlias @@ -167,7 +170,7 @@ DEFAULT_INDEX_COMPRESSORS = [ ISeriesBugTarget, ) class DistroSeries( - SQLBase, + StormBase, SeriesMixin, BugTargetBase, HasSpecificationsMixin, @@ -178,48 +181,47 @@ class DistroSeries( ): """A particular series of a distribution.""" - _table = "DistroSeries" - _defaultOrder = ["distribution", "version"] - - distribution = ForeignKey( - dbName="distribution", foreignKey="Distribution", notNull=True - ) - name = StringCol() - display_name = StringCol(dbName="displayname", notNull=True) - title = StringCol(notNull=True) - description = StringCol(notNull=True) - version = StringCol(notNull=True) + __storm_table__ = "DistroSeries" + __storm_order__ = ["distribution", "version"] + + id = Int(primary=True) + distribution_id = Int(name="distribution", allow_none=False) + distribution = Reference(distribution_id, "Distribution.id") + name = Unicode() + display_name = Unicode(name="displayname", allow_none=False) + title = Unicode(allow_none=False) + description = Unicode(allow_none=False) + version = Unicode(allow_none=False) status = DBEnum(name="releasestatus", allow_none=False, enum=SeriesStatus) - date_created = UtcDateTimeCol(notNull=False, default=UTC_NOW) - datereleased = UtcDateTimeCol(notNull=False, default=None) - previous_series = ForeignKey( - dbName="parent_series", foreignKey="DistroSeries", notNull=False + date_created = DateTime( + allow_none=True, default=UTC_NOW, tzinfo=timezone.utc ) - registrant = ForeignKey( - dbName="registrant", - foreignKey="Person", - storm_validator=validate_public_person, - notNull=True, + datereleased = DateTime(allow_none=True, default=None, tzinfo=timezone.utc) + previous_series_id = Int(name="parent_series", allow_none=True) + previous_series = Reference(previous_series_id, "DistroSeries.id") + registrant_id = Int( + name="registrant", validator=validate_public_person, allow_none=False ) - driver = ForeignKey( - dbName="driver", - foreignKey="Person", - storm_validator=validate_public_person, - notNull=False, + registrant = Reference(registrant_id, "Person.id") + driver_id = Int( + name="driver", + validator=validate_public_person, + allow_none=True, default=None, ) - changeslist = StringCol(notNull=False, default=None) + driver = Reference(driver_id, "Person.id") + changeslist = Unicode(allow_none=True, default=None) nominatedarchindep_id = Int( name="nominatedarchindep", allow_none=True, default=None ) nominatedarchindep = Reference( nominatedarchindep_id, "DistroArchSeries.id" ) - messagecount = IntCol(notNull=True, default=0) - binarycount = IntCol(notNull=True, default=DEFAULT) - sourcecount = IntCol(notNull=True, default=DEFAULT) - defer_translation_imports = BoolCol(notNull=True, default=True) - hide_all_translations = BoolCol(notNull=True, default=True) + messagecount = Int(allow_none=False, default=0) + binarycount = Int(allow_none=False, default=DEFAULT) + sourcecount = Int(allow_none=False, default=DEFAULT) + defer_translation_imports = Bool(allow_none=False, default=True) + hide_all_translations = Bool(allow_none=False, default=True) language_pack_base_id = Int( name="language_pack_base", allow_none=True, default=None ) @@ -234,7 +236,7 @@ class DistroSeries( language_pack_proposed = Reference( language_pack_proposed_id, "LanguagePack.id" ) - language_pack_full_export_requested = BoolCol(notNull=True, default=False) + language_pack_full_export_requested = Bool(allow_none=False, default=False) publishing_options = JSON("publishing_options") language_packs = ReferenceSet( @@ -249,21 +251,41 @@ class DistroSeries( "Section.id", ) - def __init__(self, *args, **kwargs): - if "publishing_options" not in kwargs: - kwargs["publishing_options"] = { - "backports_not_automatic": False, - "proposed_not_automatic": False, - "include_long_descriptions": True, - "index_compressors": [ - compressor.title - for compressor in DEFAULT_INDEX_COMPRESSORS - ], - "publish_by_hash": False, - "advertise_by_hash": False, - "strict_supported_component_dependencies": True, - } - super().__init__(*args, **kwargs) + def __init__( + self, + distribution, + name, + display_name, + title, + summary, + description, + version, + status, + registrant, + previous_series=None, + ): + super().__init__() + self.distribution = distribution + self.name = name + self.display_name = display_name + self.title = title + self.summary = summary + self.description = description + self.version = version + self.status = status + self.registrant = registrant + self.previous_series = previous_series + self.publishing_options = { + "backports_not_automatic": False, + "proposed_not_automatic": False, + "include_long_descriptions": True, + "index_compressors": [ + compressor.title for compressor in DEFAULT_INDEX_COMPRESSORS + ], + "publish_by_hash": False, + "advertise_by_hash": False, + "strict_supported_component_dependencies": True, + } @property def displayname(self): @@ -593,7 +615,7 @@ class DistroSeries( ) AS spn_info""" % sqlvalues( po_message_weight=self._current_sourcepackage_po_weight, - distroseries=self, + distroseries=self.id, active_status=active_publishing_status, primary=ArchivePurpose.PRIMARY, ) @@ -702,7 +724,7 @@ class DistroSeries( ON SourcePackageName.id = messages.sourcepackagename AND DistroSeries.id = messages.distroseries """ % sqlvalues( - distroseries=self, po_message_weight=po_message_weight + distroseries=self.id, po_message_weight=po_message_weight ) joins = ( """ @@ -732,7 +754,7 @@ class DistroSeries( AND archive.purpose = %(primary)s AND section.name != 'translations' """ % sqlvalues( - distroseries=self, + distroseries=self.id, active_status=active_publishing_status, primary=ArchivePurpose.PRIMARY, ) @@ -1668,13 +1690,13 @@ class DistroSeries( If the series isn't found, the distribution task is better than others. """ - seriesID = self.id - distributionID = self.distributionID + series_id = self.id + distribution_id = self.distribution_id def weight_function(bugtask): - if bugtask.distroseries_id == seriesID: + if bugtask.distroseries_id == series_id: return OrderedBugTask(1, bugtask.id, bugtask) - elif bugtask.distribution_id == distributionID: + elif bugtask.distribution_id == distribution_id: return OrderedBugTask(2, bugtask.id, bugtask) else: return OrderedBugTask(3, bugtask.id, bugtask) @@ -1764,7 +1786,7 @@ class DistroSeries( class DistroSeriesSet: def get(self, distroseriesid): """See `IDistroSeriesSet`.""" - return DistroSeries.get(distroseriesid) + return IStore(DistroSeries).get(DistroSeries, distroseriesid) def translatables(self): """See `IDistroSeriesSet`.""" @@ -1783,7 +1805,11 @@ class DistroSeriesSet: def queryByName(self, distribution, name, follow_aliases=False): """See `IDistroSeriesSet`.""" - series = DistroSeries.selectOneBy(distribution=distribution, name=name) + series = ( + IStore(DistroSeries) + .find(DistroSeries, distribution=distribution, name=name) + .one() + ) if series is not None: return series if follow_aliases: @@ -1795,8 +1821,10 @@ class DistroSeriesSet: def queryByVersion(self, distribution, version): """See `IDistroSeriesSet`.""" - return DistroSeries.selectOneBy( - distribution=distribution, version=version + return ( + IStore(DistroSeries) + .find(DistroSeries, distribution=distribution, version=version) + .one() ) def _parseSuite(self, suite): @@ -1841,23 +1869,21 @@ class DistroSeriesSet: def search(self, distribution=None, isreleased=None, orderBy=None): """See `IDistroSeriesSet`.""" - where_clause = "" + clauses = [] if distribution is not None: - where_clause += "distribution = %s" % sqlvalues(distribution.id) + clauses.append(DistroSeries.distribution == distribution) if isreleased is not None: - if where_clause: - where_clause += " AND " if isreleased: # The query is filtered on released releases. - where_clause += "releasestatus in (%s, %s)" % sqlvalues( - *ACTIVE_RELEASED_STATUSES + clauses.append( + DistroSeries.status.is_in(ACTIVE_RELEASED_STATUSES) ) else: # The query is filtered on unreleased releases. - where_clause += "releasestatus in (%s, %s, %s)" % sqlvalues( - *ACTIVE_UNRELEASED_STATUSES + clauses.append( + DistroSeries.status.is_in(ACTIVE_UNRELEASED_STATUSES) ) + rows = IStore(DistroSeries).find(DistroSeries, *clauses) if orderBy is not None: - return DistroSeries.select(where_clause, orderBy=orderBy) - else: - return DistroSeries.select(where_clause) + rows = rows.order_by(orderBy) + return rows diff --git a/lib/lp/registry/model/distroseriesdifference.py b/lib/lp/registry/model/distroseriesdifference.py index 75719fc..28859ba 100644 --- a/lib/lp/registry/model/distroseriesdifference.py +++ b/lib/lp/registry/model/distroseriesdifference.py @@ -98,7 +98,7 @@ def most_recent_publications(dsds, in_parent, statuses, match_version=False): tables=[Archive, DistroSeries], where=And( DistroSeries.id == series_col, - Archive.distributionID == DistroSeries.distributionID, + Archive.distributionID == DistroSeries.distribution_id, Archive.purpose == ArchivePurpose.PRIMARY, ), ) diff --git a/lib/lp/registry/model/sourcepackage.py b/lib/lp/registry/model/sourcepackage.py index c15b371..cf3bb8e 100644 --- a/lib/lp/registry/model/sourcepackage.py +++ b/lib/lp/registry/model/sourcepackage.py @@ -667,7 +667,7 @@ class SourcePackage( """ % sqlvalues( self.sourcepackagename.id, - self.distroseries, + self.distroseries.id, list(self.distribution.all_distro_archive_ids), ) ] @@ -877,19 +877,19 @@ class SourcePackage( We look for the source package task, followed by the distro source package, then the distroseries task, and lastly the distro task. """ - sourcepackagenameID = self.sourcepackagename.id - seriesID = self.distroseries.id - distributionID = self.distroseries.distributionID + sourcepackagename_id = self.sourcepackagename.id + series_id = self.distroseries.id + distribution_id = self.distroseries.distribution_id def weight_function(bugtask): - if bugtask.sourcepackagename_id == sourcepackagenameID: - if bugtask.distroseries_id == seriesID: + if bugtask.sourcepackagename_id == sourcepackagename_id: + if bugtask.distroseries_id == series_id: return OrderedBugTask(1, bugtask.id, bugtask) - elif bugtask.distribution_id == distributionID: + elif bugtask.distribution_id == distribution_id: return OrderedBugTask(2, bugtask.id, bugtask) - elif bugtask.distroseries_id == seriesID: + elif bugtask.distroseries_id == series_id: return OrderedBugTask(3, bugtask.id, bugtask) - elif bugtask.distribution_id == distributionID: + elif bugtask.distribution_id == distribution_id: return OrderedBugTask(4, bugtask.id, bugtask) # Catch the default case, and where there is a task for the same # sourcepackage on a different distro. diff --git a/lib/lp/registry/scripts/populate_distroseriesdiff.py b/lib/lp/registry/scripts/populate_distroseriesdiff.py index a39d4bf..7847ee6 100644 --- a/lib/lp/registry/scripts/populate_distroseriesdiff.py +++ b/lib/lp/registry/scripts/populate_distroseriesdiff.py @@ -55,7 +55,7 @@ def compose_sql_find_latest_source_package_releases(distroseries): """ parameters = { "active_status": quote(active_publishing_status), - "distroseries": quote(distroseries), + "distroseries": quote(distroseries.id), "main_archive": quote(distroseries.distribution.main_archive), "release_pocket": quote(PackagePublishingPocket.RELEASE), } @@ -166,8 +166,8 @@ def compose_sql_populate_distroseriesdiff( :return: SQL query, as a string. """ parameters = { - "derived_series": quote(derived_series), - "parent_series": quote(parent_series), + "derived_series": quote(derived_series.id), + "parent_series": quote(parent_series.id), "difference_type_expression": compose_sql_difference_type(), "needs_attention": quote(DistroSeriesDifferenceStatus.NEEDS_ATTENTION), "temp_table": quote_identifier(temp_table), diff --git a/lib/lp/registry/vocabularies.py b/lib/lp/registry/vocabularies.py index 955e975..d87766e 100644 --- a/lib/lp/registry/vocabularies.py +++ b/lib/lp/registry/vocabularies.py @@ -147,7 +147,6 @@ from lp.services.database import bulk from lp.services.database.decoratedresultset import DecoratedResultSet from lp.services.database.interfaces import IStore from lp.services.database.sqlbase import sqlvalues -from lp.services.database.sqlobject import AND, CONTAINSSTRING, OR from lp.services.database.stormexpr import ( RegexpMatch, WithMaterialized, @@ -1342,11 +1341,11 @@ class ProductSeriesVocabulary(StormVocabularyBase): return result -class FilteredDistroSeriesVocabulary(SQLObjectVocabularyBase): +class FilteredDistroSeriesVocabulary(StormVocabularyBase): """Describes the series of a particular distribution.""" _table = DistroSeries - _orderBy = "version" + _order_by = "version" def toTerm(self, obj): """See `IVocabulary`.""" @@ -1355,13 +1354,14 @@ class FilteredDistroSeriesVocabulary(SQLObjectVocabularyBase): ) def __iter__(self): - kw = {} - if self._orderBy: - kw["orderBy"] = self._orderBy launchbag = getUtility(ILaunchBag) if launchbag.distribution: distribution = launchbag.distribution - series = self._table.selectBy(distributionID=distribution.id, **kw) + series = IStore(DistroSeries).find( + DistroSeries, distribution=distribution + ) + if self._order_by: + series = series.order_by(self._order_by) for series in sorted(series, key=attrgetter("sortkey")): yield self.toTerm(series) @@ -1620,20 +1620,15 @@ class DistributionVocabulary(NamedSQLObjectVocabulary): return rows -class DistroSeriesVocabulary(NamedSQLObjectVocabulary): +class DistroSeriesVocabulary(NamedStormVocabulary): """All `IDistroSeries` objects vocabulary.""" _table = DistroSeries - _orderBy = ["Distribution.displayname", "-DistroSeries.date_created"] - _clauseTables = ["Distribution"] + _order_by = [Distribution.display_name, Desc(DistroSeries.date_created)] + _clauses = [DistroSeries.distribution == Distribution.id] def __iter__(self): - series = self._table.select( - DistroSeries.q.distributionID == Distribution.q.id, - orderBy=self._orderBy, - clauseTables=self._clauseTables, - ) - for series in sorted(series, key=attrgetter("sortkey")): + for series in sorted(self._entries, key=attrgetter("sortkey")): yield self.toTerm(series) @staticmethod @@ -1672,18 +1667,19 @@ class DistroSeriesVocabulary(NamedSQLObjectVocabulary): if not query: return self.emptySelectResults() - query = six.ensure_text(query).lower() - objs = self._table.select( - AND( - Distribution.q.id == DistroSeries.q.distributionID, - OR( - CONTAINSSTRING(Distribution.q.name, query), - CONTAINSSTRING(DistroSeries.q.name, query), + query = query.lower() + return ( + IStore(DistroSeries) + .find( + DistroSeries, + DistroSeries.distribution == Distribution.id, + Or( + Distribution.name.contains_string(query), + DistroSeries.name.contains_string(query), ), - ), - orderBy=self._orderBy, + ) + .order_by(self._order_by) ) - return objs @implementer(IHugeVocabulary) @@ -1792,10 +1788,10 @@ class DistroSeriesDerivationVocabulary(FilteredVocabularyBase): where.append(search) parent_distributions = list( IStore(DistroSeries).find( - parent.distributionID, + parent.distribution_id, And( - parent.distributionID != self.distribution.id, - child.distributionID == self.distribution.id, + parent.distribution_id != self.distribution.id, + child.distribution_id == self.distribution.id, child.id == DistroSeriesParent.derived_series_id, parent.id == DistroSeriesParent.parent_series_id, ), @@ -1803,7 +1799,7 @@ class DistroSeriesDerivationVocabulary(FilteredVocabularyBase): ) if parent_distributions != []: where.append( - DistroSeries.distributionID.is_in(parent_distributions) + DistroSeries.distribution_id.is_in(parent_distributions) ) return self.find_terms(where) else: diff --git a/lib/lp/scripts/harness.py b/lib/lp/scripts/harness.py index d6dc0d0..b3b23aa 100644 --- a/lib/lp/scripts/harness.py +++ b/lib/lp/scripts/harness.py @@ -74,7 +74,7 @@ def _get_locals(): # Do we really use these? Are they worth carrying around? d = Distribution.get(1) p = Person.get(1) - ds = DistroSeries.get(1) + ds = store.get(DistroSeries, 1) prod = store.get(Product, 1) proj = store.get(ProjectGroup, 1) b2 = store.get(Bug, 2) diff --git a/lib/lp/snappy/model/snapbuild.py b/lib/lp/snappy/model/snapbuild.py index 174d586..afc3275 100644 --- a/lib/lp/snappy/model/snapbuild.py +++ b/lib/lp/snappy/model/snapbuild.py @@ -611,7 +611,7 @@ class SnapBuildSet(SpecificBuildFarmJobSourceMixin): distroseries = load_related( DistroSeries, distroarchseries, ["distroseries_id"] ) - load_related(Distribution, distroseries, ["distributionID"]) + load_related(Distribution, distroseries, ["distribution_id"]) snaps = load_related(Snap, builds, ["snap_id"]) getUtility(ISnapSet).preloadDataForSnaps(snaps) snapbuild_ids = set(map(attrgetter("id"), builds)) diff --git a/lib/lp/snappy/vocabularies.py b/lib/lp/snappy/vocabularies.py index a7625d1..32cfaea 100644 --- a/lib/lp/snappy/vocabularies.py +++ b/lib/lp/snappy/vocabularies.py @@ -118,7 +118,7 @@ class SnappyDistroSeriesVocabulary(StormVocabularyBase): DistroSeries, SnappyDistroSeries.distro_series_id == DistroSeries.id, ), - LeftJoin(Distribution, DistroSeries.distributionID == Distribution.id), + LeftJoin(Distribution, DistroSeries.distribution == Distribution.id), SnappySeries, ] _clauses = [ diff --git a/lib/lp/soyuz/doc/gina-multiple-arch.rst b/lib/lp/soyuz/doc/gina-multiple-arch.rst index 2c9f06b..d36a2fe 100644 --- a/lib/lp/soyuz/doc/gina-multiple-arch.rst +++ b/lib/lp/soyuz/doc/gina-multiple-arch.rst @@ -60,8 +60,10 @@ Create a distribution series and an arch series for dapper: Check it was properly created and create its DistroArchSeriess. >>> from lp.registry.model.distroseries import DistroSeries - >>> dapper = DistroSeries.selectOneBy( - ... name="dapper", distributionID=ubuntu.id + >>> dapper = ( + ... IStore(DistroSeries) + ... .find(DistroSeries, name="dapper", distribution=ubuntu) + ... .one() ... ) >>> processor = getUtility(IProcessorSet).getByName("386") >>> dar = dapper.newArch( diff --git a/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst b/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst index 1ba2b35..0355122 100644 --- a/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst +++ b/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst @@ -643,7 +643,7 @@ Set ubuntutest/breezy to 'experimental' state again to not affect the rest of the test: >>> breezy.status = SeriesStatus.EXPERIMENTAL - >>> breezy.syncUpdate() + >>> IStore(breezy).flush() Regression test for bug 54039. Currently must be here, see bug 54158. diff --git a/lib/lp/soyuz/model/binarypackagebuild.py b/lib/lp/soyuz/model/binarypackagebuild.py index 202265f..ca82a8e 100644 --- a/lib/lp/soyuz/model/binarypackagebuild.py +++ b/lib/lp/soyuz/model/binarypackagebuild.py @@ -944,7 +944,7 @@ class BinaryPackageBuildSet(SpecificBuildFarmJobSourceMixin): archives = load_related(Archive, builds, ["archive_id"]) load_related(Person, archives, ["ownerID"]) distroseries = load_related(DistroSeries, das, ["distroseries_id"]) - load_related(Distribution, distroseries, ["distributionID"]) + load_related(Distribution, distroseries, ["distribution_id"]) def getByBuildFarmJobs(self, build_farm_jobs): """See `ISpecificBuildFarmJobSource`.""" diff --git a/lib/lp/soyuz/model/initializedistroseriesjob.py b/lib/lp/soyuz/model/initializedistroseriesjob.py index 48a30eb..e487713 100644 --- a/lib/lp/soyuz/model/initializedistroseriesjob.py +++ b/lib/lp/soyuz/model/initializedistroseriesjob.py @@ -141,7 +141,7 @@ class InitializeDistroSeriesJob(DistributionJobDerived): parts += ", parent[overlay?/pockets/components]: " parents = [] for i in range(len(self.overlays)): - series = DistroSeries.get(self.parents[i]) + series = IStore(DistroSeries).get(DistroSeries, self.parents[i]) parents.append( "%s[%s/%s/%s]" % ( diff --git a/lib/lp/soyuz/model/packagecloner.py b/lib/lp/soyuz/model/packagecloner.py index 659345d..15029b4 100644 --- a/lib/lp/soyuz/model/packagecloner.py +++ b/lib/lp/soyuz/model/packagecloner.py @@ -229,7 +229,7 @@ class PackageCloner: WHERE mcd.obsoleted = True OR mcd.missing = True """ % sqlvalues( - destination.distroseries, + destination.distroseries.id, destination.archive, UTC_NOW, UTC_NOW, @@ -294,7 +294,7 @@ class PackageCloner: origin.archive, PackagePublishingStatus.PENDING, PackagePublishingStatus.PUBLISHED, - origin.distroseries, + origin.distroseries.id, origin.pocket, ) @@ -337,7 +337,7 @@ class PackageCloner: origin.archive, PackagePublishingStatus.PENDING, PackagePublishingStatus.PUBLISHED, - origin.distroseries, + origin.distroseries.id, origin.pocket, ) @@ -417,7 +417,7 @@ class PackageCloner: destination.archive, PackagePublishingStatus.PENDING, PackagePublishingStatus.PUBLISHED, - destination.distroseries, + destination.distroseries.id, destination.pocket, ) @@ -464,12 +464,12 @@ class PackageCloner: spph.pocket = %s AND spph.archive = %s """ % sqlvalues( - destination.distroseries, + destination.distroseries.id, destination.archive, UTC_NOW, UTC_NOW, destination.pocket, - origin.distroseries, + origin.distroseries.id, PackagePublishingStatus.PENDING, PackagePublishingStatus.PUBLISHED, origin.pocket, diff --git a/lib/lp/soyuz/model/packagecopyjob.py b/lib/lp/soyuz/model/packagecopyjob.py index fa87145..d441a99 100644 --- a/lib/lp/soyuz/model/packagecopyjob.py +++ b/lib/lp/soyuz/model/packagecopyjob.py @@ -878,7 +878,7 @@ class PlainPackageCopyJob(PackageCopyJobDerived): return [ dsd for dsd in candidates - if dsd.parent_series.distributionID == source_distro_id + if dsd.parent_series.distribution_id == source_distro_id ] def reportFailure(self, message): diff --git a/lib/lp/soyuz/scripts/gina/handlers.py b/lib/lp/soyuz/scripts/gina/handlers.py index 8d07ea7..60b047c 100644 --- a/lib/lp/soyuz/scripts/gina/handlers.py +++ b/lib/lp/soyuz/scripts/gina/handlers.py @@ -245,7 +245,11 @@ class ImporterHandler: def _get_distroseries(self, name): """Return the distroseries database object by name.""" - dr = DistroSeries.selectOneBy(name=name, distributionID=self.distro.id) + dr = ( + IStore(DistroSeries) + .find(DistroSeries, name=name, distribution=self.distro) + .one() + ) if not dr: raise DataSetupError("Error finding distroseries %r" % name) return dr diff --git a/lib/lp/soyuz/scripts/initialize_distroseries.py b/lib/lp/soyuz/scripts/initialize_distroseries.py index 8e76922..bcb6f28 100644 --- a/lib/lp/soyuz/scripts/initialize_distroseries.py +++ b/lib/lp/soyuz/scripts/initialize_distroseries.py @@ -473,7 +473,7 @@ class InitializeDistroSeries: GROUP BY processor, architecturetag """ % ( - sqlvalues(self.distroseries, self.distroseries.owner) + sqlvalues(self.distroseries.id, self.distroseries.owner.id) + (das_filter,) ) ) diff --git a/lib/lp/soyuz/vocabularies.py b/lib/lp/soyuz/vocabularies.py index 2ce2ac7..1b640b8 100644 --- a/lib/lp/soyuz/vocabularies.py +++ b/lib/lp/soyuz/vocabularies.py @@ -69,7 +69,7 @@ class FilteredDistroArchSeriesVocabulary(StormVocabularyBase): .find( self._table, DistroSeries.id == DistroArchSeries.distroseries_id, - DistroSeries.distributionID == distribution.id, + DistroSeries.distribution == distribution, ) .order_by(*self._orderBy) ) diff --git a/lib/lp/translations/doc/distroseries-translations-copy.rst b/lib/lp/translations/doc/distroseries-translations-copy.rst index bc3df4f..4aa591c 100644 --- a/lib/lp/translations/doc/distroseries-translations-copy.rst +++ b/lib/lp/translations/doc/distroseries-translations-copy.rst @@ -201,7 +201,8 @@ set. >>> transaction.abort() >>> from lp.registry.model.distroseries import DistroSeries - >>> darty = DistroSeries.get(darty_id) + >>> from lp.services.database.interfaces import IStore + >>> darty = IStore(DistroSeries).get(DistroSeries, darty_id) >>> darty.defer_translation_imports False >>> darty.hide_all_translations @@ -211,7 +212,7 @@ It succeeds, however, when we pass the --force option. The script then sets the defer_translation_imports flag itself before copying. >>> transaction.abort() - >>> darty = DistroSeries.get(darty_id) + >>> darty = IStore(DistroSeries).get(DistroSeries, darty_id) >>> returnvalue, output, error_output = run_script( ... "scripts/copy-distroseries-translations.py", ... ["--distribution=foobuntu", "--series=darty", "--force"], @@ -243,7 +244,7 @@ After completing, the script restores the defer_translation_imports flag to its previous value (off). >>> transaction.abort() - >>> darty = DistroSeries.get(darty_id) + >>> darty = IStore(DistroSeries).get(DistroSeries, darty_id) >>> darty.defer_translation_imports False >>> darty.hide_all_translations @@ -331,7 +332,7 @@ for package2, and template3 is inactive, so they're both skipped. >>> returnvalue 0 >>> transaction.abort() - >>> lumpy = DistroSeries.get(lumpy_id) + >>> lumpy = IStore(DistroSeries).get(DistroSeries, lumpy_id) >>> len(getUtility(IPOTemplateSet).getSubset(distroseries=lumpy)) 0 @@ -354,7 +355,7 @@ for package2, and template3 is inactive, so they're both skipped. >>> returnvalue 0 >>> transaction.abort() - >>> lumpy = DistroSeries.get(lumpy_id) + >>> lumpy = IStore(DistroSeries).get(DistroSeries, lumpy_id) >>> for pot in getUtility(IPOTemplateSet).getSubset(distroseries=lumpy): ... print(pot.name) ... diff --git a/lib/lp/translations/doc/translationimportqueue.rst b/lib/lp/translations/doc/translationimportqueue.rst index 29dabee..aa79840 100644 --- a/lib/lp/translations/doc/translationimportqueue.rst +++ b/lib/lp/translations/doc/translationimportqueue.rst @@ -111,7 +111,7 @@ this IPOFile is located ('po/') Now let's try the same against the evolution sourcepackage that only has an IPOTemplate. - >>> hoary_distroseries = DistroSeries.get(3) + >>> hoary_distroseries = IStore(DistroSeries).get(DistroSeries, 3) >>> evolution_sourcepackagename = IStore(SourcePackageName).get( ... SourcePackageName, 9 ... ) diff --git a/lib/lp/translations/model/distroseries_translations_copy.py b/lib/lp/translations/model/distroseries_translations_copy.py index d66474b..bd7de81 100644 --- a/lib/lp/translations/model/distroseries_translations_copy.py +++ b/lib/lp/translations/model/distroseries_translations_copy.py @@ -123,7 +123,7 @@ def copy_active_translations( # Copy relevant POTemplates from existing series into a holding table, # complete with their original id fields. - where = "distroseries = %s AND iscurrent" % quote(source) + where = "distroseries = %s AND iscurrent" % quote(source.id) if sourcepackagenames is not None: if not sourcepackagenames: where += " AND false" @@ -137,7 +137,7 @@ def copy_active_translations( SELECT sourcepackagename FROM potemplate WHERE distroseries = %s) """ % quote( - target + target.id ) copier.extract("potemplate", [], where) @@ -156,7 +156,7 @@ def copy_active_translations( timezone('UTC'::text, ('now'::text)::timestamp(6) with time zone) """ - % (copier.getHoldingTableName("potemplate"), quote(target)) + % (copier.getHoldingTableName("potemplate"), quote(target.id)) ) # Copy each TranslationTemplateItem whose template we copied, and let diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py index 22fa91a..87e79d5 100644 --- a/lib/lp/translations/model/potemplate.py +++ b/lib/lp/translations/model/potemplate.py @@ -1691,7 +1691,7 @@ class POTemplateSharingSubset: Location, LeftJoin( DistroSeries, - DistroSeries.distributionID == Location.distribution_id, + DistroSeries.distribution_id == Location.distribution_id, ), LeftJoin( ProductSeries, ProductSeries.product_id == Location.product_id diff --git a/lib/lp/translations/model/translationimportqueue.py b/lib/lp/translations/model/translationimportqueue.py index af10e15..f89b2c3 100644 --- a/lib/lp/translations/model/translationimportqueue.py +++ b/lib/lp/translations/model/translationimportqueue.py @@ -964,7 +964,7 @@ def list_distroseries_request_targets(status_condition): distroseries = IStore(DistroSeries).find( DistroSeries, DistroSeries.defer_translation_imports == False, - Distribution.id == DistroSeries.distributionID, + Distribution.id == DistroSeries.distribution_id, DistroSeries.id.is_in( Select( TranslationImportQueueEntry.distroseries_id, diff --git a/lib/lp/translations/model/translationsperson.py b/lib/lp/translations/model/translationsperson.py index 3d80d12..715ba35 100644 --- a/lib/lp/translations/model/translationsperson.py +++ b/lib/lp/translations/model/translationsperson.py @@ -311,10 +311,10 @@ class TranslationsPerson: Join( Distribution, And( - Distribution.id == DistroSeries.distributionID, + Distribution.id == DistroSeries.distribution_id, Distribution.translations_usage == ServiceUsage.LAUNCHPAD, - Distribution.translation_focusID + Distribution.translation_focus_id == DistroSeries.id, ), ), @@ -397,9 +397,9 @@ class TranslationsPerson: # If there's a DistroSeries, it should be the distro's # translation focus. distrojoin_conditions = And( - Distribution.id == DistroSeries.distributionID, + Distribution.id == DistroSeries.distribution_id, Distribution.translations_usage == ServiceUsage.LAUNCHPAD, - Distribution.translation_focusID == DistroSeries.id, + Distribution.translation_focus_id == DistroSeries.id, ) DistroJoin = LeftJoin(Distribution, distrojoin_conditions) diff --git a/lib/lp/translations/scripts/language_pack.py b/lib/lp/translations/scripts/language_pack.py index 2da785d..41c2f19 100644 --- a/lib/lp/translations/scripts/language_pack.py +++ b/lib/lp/translations/scripts/language_pack.py @@ -15,11 +15,13 @@ import tempfile from shutil import copyfileobj import transaction +from storm.expr import Is from storm.store import Store from zope.component import getUtility from lp.registry.interfaces.distribution import IDistributionSet -from lp.services.database.sqlbase import cursor, sqlvalues +from lp.registry.model.sourcepackagename import SourcePackageName +from lp.services.database.interfaces import IStore from lp.services.librarian.interfaces.client import ( ILibrarianClient, UploadFailed, @@ -28,6 +30,7 @@ from lp.services.tarfile_helpers import LaunchpadWriteTarFile from lp.translations.enums import LanguagePackType from lp.translations.interfaces.languagepack import ILanguagePackSet from lp.translations.interfaces.vpoexport import IVPOExportSet +from lp.translations.model.potemplate import POTemplate def iter_sourcepackage_translationdomain_mapping(series): @@ -37,22 +40,12 @@ def iter_sourcepackage_translationdomain_mapping(series): With the output of this method we can know the translationdomains that a sourcepackage has. """ - cur = cursor() - cur.execute( - """ - SELECT SourcePackageName.name, POTemplate.translation_domain - FROM - SourcePackageName - JOIN POTemplate ON - POTemplate.sourcepackagename = SourcePackageName.id AND - POTemplate.distroseries = %s AND - POTemplate.languagepack = TRUE - ORDER BY SourcePackageName.name, POTemplate.translation_domain - """ - % sqlvalues(series) - ) - - yield from cur.fetchall() + yield from IStore(SourcePackageName).find( + (SourcePackageName.name, POTemplate.translation_domain), + POTemplate.sourcepackagename == SourcePackageName.id, + POTemplate.distroseries == series, + Is(POTemplate.languagepack, True), + ).order_by(SourcePackageName.name, POTemplate.translation_domain) def export(distroseries, component, update, force_utf8, logger): diff --git a/lib/lp/translations/scripts/scrub_pofiletranslator.py b/lib/lp/translations/scripts/scrub_pofiletranslator.py index 99048e0..ee45697 100644 --- a/lib/lp/translations/scripts/scrub_pofiletranslator.py +++ b/lib/lp/translations/scripts/scrub_pofiletranslator.py @@ -252,7 +252,7 @@ def preload_work_items(work_items): load_related(Language, pofiles, ["language_id"]) templates = load_related(POTemplate, pofiles, ["potemplate_id"]) distroseries = load_related(DistroSeries, templates, ["distroseries_id"]) - load_related(Distribution, distroseries, ["distributionID"]) + load_related(Distribution, distroseries, ["distribution_id"]) productseries = load_related( ProductSeries, templates, ["productseries_id"] ) diff --git a/lib/lp/translations/tests/test_autoapproval.py b/lib/lp/translations/tests/test_autoapproval.py index 94cfb07..ef4c11f 100644 --- a/lib/lp/translations/tests/test_autoapproval.py +++ b/lib/lp/translations/tests/test_autoapproval.py @@ -1217,7 +1217,7 @@ class TestCleanup(TestCaseWithFactory, GardenerDbUserMixin): self.assertTrue(self._exists(entry_id)) entry.distroseries.status = SeriesStatus.OBSOLETE - entry.distroseries.syncUpdate() + self.store.flush() self.becomeTheGardener() self.queue._cleanUpObsoleteDistroEntries(self.store)
_______________________________________________ Mailing list: https://launchpad.net/~launchpad-reviewers Post to : launchpad-reviewers@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-reviewers More help : https://help.launchpad.net/ListHelp