aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguillep2k <18600385+guillep2k@users.noreply.github.com>2020-02-15 14:07:09 -0300
committerGitHub <noreply@github.com>2020-02-15 19:07:09 +0200
commit5525452bdf517227e1e6f92fc4adde5f45b4d858 (patch)
tree0f28968c35f05b0d828c47b0aed53bc9ac3fb963
parent987cd277f69f8f3b76f51109f638e2b1124c2dec (diff)
downloadgitea-5525452bdf517227e1e6f92fc4adde5f45b4d858.tar.gz
gitea-5525452bdf517227e1e6f92fc4adde5f45b4d858.zip
Divide GetIssueStats query in smaller chunks (#10176) (#10282)
* Divide GetIssueStats query in smaller chunks * Skip chunking if count is low enough * Fix lint * Define maxQueryParameters * Remove absMaxQueryParameters because of lint * Restart CI * Restart CI Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: Lauris BH <lauris@nix.lv>
-rw-r--r--models/issue.go30
-rw-r--r--models/models.go6
2 files changed, 36 insertions, 0 deletions
diff --git a/models/issue.go b/models/issue.go
index 7c7a7c295a..5d6c9a83e2 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -1336,6 +1336,36 @@ type IssueStatsOptions struct {
// GetIssueStats returns issue statistic information by given conditions.
func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
+ if len(opts.IssueIDs) <= maxQueryParameters {
+ return getIssueStatsChunk(opts, opts.IssueIDs)
+ }
+
+ // If too long a list of IDs is provided, we get the statistics in
+ // smaller chunks and get accumulates. Note: this could potentially
+ // get us invalid results. The alternative is to insert the list of
+ // ids in a temporary table and join from them.
+ accum := &IssueStats{}
+ for i := 0; i < len(opts.IssueIDs); {
+ chunk := i + maxQueryParameters
+ if chunk > len(opts.IssueIDs) {
+ chunk = len(opts.IssueIDs)
+ }
+ stats, err := getIssueStatsChunk(opts, opts.IssueIDs[i:chunk])
+ if err != nil {
+ return nil, err
+ }
+ accum.OpenCount += stats.OpenCount
+ accum.ClosedCount += stats.ClosedCount
+ accum.YourRepositoriesCount += stats.YourRepositoriesCount
+ accum.AssignCount += stats.AssignCount
+ accum.CreateCount += stats.CreateCount
+ accum.OpenCount += stats.MentionCount
+ i = chunk
+ }
+ return accum, nil
+}
+
+func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, error) {
stats := &IssueStats{}
countSession := func(opts *IssueStatsOptions) *xorm.Session {
diff --git a/models/models.go b/models/models.go
index 9eb174e200..fa57840382 100644
--- a/models/models.go
+++ b/models/models.go
@@ -46,6 +46,12 @@ type Engine interface {
Asc(colNames ...string) *xorm.Session
}
+const (
+ // When queries are broken down in parts because of the number
+ // of parameters, attempt to break by this amount
+ maxQueryParameters = 300
+)
+
var (
x *xorm.Engine
tables []interface{}