From 377d160baa6d640d87457c11b99dbb54d9d0baa7 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Tue, 6 Jun 2023 03:39:16 +0200 Subject: [PATCH 1/3] Show total TrackedTime in issue list and milestone issue list [partial frontport] --- models/issues/issue_stats.go | 97 ++++++++++++++++++----------------- models/issues/tracked_time.go | 50 ++++++++++++++++++ 2 files changed, 99 insertions(+), 48 deletions(-) diff --git a/models/issues/issue_stats.go b/models/issues/issue_stats.go index 6c249c224416..8f2820b28191 100644 --- a/models/issues/issue_stats.go +++ b/models/issues/issue_stats.go @@ -116,68 +116,69 @@ func GetIssueStats(opts *IssuesOptions) (*IssueStats, error) { func getIssueStatsChunk(opts *IssuesOptions, issueIDs []int64) (*IssueStats, error) { stats := &IssueStats{} - countSession := func(opts *IssuesOptions, issueIDs []int64) *xorm.Session { - sess := db.GetEngine(db.DefaultContext). - Join("INNER", "repository", "`issue`.repo_id = `repository`.id") - if len(opts.RepoIDs) > 1 { - sess.In("issue.repo_id", opts.RepoIDs) - } else if len(opts.RepoIDs) == 1 { - sess.And("issue.repo_id = ?", opts.RepoIDs[0]) - } + sess := db.GetEngine(db.DefaultContext). + Join("INNER", "repository", "`issue`.repo_id = `repository`.id") - if len(issueIDs) > 0 { - sess.In("issue.id", issueIDs) - } + var err error + stats.OpenCount, err = applyIssueStatsOptions(sess, opts, issueIDs). + And("issue.is_closed = ?", false). + Count(new(Issue)) + if err != nil { + return stats, err + } + stats.ClosedCount, err = applyIssueStatsOptions(sess, opts, issueIDs). + And("issue.is_closed = ?", true). + Count(new(Issue)) + return stats, err +} - applyLabelsCondition(sess, opts) +func applyIssueStatsOptions(sess *xorm.Session, opts *IssuesOptions, issueIDs []int64) *xorm.Session { + if len(opts.RepoIDs) > 1 { + sess.In("issue.repo_id", opts.RepoIDs) + } else if len(opts.RepoIDs) == 1 { + sess.And("issue.repo_id = ?", opts.RepoIDs[0]) + } - applyMilestoneCondition(sess, opts) + if len(issueIDs) > 0 { + sess.In("issue.id", issueIDs) + } - applyProjectCondition(sess, opts) + applyLabelsCondition(sess, opts) - if opts.AssigneeID > 0 { - applyAssigneeCondition(sess, opts.AssigneeID) - } else if opts.AssigneeID == db.NoConditionID { - sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)") - } + applyMilestoneCondition(sess, opts) - if opts.PosterID > 0 { - applyPosterCondition(sess, opts.PosterID) - } + applyProjectCondition(sess, opts) - if opts.MentionedID > 0 { - applyMentionedCondition(sess, opts.MentionedID) - } + if opts.AssigneeID > 0 { + applyAssigneeCondition(sess, opts.AssigneeID) + } else if opts.AssigneeID == db.NoConditionID { + sess.Where("issue.id NOT IN (SELECT issue_id FROM issue_assignees)") + } - if opts.ReviewRequestedID > 0 { - applyReviewRequestedCondition(sess, opts.ReviewRequestedID) - } + if opts.PosterID > 0 { + applyPosterCondition(sess, opts.PosterID) + } - if opts.ReviewedID > 0 { - applyReviewedCondition(sess, opts.ReviewedID) - } + if opts.MentionedID > 0 { + applyMentionedCondition(sess, opts.MentionedID) + } - switch opts.IsPull { - case util.OptionalBoolTrue: - sess.And("issue.is_pull=?", true) - case util.OptionalBoolFalse: - sess.And("issue.is_pull=?", false) - } + if opts.ReviewRequestedID > 0 { + applyReviewRequestedCondition(sess, opts.ReviewRequestedID) + } - return sess + if opts.ReviewedID > 0 { + applyReviewedCondition(sess, opts.ReviewedID) } - var err error - stats.OpenCount, err = countSession(opts, issueIDs). - And("issue.is_closed = ?", false). - Count(new(Issue)) - if err != nil { - return stats, err + switch opts.IsPull { + case util.OptionalBoolTrue: + sess.And("issue.is_pull=?", true) + case util.OptionalBoolFalse: + sess.And("issue.is_pull=?", false) } - stats.ClosedCount, err = countSession(opts, issueIDs). - And("issue.is_closed = ?", true). - Count(new(Issue)) - return stats, err + + return sess } // GetUserIssueStats returns issue statistic information for dashboard by given conditions. diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index 58c6b775f077..ef109fc09937 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/util" "xorm.io/builder" + "xorm.io/xorm" ) // TrackedTime represents a time that was spent for a specific issue. @@ -325,3 +326,52 @@ func GetTrackedTimeByID(id int64) (*TrackedTime, error) { } return time, nil } + +// GetIssueTotalTrackedTime returns the total tracked time for issues by given conditions. +func GetIssueTotalTrackedTime(opts *IssuesOptions, isClosed bool) (int64, error) { + if len(opts.IssueIDs) <= MaxQueryParameters { + return getIssueTotalTrackedTimeChunk(opts, isClosed, 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. + var accum int64 = 0 + for i := 0; i < len(opts.IssueIDs); { + chunk := i + MaxQueryParameters + if chunk > len(opts.IssueIDs) { + chunk = len(opts.IssueIDs) + } + time, err := getIssueTotalTrackedTimeChunk(opts, isClosed, opts.IssueIDs[i:chunk]) + if err != nil { + return 0, err + } + accum += time + i = chunk + } + return accum, nil +} + +func getIssueTotalTrackedTimeChunk(opts *IssuesOptions, isClosed bool, issueIDs []int64) (int64, error) { + sumSession := func(opts *IssuesOptions, issueIDs []int64) *xorm.Session { + sess := db.GetEngine(db.DefaultContext). + Table("tracked_time"). + Where("tracked_time.deleted = ?", false). + Join("INNER", "issue", "tracked_time.issue_id = issue.id") + + if len(issueIDs) > 0 { + sess.In("issue.id", issueIDs) + } + + return applyIssueStatsOptions(sess, opts, nil) + } + + type trackedTime struct { + Time int64 + } + + return sumSession(opts, issueIDs). + And("issue.is_closed = ?", isClosed). + SumInt(new(trackedTime), "tracked_time.time") +} From 056ea960ed3c0faf444eb622f53ba9a8c28a5ac2 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Wed, 23 Aug 2023 00:53:32 +0200 Subject: [PATCH 2/3] rm diff thats to be in next pull --- models/issues/tracked_time.go | 50 ----------------------------------- 1 file changed, 50 deletions(-) diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go index ef109fc09937..58c6b775f077 100644 --- a/models/issues/tracked_time.go +++ b/models/issues/tracked_time.go @@ -15,7 +15,6 @@ import ( "code.gitea.io/gitea/modules/util" "xorm.io/builder" - "xorm.io/xorm" ) // TrackedTime represents a time that was spent for a specific issue. @@ -326,52 +325,3 @@ func GetTrackedTimeByID(id int64) (*TrackedTime, error) { } return time, nil } - -// GetIssueTotalTrackedTime returns the total tracked time for issues by given conditions. -func GetIssueTotalTrackedTime(opts *IssuesOptions, isClosed bool) (int64, error) { - if len(opts.IssueIDs) <= MaxQueryParameters { - return getIssueTotalTrackedTimeChunk(opts, isClosed, 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. - var accum int64 = 0 - for i := 0; i < len(opts.IssueIDs); { - chunk := i + MaxQueryParameters - if chunk > len(opts.IssueIDs) { - chunk = len(opts.IssueIDs) - } - time, err := getIssueTotalTrackedTimeChunk(opts, isClosed, opts.IssueIDs[i:chunk]) - if err != nil { - return 0, err - } - accum += time - i = chunk - } - return accum, nil -} - -func getIssueTotalTrackedTimeChunk(opts *IssuesOptions, isClosed bool, issueIDs []int64) (int64, error) { - sumSession := func(opts *IssuesOptions, issueIDs []int64) *xorm.Session { - sess := db.GetEngine(db.DefaultContext). - Table("tracked_time"). - Where("tracked_time.deleted = ?", false). - Join("INNER", "issue", "tracked_time.issue_id = issue.id") - - if len(issueIDs) > 0 { - sess.In("issue.id", issueIDs) - } - - return applyIssueStatsOptions(sess, opts, nil) - } - - type trackedTime struct { - Time int64 - } - - return sumSession(opts, issueIDs). - And("issue.is_closed = ?", isClosed). - SumInt(new(trackedTime), "tracked_time.time") -} From 7e7a2c5b69cb6ced5892064d29a3c611c7fa48d5 Mon Sep 17 00:00:00 2001 From: "m.huber" Date: Wed, 23 Aug 2023 00:57:37 +0200 Subject: [PATCH 3/3] adjust to renamed opt --- models/issues/issue_stats.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/models/issues/issue_stats.go b/models/issues/issue_stats.go index 8f2820b28191..1654e6ce756f 100644 --- a/models/issues/issue_stats.go +++ b/models/issues/issue_stats.go @@ -120,19 +120,19 @@ func getIssueStatsChunk(opts *IssuesOptions, issueIDs []int64) (*IssueStats, err Join("INNER", "repository", "`issue`.repo_id = `repository`.id") var err error - stats.OpenCount, err = applyIssueStatsOptions(sess, opts, issueIDs). + stats.OpenCount, err = applyIssuesOptions(sess, opts, issueIDs). And("issue.is_closed = ?", false). Count(new(Issue)) if err != nil { return stats, err } - stats.ClosedCount, err = applyIssueStatsOptions(sess, opts, issueIDs). + stats.ClosedCount, err = applyIssuesOptions(sess, opts, issueIDs). And("issue.is_closed = ?", true). Count(new(Issue)) return stats, err } -func applyIssueStatsOptions(sess *xorm.Session, opts *IssuesOptions, issueIDs []int64) *xorm.Session { +func applyIssuesOptions(sess *xorm.Session, opts *IssuesOptions, issueIDs []int64) *xorm.Session { if len(opts.RepoIDs) > 1 { sess.In("issue.repo_id", opts.RepoIDs) } else if len(opts.RepoIDs) == 1 {