launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #18494
[Merge] lp:~cjwatson/launchpad/testfix-git-target-inline-default-repo into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/testfix-git-target-inline-default-repo into lp:launchpad.
Commit message:
Preload default Git repositories for projects so that ProductSet:+review-licenses can have a constant query count again.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/testfix-git-target-inline-default-repo/+merge/258528
Preload default Git repositories for projects so that ProductSet:+review-licenses can have a constant query count again.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/testfix-git-target-inline-default-repo into lp:launchpad.
=== modified file 'lib/lp/code/interfaces/gitrepository.py'
--- lib/lp/code/interfaces/gitrepository.py 2015-05-07 15:03:27 +0000
+++ lib/lp/code/interfaces/gitrepository.py 2015-05-07 16:52:35 +0000
@@ -724,6 +724,13 @@
This only exists to keep lazr.restful happy.
"""
+ def preloadDefaultRepositoriesForProjects(projects):
+ """Get preloaded default repositories for a list of projects.
+
+ :return: A dict mapping project IDs to their default repositories.
+ Projects that do not have default repositories are omitted.
+ """
+
class IGitRepositoryDelta(Interface):
"""The quantitative changes made to a Git repository that was edited or
=== modified file 'lib/lp/code/model/gitrepository.py'
--- lib/lp/code/model/gitrepository.py 2015-05-07 15:03:27 +0000
+++ lib/lp/code/model/gitrepository.py 2015-05-07 16:52:35 +0000
@@ -122,7 +122,10 @@
)
from lp.services.features import getFeatureFlag
from lp.services.mail.notificationrecipientset import NotificationRecipientSet
-from lp.services.propertycache import cachedproperty
+from lp.services.propertycache import (
+ cachedproperty,
+ get_property_cache,
+ )
from lp.services.webapp.authorization import available_with_permission
@@ -283,6 +286,9 @@
if existing is not None:
raise GitDefaultConflict(existing, self.target)
self.target_default = value
+ if IProduct.providedBy(self.target):
+ get_property_cache(self.target)._default_git_repository = (
+ self if value else None)
@property
def display_name(self):
@@ -894,6 +900,14 @@
"""See `IGitRepositorySet`."""
return []
+ @staticmethod
+ def preloadDefaultRepositoriesForProjects(projects):
+ repositories = bulk.load_referencing(
+ GitRepository, projects, ["project_id"],
+ extra_conditions=[GitRepository.target_default == True])
+ return {
+ repository.project_id: repository for repository in repositories}
+
def get_git_repository_privacy_filter(user, repository_class=GitRepository):
public_filter = repository_class.information_type.is_in(
=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py 2015-05-07 11:38:18 +0000
+++ lib/lp/registry/model/product.py 2015-05-07 16:52:35 +0000
@@ -580,9 +580,13 @@
"""See `IPillar`."""
return "Project"
+ @cachedproperty
+ def _default_git_repository(self):
+ return getUtility(IGitRepositorySet).getDefaultRepository(self)
+
@property
def official_codehosting(self):
- repository = getUtility(IGitRepositorySet).getDefaultRepository(self)
+ repository = self._default_git_repository
return (
self.development_focus.branch is not None or
repository is not None)
@@ -617,7 +621,7 @@
@property
def codehosting_usage(self):
- repository = getUtility(IGitRepositorySet).getDefaultRepository(self)
+ repository = self._default_git_repository
if self.development_focus.branch is None and repository is None:
return ServiceUsage.UNKNOWN
elif (repository is not None or
@@ -1582,7 +1586,8 @@
def get_precached_products(products, need_licences=False,
need_projectgroups=False, need_series=False,
need_releases=False, role_names=None,
- need_role_validity=False):
+ need_role_validity=False,
+ need_codehosting_usage=False):
"""Load and cache product information.
:param products: the products for which to pre-cache information
@@ -1592,10 +1597,13 @@
:param need_releases: whether to cache release information
:param role_names: the role names to cache eg bug_supervisor
:param need_role_validity: whether to cache validity information
+ :param need_codehosting_usage: whether to cache codehosting usage
+ information
:return: a list of products
"""
- # Circular import.
+ # Circular imports.
+ from lp.code.interfaces.gitrepository import IGitRepositorySet
from lp.registry.model.projectgroup import ProjectGroup
product_ids = set(obj.id for obj in products)
@@ -1684,6 +1692,13 @@
person_ids.discard(None)
list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(
person_ids, need_validity=need_role_validity))
+ if need_codehosting_usage:
+ repository_set = getUtility(IGitRepositorySet)
+ repository_map = repository_set.preloadDefaultRepositoriesForProjects(
+ products)
+ for product_id in product_ids:
+ caches[product_id]._default_git_repository = repository_map.get(
+ product_id)
return products
@@ -2001,7 +2016,8 @@
return get_precached_products(
products, role_names=['_owner', 'registrant'],
need_role_validity=True, need_licences=True,
- need_series=True, need_releases=True)
+ need_series=True, need_releases=True,
+ need_codehosting_usage=True)
return DecoratedResultSet(result, pre_iter_hook=eager_load)
Follow ups