diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2024-03-21 21:13:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-21 14:13:08 +0100 |
commit | 62f8174aa2fae1481c7e17a6afcb731a5b178cd0 (patch) | |
tree | f94686ea110e943418a25534e0306f45169c9f48 /models | |
parent | 01500957c29f6bfa2396b8457dbb0645edaafa99 (diff) | |
download | gitea-62f8174aa2fae1481c7e17a6afcb731a5b178cd0.tar.gz gitea-62f8174aa2fae1481c7e17a6afcb731a5b178cd0.zip |
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>
Diffstat (limited to 'models')
-rw-r--r-- | models/activities/notification_list.go | 29 | ||||
-rw-r--r-- | models/issues/issue.go | 14 | ||||
-rw-r--r-- | models/issues/issue_list.go | 3 | ||||
-rw-r--r-- | models/issues/pull_list.go | 9 | ||||
-rw-r--r-- | models/issues/review.go | 9 |
5 files changed, 45 insertions, 19 deletions
diff --git a/models/activities/notification_list.go b/models/activities/notification_list.go index 957f9456e7..5858933391 100644 --- a/models/activities/notification_list.go +++ b/models/activities/notification_list.go @@ -14,6 +14,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -470,3 +471,31 @@ func (nl NotificationList) LoadComments(ctx context.Context) ([]int, error) { } return failures, nil } + +// 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 +} diff --git a/models/issues/issue.go b/models/issues/issue.go index 563a780dcb..87c1c86eb1 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -193,20 +193,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 { diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index 41a90d133d..218891ad35 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -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 } diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go index c209386e2e..2ee69cd323 100644 --- a/models/issues/pull_list.go +++ b/models/issues/pull_list.go @@ -212,3 +212,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) +} diff --git a/models/issues/review.go b/models/issues/review.go index fc110630e0..70aba0f94d 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -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 } |