launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #29325
[Merge] ~lgp171188/launchpad:optimize-distribution-has-published-sources-queries into launchpad:master
Guruprasad has proposed merging ~lgp171188/launchpad:optimize-distribution-has-published-sources-queries into launchpad:master.
Commit message:
Optimize the queries issued by IDistribution.has_published_sources
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~lgp171188/launchpad/+git/launchpad/+merge/431724
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~lgp171188/launchpad:optimize-distribution-has-published-sources-queries into launchpad:master.
diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
index 354353b..378ec86 100644
--- a/lib/lp/registry/model/distribution.py
+++ b/lib/lp/registry/model/distribution.py
@@ -196,6 +196,7 @@ from lp.soyuz.model.publishing import (
SourcePackagePublishingHistory,
get_current_source_releases,
)
+from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
from lp.translations.enums import TranslationPermission
from lp.translations.model.hastranslationimports import (
HasTranslationImportsMixin,
@@ -2144,12 +2145,25 @@ class Distribution(
return weight_function
- @property
+ @cachedproperty
def has_published_sources(self):
- for archive in self.all_distro_archives:
- if not archive.getPublishedSources().order_by().is_empty():
- return True
- return False
+ if not self.all_distro_archives:
+ return False
+
+ store = Store.of(self)
+ clauses = [
+ SourcePackagePublishingHistory.archiveID.is_in(
+ archive.id for archive in self.all_distro_archives
+ ),
+ SourcePackagePublishingHistory.sourcepackagenameID
+ == SourcePackageName.id,
+ SourcePackagePublishingHistory.sourcepackagereleaseID
+ == SourcePackageRelease.id,
+ ]
+
+ if store.find(SourcePackagePublishingHistory, *clauses).is_empty():
+ return False
+ return True
def newOCIProject(self, registrant, name, description=None):
"""Create an `IOCIProject` for this distro."""
diff --git a/lib/lp/registry/tests/test_distribution.py b/lib/lp/registry/tests/test_distribution.py
index b50fa90..7f2b6cf 100644
--- a/lib/lp/registry/tests/test_distribution.py
+++ b/lib/lp/registry/tests/test_distribution.py
@@ -74,11 +74,11 @@ from lp.registry.interfaces.series import SeriesStatus
from lp.registry.model.distribution import Distribution
from lp.registry.tests.test_distroseries import CurrentSourceReleasesMixin
from lp.services.librarianserver.testing.fake import FakeLibrarian
-from lp.services.propertycache import get_property_cache
+from lp.services.propertycache import clear_property_cache, get_property_cache
from lp.services.webapp import canonical_url
from lp.services.webapp.interfaces import OAuthPermission
from lp.services.worlddata.interfaces.country import ICountrySet
-from lp.soyuz.enums import PackagePublishingStatus
+from lp.soyuz.enums import ArchivePurpose, PackagePublishingStatus
from lp.soyuz.interfaces.distributionsourcepackagerelease import (
IDistributionSourcePackageRelease,
)
@@ -99,7 +99,7 @@ from lp.testing.layers import (
LaunchpadFunctionalLayer,
ZopelessDatabaseLayer,
)
-from lp.testing.matchers import Provides
+from lp.testing.matchers import HasQueryCount, Provides
from lp.testing.pages import webservice_for_person
from lp.testing.views import create_initialized_view
from lp.translations.enums import TranslationPermission
@@ -2709,3 +2709,33 @@ class TestDistributionVulnerabilitiesWebService(TestCaseWithFactory):
}
),
)
+
+
+class TestDistributionPublishedSources(TestCaseWithFactory):
+
+ layer = DatabaseFunctionalLayer
+
+ def test_has_published_sources_no_sources(self):
+ distribution = self.factory.makeDistribution()
+ self.assertFalse(distribution.has_published_sources)
+
+ def test_has_published_sources(self):
+ ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
+ self.assertTrue(ubuntu.all_distro_archives.count() > 0)
+ self.assertTrue(ubuntu.has_published_sources)
+
+ def test_has_published_sources_query_count(self):
+ distribution = self.factory.makeDistribution()
+ self.assertEqual(1, distribution.all_distro_archives.count())
+ with StormStatementRecorder() as recorder1:
+ distribution.has_published_sources
+ clear_property_cache(distribution)
+ self.factory.makeArchive(
+ distribution=distribution,
+ purpose=ArchivePurpose.PARTNER,
+ )
+ self.assertEqual(2, distribution.all_distro_archives.count())
+ with StormStatementRecorder() as recorder2:
+ distribution.has_published_sources
+
+ self.assertThat(recorder2, HasQueryCount.byEquality(recorder1))
Follow ups