diff options
Diffstat (limited to 'models/git/commit_status.go')
-rw-r--r-- | models/git/commit_status.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 82cbb23637..6028e46649 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -23,6 +23,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" "xorm.io/xorm" ) @@ -240,6 +241,55 @@ func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOp return statuses, count, db.GetEngine(ctx).In("id", ids).Find(&statuses) } +// GetLatestCommitStatusForPairs returns all statuses with a unique context for a given list of repo-sha pairs +func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHAs map[int64]string, listOptions db.ListOptions) (map[int64][]*CommitStatus, error) { + type result struct { + ID int64 + RepoID int64 + } + + results := make([]result, 0, len(repoIDsToLatestCommitSHAs)) + + sess := db.GetEngine(ctx).Table(&CommitStatus{}) + + // Create a disjunction of conditions for each repoID and SHA pair + conds := make([]builder.Cond, 0, len(repoIDsToLatestCommitSHAs)) + for repoID, sha := range repoIDsToLatestCommitSHAs { + conds = append(conds, builder.Eq{"repo_id": repoID, "sha": sha}) + } + sess = sess.Where(builder.Or(conds...)). + Select("max( id ) as id, repo_id"). + GroupBy("context_hash, repo_id").OrderBy("max( id ) desc") + + sess = db.SetSessionPagination(sess, &listOptions) + + err := sess.Find(&results) + if err != nil { + return nil, err + } + + ids := make([]int64, 0, len(results)) + repoStatuses := make(map[int64][]*CommitStatus) + for _, result := range results { + ids = append(ids, result.ID) + } + + statuses := make([]*CommitStatus, 0, len(ids)) + if len(ids) > 0 { + err = db.GetEngine(ctx).In("id", ids).Find(&statuses) + if err != nil { + return nil, err + } + + // Group the statuses by repo ID + for _, status := range statuses { + repoStatuses[status.RepoID] = append(repoStatuses[status.RepoID], status) + } + } + + return repoStatuses, nil +} + // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) { start := timeutil.TimeStampNow().AddDuration(-before) |