performance: better sql

This commit is contained in:
Tim-Niclas Oelschläger 2024-02-13 23:43:18 +01:00 committed by Lunny Xiao
parent f9726ea8a4
commit d460a5cdc0
4 changed files with 84 additions and 21 deletions

View File

@ -597,6 +597,8 @@ func IsUserParticipantsOfIssue(ctx context.Context, user *user_model.User, issue
type DependencyInfo struct {
Issue `xorm:"extends"`
repo_model.Repository `xorm:"extends"`
IssueID int64 `xorm:"NOT NULL"`
DependencyID int64 `xorm:"NOT NULL"`
}
// GetParticipantIDsByIssue returns all userIDs who are participated in comments of an issue and issue author

View File

@ -6,6 +6,7 @@ package issues
import (
"context"
"fmt"
"strings"
"code.gitea.io/gitea/models/db"
project_model "code.gitea.io/gitea/models/project"
@ -599,3 +600,59 @@ func (issues IssueList) GetApprovalCounts(ctx context.Context) (map[int64][]*Rev
return approvalCountMap, nil
}
func (issues IssueList) BlockingDependenciesMap(ctx context.Context) (issueDepsMap map[int64][]*DependencyInfo, err error) {
var issueDeps []*DependencyInfo
issueIDsString := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(issues.getIssueIDs())), ","), "[]")
repoIDsString := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(issues.getRepoIDs())), ","), "[]")
err = db.GetEngine(ctx).
Table("issue").
Join("INNER", "repository", "repository.id = issue.repo_id").
Join("INNER", "issue_dependency", "issue_dependency.issue_id = issue.id").
Where(fmt.Sprintf("dependency_id IN (%s)", issueIDsString)).
// sort by repo id then created date, with the issues of the same repo at the beginning of the list
OrderBy(fmt.Sprintf("CASE WHEN issue.repo_id IN (%s) THEN 0 ELSE issue.repo_id END, issue.created_unix ASC", repoIDsString)).
Find(&issueDeps)
if err != nil {
return nil, err
}
issueDepsMap = make(map[int64][]*DependencyInfo, len(issues))
for _, depInfo := range issueDeps {
depInfo.Issue.Repo = &depInfo.Repository
issueDepsMap[depInfo.DependencyID] = append(issueDepsMap[depInfo.DependencyID], depInfo)
}
return issueDepsMap, nil
}
func (issues IssueList) BlockedByDependenciesMap(ctx context.Context) (issueDepsMap map[int64][]*DependencyInfo, err error) {
var issueDeps []*DependencyInfo
issueIDsString := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(issues.getIssueIDs())), ","), "[]")
repoIDsString := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(issues.getRepoIDs())), ","), "[]")
err = db.GetEngine(ctx).
Table("issue").
Join("INNER", "repository", "repository.id = issue.repo_id").
Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id").
Where(fmt.Sprintf("issue_id IN (%s)", issueIDsString)).
// sort by repo id then created date, with the issues of the same repo at the beginning of the list
OrderBy(fmt.Sprintf("CASE WHEN issue.repo_id IN (%s) THEN 0 ELSE issue.repo_id END, issue.created_unix ASC", repoIDsString)).
Find(&issueDeps)
if err != nil {
return nil, err
}
issueDepsMap = make(map[int64][]*DependencyInfo, len(issues))
for _, depInfo := range issueDeps {
depInfo.Issue.Repo = &depInfo.Repository
issueDepsMap[depInfo.IssueID] = append(issueDepsMap[depInfo.IssueID], depInfo)
}
return issueDepsMap, nil
}

View File

@ -346,8 +346,27 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
return
}
blockingDependenciesMap := make(map[int64]template.HTML, len(issues))
blockedByDependenciesMap := make(map[int64]template.HTML, len(issues))
blockingDependenciesTemplates := make(map[int64]template.HTML, len(issues))
blockedByDependenciesTemplates := make(map[int64]template.HTML, len(issues))
blockingDependenciesMap, err := issues.BlockingDependenciesMap(ctx)
if err != nil {
ctx.ServerError("BlockingDependenciesMap", err)
return
}
for i, blockingDependencies := range blockingDependenciesMap {
blockingDependenciesTemplates[i] = dependenciesToHTML(ctx, blockingDependencies)
}
blockedByDependenciesMap, err := issues.BlockedByDependenciesMap(ctx)
if err != nil {
ctx.ServerError("BlockedByDependenciesMap", err)
return
}
for i, blockedByDependencies := range blockedByDependenciesMap {
blockedByDependenciesTemplates[i] = dependenciesToHTML(ctx, blockedByDependencies)
}
// Get posters.
for i := range issues {
// Check read status
@ -357,24 +376,9 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.ServerError("GetIsRead", err)
return
}
blockingDependencies, err := issues[i].BlockingDependencies(ctx)
if err != nil {
ctx.ServerError("BlockingDependencies", err)
return
}
slices.Reverse(blockingDependencies)
blockingDependenciesMap[issues[i].ID] = dependenciesToHTML(ctx, blockingDependencies)
blockedByDependencies, err := issues[i].BlockedByDependencies(ctx, db.ListOptions{})
if err != nil {
ctx.ServerError("BlockedByDependencies", err)
return
}
slices.Reverse(blockedByDependencies)
blockedByDependenciesMap[issues[i].ID] = dependenciesToHTML(ctx, blockedByDependencies)
}
ctx.Data["BlockingDependenciesMap"] = blockingDependenciesMap
ctx.Data["BlockedByDependenciesMap"] = blockedByDependenciesMap
ctx.Data["BlockingDependenciesTemplates"] = blockingDependenciesTemplates
ctx.Data["BlockedByDependenciesTemplates"] = blockedByDependenciesTemplates
commitStatuses, lastStatus, err := pull_service.GetIssuesAllCommitStatus(ctx, issues)
if err != nil {

View File

@ -119,10 +119,10 @@
</span>
{{end}}
{{template "shared/issue_dependency" (dict
"Dependencies" (index $.BlockedByDependenciesMap .ID)
"Dependencies" (index $.BlockedByDependenciesTemplates .ID)
"TitleKey" "repo.issues.dependency.blocked_by_following")}}
{{template "shared/issue_dependency" (dict
"Dependencies" (index $.BlockingDependenciesMap .ID)
"Dependencies" (index $.BlockingDependenciesTemplates .ID)
"TitleKey" "repo.issues.dependency.blocks_following")}}
{{if .IsPull}}
{{$approveOfficial := call $approvalCounts .ID "approve"}}