Performance improvements for pull request list page (#29900)
This PR will avoid load pullrequest.Issue twice in pull request list page. It will reduce x times database queries for those WIP pull requests. Partially fix #29585 --------- Co-authored-by: Giteabot <teabot@gitea.io> (cherry picked from commit 62f8174aa2fae1481c7e17a6afcb731a5b178cd0) Conflicts: models/activities/notification_list.go moved to models/activities/notification.go
This commit is contained in:
parent
0f4614004e
commit
d92c2048b3
14 changed files with 86 additions and 50 deletions
|
@ -20,6 +20,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
@ -841,3 +842,31 @@ func UpdateNotificationStatuses(ctx context.Context, user *user_model.User, curr
|
|||
Update(n)
|
||||
return err
|
||||
}
|
||||
|
||||
// LoadIssuePullRequests loads all issues' pull requests if possible
|
||||
func (nl NotificationList) LoadIssuePullRequests(ctx context.Context) error {
|
||||
issues := make(map[int64]*issues_model.Issue, len(nl))
|
||||
for _, notification := range nl {
|
||||
if notification.Issue != nil && notification.Issue.IsPull && notification.Issue.PullRequest == nil {
|
||||
issues[notification.Issue.ID] = notification.Issue
|
||||
}
|
||||
}
|
||||
|
||||
if len(issues) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
pulls, err := issues_model.GetPullRequestByIssueIDs(ctx, util.KeysOfMap(issues))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pull := range pulls {
|
||||
if issue := issues[pull.IssueID]; issue != nil {
|
||||
issue.PullRequest = pull
|
||||
issue.PullRequest.Issue = issue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -194,20 +194,6 @@ func (issue *Issue) IsTimetrackerEnabled(ctx context.Context) bool {
|
|||
return issue.Repo.IsTimetrackerEnabled(ctx)
|
||||
}
|
||||
|
||||
// GetPullRequest returns the issue pull request
|
||||
func (issue *Issue) GetPullRequest(ctx context.Context) (pr *PullRequest, err error) {
|
||||
if !issue.IsPull {
|
||||
return nil, fmt.Errorf("Issue is not a pull request")
|
||||
}
|
||||
|
||||
pr, err = GetPullRequestByIssueID(ctx, issue.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pr.Issue = issue
|
||||
return pr, err
|
||||
}
|
||||
|
||||
// LoadPoster loads poster
|
||||
func (issue *Issue) LoadPoster(ctx context.Context) (err error) {
|
||||
if issue.Poster == nil && issue.PosterID != 0 {
|
||||
|
|
|
@ -370,6 +370,9 @@ func (issues IssueList) LoadPullRequests(ctx context.Context) error {
|
|||
|
||||
for _, issue := range issues {
|
||||
issue.PullRequest = pullRequestMaps[issue.ID]
|
||||
if issue.PullRequest != nil {
|
||||
issue.PullRequest.Issue = issue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -220,3 +220,12 @@ func HasMergedPullRequestInRepo(ctx context.Context, repoID, posterID int64) (bo
|
|||
Limit(1).
|
||||
Get(new(Issue))
|
||||
}
|
||||
|
||||
// GetPullRequestByIssueIDs returns all pull requests by issue ids
|
||||
func GetPullRequestByIssueIDs(ctx context.Context, issueIDs []int64) (PullRequestList, error) {
|
||||
prs := make([]*PullRequest, 0, len(issueIDs))
|
||||
return prs, db.GetEngine(ctx).
|
||||
Where("issue_id > 0").
|
||||
In("issue_id", issueIDs).
|
||||
Find(&prs)
|
||||
}
|
||||
|
|
|
@ -239,11 +239,11 @@ type CreateReviewOptions struct {
|
|||
|
||||
// IsOfficialReviewer check if at least one of the provided reviewers can make official reviews in issue (counts towards required approvals)
|
||||
func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewer *user_model.User) (bool, error) {
|
||||
pr, err := GetPullRequestByIssueID(ctx, issue.ID)
|
||||
if err != nil {
|
||||
if err := issue.LoadPullRequest(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
pr := issue.PullRequest
|
||||
rule, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -271,11 +271,10 @@ func IsOfficialReviewer(ctx context.Context, issue *Issue, reviewer *user_model.
|
|||
|
||||
// IsOfficialReviewerTeam check if reviewer in this team can make official reviews in issue (counts towards required approvals)
|
||||
func IsOfficialReviewerTeam(ctx context.Context, issue *Issue, team *organization.Team) (bool, error) {
|
||||
pr, err := GetPullRequestByIssueID(ctx, issue.ID)
|
||||
if err != nil {
|
||||
if err := issue.LoadPullRequest(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch)
|
||||
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, issue.PullRequest.BaseRepoID, issue.PullRequest.BaseBranch)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue