From f9a6241238ffc5162f70c8c9f5f53ef8749a8e03 Mon Sep 17 00:00:00 2001 From: YR Chen Date: Mon, 25 Mar 2024 16:13:33 +0000 Subject: [PATCH 1/5] Replace `max( id )` in `GetLatestCommitStatus` --- models/git/commit_status.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 2d1d1bcb06db6..91c3d5ae62037 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -269,23 +269,23 @@ type CommitStatusIndex struct { // GetLatestCommitStatus returns all statuses with a unique context for a given commit. func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOptions db.ListOptions) ([]*CommitStatus, int64, error) { - ids := make([]int64, 0, 10) - sess := db.GetEngine(ctx).Table(&CommitStatus{}). - Where("repo_id = ?", repoID).And("sha = ?", sha). - Select("max( id ) as id"). - GroupBy("context_hash").OrderBy("max( id ) desc") + base := db.GetEngine(ctx).Table(&CommitStatus{}). + Where("repo_id = ?", repoID).And("sha = ?", sha) + indices := make([]int64, 0, 10) + sess := base.Select("max( `index` ) as `index`"). + GroupBy("context_hash").OrderBy("max( `index` ) desc") if !listOptions.IsListAll() { sess = db.SetSessionPagination(sess, &listOptions) } - count, err := sess.FindAndCount(&ids) + count, err := sess.FindAndCount(&indices) if err != nil { return nil, count, err } - statuses := make([]*CommitStatus, 0, len(ids)) - if len(ids) == 0 { + statuses := make([]*CommitStatus, 0, len(indices)) + if len(indices) == 0 { return statuses, count, nil } - return statuses, count, db.GetEngine(ctx).In("id", ids).Find(&statuses) + return statuses, count, base.And(builder.In("`index`", indices)).Find(&statuses) } // GetLatestCommitStatusForPairs returns all statuses with a unique context for a given list of repo-sha pairs From 4921971fa4744af98a0d5fb7537333f0cf8caddd Mon Sep 17 00:00:00 2001 From: YR Chen Date: Mon, 25 Mar 2024 16:42:58 +0000 Subject: [PATCH 2/5] Replace `max( id )` in `FindRepoRecentCommitStatusContexts` --- models/git/commit_status.go | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 91c3d5ae62037..d0c9fe7586678 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -388,22 +388,33 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) { + type result struct { + Index int64 + SHA string + } start := timeutil.TimeStampNow().AddDuration(-before) - ids := make([]int64, 0, 10) - if err := db.GetEngine(ctx).Table("commit_status"). - Where("repo_id = ?", repoID). - And("updated_unix >= ?", start). - Select("max( id ) as id"). - GroupBy("context_hash").OrderBy("max( id ) desc"). - Find(&ids); err != nil { + base := db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID) + results := make([]result, 0, 10) + + sess := base.And("updated_unix >= ?", start). + Select("max( `index` ) as `index`, sha"). + GroupBy("context_hash, sha").OrderBy("max( `index` ) desc") + + err := sess.Find(&results) + if err != nil { return nil, err } - contexts := make([]string, 0, len(ids)) - if len(ids) == 0 { + contexts := make([]string, 0, len(results)) + if len(results) == 0 { return contexts, nil } - return contexts, db.GetEngine(ctx).Select("context").Table("commit_status").In("id", ids).Find(&contexts) + + conds := make([]builder.Cond, 0, len(results)) + for _, result := range results { + conds = append(conds, builder.Eq{"`index`": result.Index, "sha": result.SHA}) + } + return contexts, base.And(builder.Or(conds...)).Select("context").Find(&contexts) } // NewCommitStatusOptions holds options for creating a CommitStatus From d79945799ee368315fdb13c2333c9f86fd6c47f6 Mon Sep 17 00:00:00 2001 From: YR Chen Date: Mon, 25 Mar 2024 17:02:55 +0000 Subject: [PATCH 3/5] Replace `max( id )` in `GetLatestCommitStatusForRepoCommitIDs` --- models/git/commit_status.go | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index d0c9fe7586678..684829b2f0fb2 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -342,42 +342,40 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHA // GetLatestCommitStatusForRepoCommitIDs returns all statuses with a unique context for a given list of repo-sha pairs func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, commitIDs []string) (map[string][]*CommitStatus, error) { type result struct { - ID int64 - Sha string + Index int64 + SHA string } - + base := db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID) results := make([]result, 0, len(commitIDs)) - sess := db.GetEngine(ctx).Table(&CommitStatus{}) - - // Create a disjunction of conditions for each repoID and SHA pair conds := make([]builder.Cond, 0, len(commitIDs)) for _, sha := range commitIDs { conds = append(conds, builder.Eq{"sha": sha}) } - sess = sess.Where(builder.Eq{"repo_id": repoID}.And(builder.Or(conds...))). - Select("max( id ) as id, sha"). - GroupBy("context_hash, sha").OrderBy("max( id ) desc") + sess := base.And(builder.Or(conds...)). + Select("max( `index` ) as `index`, sha"). + GroupBy("context_hash, sha").OrderBy("max( `index` ) desc") err := sess.Find(&results) if err != nil { return nil, err } - ids := make([]int64, 0, len(results)) repoStatuses := make(map[string][]*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 len(results) > 0 { + statuses := make([]*CommitStatus, 0, len(results)) + + conds = make([]builder.Cond, 0, len(results)) + for _, result := range results { + conds = append(conds, builder.Eq{"`index`": result.Index, "sha": result.SHA}) + } + err = base.And(builder.Or(conds...)).Find(&statuses) if err != nil { return nil, err } - // Group the statuses by repo ID + // Group the statuses by commit for _, status := range statuses { repoStatuses[status.SHA] = append(repoStatuses[status.SHA], status) } From 14d13d852ac09b4041bd408b1ac4c05782903e4e Mon Sep 17 00:00:00 2001 From: YR Chen Date: Mon, 25 Mar 2024 17:19:26 +0000 Subject: [PATCH 4/5] Replace `max( id )` in `GetLatestCommitStatusForPairs` --- models/git/commit_status.go | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 684829b2f0fb2..504e836e25865 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -291,22 +291,22 @@ func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOp // 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 + Index int64 RepoID int64 } results := make([]result, 0, len(repoIDsToLatestCommitSHAs)) - sess := db.GetEngine(ctx).Table(&CommitStatus{}) + base := 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 := base.Where(builder.Or(conds...)). + Select("max( `index` ) as `index`, repo_id"). + GroupBy("context_hash, repo_id").OrderBy("max( `index` ) desc") if !listOptions.IsListAll() { sess = db.SetSessionPagination(sess, &listOptions) @@ -317,15 +317,21 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHA 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 len(results) > 0 { + statuses := make([]*CommitStatus, 0, len(results)) + + conds = make([]builder.Cond, 0, len(results)) + for _, result := range results { + cond := builder.Eq{ + "`index`": result.Index, + "repo_id": result.RepoID, + "sha": repoIDsToLatestCommitSHAs[result.RepoID], + } + conds = append(conds, cond) + } + err = base.Where(builder.Or(conds...)).Find(&statuses) if err != nil { return nil, err } From 9f943362ed86ff0a5513051bb2560fad847c06ad Mon Sep 17 00:00:00 2001 From: YR Chen Date: Mon, 25 Mar 2024 19:12:35 +0000 Subject: [PATCH 5/5] Always create new xorm session --- models/git/commit_status.go | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 504e836e25865..bb75dcca263b8 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -25,6 +25,7 @@ import ( "code.gitea.io/gitea/modules/translation" "xorm.io/builder" + "xorm.io/xorm" ) // CommitStatus holds a single Status of a single Commit @@ -269,10 +270,12 @@ type CommitStatusIndex struct { // GetLatestCommitStatus returns all statuses with a unique context for a given commit. func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOptions db.ListOptions) ([]*CommitStatus, int64, error) { - base := db.GetEngine(ctx).Table(&CommitStatus{}). - Where("repo_id = ?", repoID).And("sha = ?", sha) + getBase := func() *xorm.Session { + return db.GetEngine(ctx).Table(&CommitStatus{}). + Where("repo_id = ?", repoID).And("sha = ?", sha) + } indices := make([]int64, 0, 10) - sess := base.Select("max( `index` ) as `index`"). + sess := getBase().Select("max( `index` ) as `index`"). GroupBy("context_hash").OrderBy("max( `index` ) desc") if !listOptions.IsListAll() { sess = db.SetSessionPagination(sess, &listOptions) @@ -285,7 +288,7 @@ func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOp if len(indices) == 0 { return statuses, count, nil } - return statuses, count, base.And(builder.In("`index`", indices)).Find(&statuses) + return statuses, count, getBase().And(builder.In("`index`", indices)).Find(&statuses) } // GetLatestCommitStatusForPairs returns all statuses with a unique context for a given list of repo-sha pairs @@ -297,14 +300,16 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHA results := make([]result, 0, len(repoIDsToLatestCommitSHAs)) - base := db.GetEngine(ctx).Table(&CommitStatus{}) + getBase := func() *xorm.Session { + return 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 := base.Where(builder.Or(conds...)). + sess := getBase().Where(builder.Or(conds...)). Select("max( `index` ) as `index`, repo_id"). GroupBy("context_hash, repo_id").OrderBy("max( `index` ) desc") @@ -331,7 +336,7 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHA } conds = append(conds, cond) } - err = base.Where(builder.Or(conds...)).Find(&statuses) + err = getBase().Where(builder.Or(conds...)).Find(&statuses) if err != nil { return nil, err } @@ -351,14 +356,17 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co Index int64 SHA string } - base := db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID) + + getBase := func() *xorm.Session { + return db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID) + } results := make([]result, 0, len(commitIDs)) conds := make([]builder.Cond, 0, len(commitIDs)) for _, sha := range commitIDs { conds = append(conds, builder.Eq{"sha": sha}) } - sess := base.And(builder.Or(conds...)). + sess := getBase().And(builder.Or(conds...)). Select("max( `index` ) as `index`, sha"). GroupBy("context_hash, sha").OrderBy("max( `index` ) desc") @@ -376,7 +384,7 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co for _, result := range results { conds = append(conds, builder.Eq{"`index`": result.Index, "sha": result.SHA}) } - err = base.And(builder.Or(conds...)).Find(&statuses) + err = getBase().And(builder.Or(conds...)).Find(&statuses) if err != nil { return nil, err } @@ -396,11 +404,14 @@ func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, befor Index int64 SHA string } + getBase := func() *xorm.Session { + return db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID) + } + start := timeutil.TimeStampNow().AddDuration(-before) - base := db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID) results := make([]result, 0, 10) - sess := base.And("updated_unix >= ?", start). + sess := getBase().And("updated_unix >= ?", start). Select("max( `index` ) as `index`, sha"). GroupBy("context_hash, sha").OrderBy("max( `index` ) desc") @@ -418,7 +429,7 @@ func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, befor for _, result := range results { conds = append(conds, builder.Eq{"`index`": result.Index, "sha": result.SHA}) } - return contexts, base.And(builder.Or(conds...)).Select("context").Find(&contexts) + return contexts, getBase().And(builder.Or(conds...)).Select("context").Find(&contexts) } // NewCommitStatusOptions holds options for creating a CommitStatus