diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2020-03-30 13:30:39 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-30 02:30:39 -0300 |
commit | f490291bea98308c55e61e68245becda42270b4c (patch) | |
tree | b279e2ffb10955d49b9d4835790a90a0f4d7ec6f | |
parent | 5c3be56f7bad9f068b8e8c0c3d6664b6847349c6 (diff) | |
download | gitea-f490291bea98308c55e61e68245becda42270b4c.tar.gz gitea-f490291bea98308c55e61e68245becda42270b4c.zip |
Use subquery to instead In (#10874)
* Use subquery to instead In
* Support excludedLabelNames on issues options
* Fix tests
Co-authored-by: zeripath <art27@cantab.net>
-rw-r--r-- | models/issue.go | 30 | ||||
-rw-r--r-- | models/issue_label.go | 11 | ||||
-rw-r--r-- | routers/api/v1/repo/issue.go | 30 |
3 files changed, 45 insertions, 26 deletions
diff --git a/models/issue.go b/models/issue.go index 03af32700d..8aa02873a1 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1045,16 +1045,18 @@ func GetIssuesByIDs(issueIDs []int64) ([]*Issue, error) { // IssuesOptions represents options of an issue. type IssuesOptions struct { ListOptions - RepoIDs []int64 // include all repos if empty - AssigneeID int64 - PosterID int64 - MentionedID int64 - MilestoneID int64 - IsClosed util.OptionalBool - IsPull util.OptionalBool - LabelIDs []int64 - SortType string - IssueIDs []int64 + RepoIDs []int64 // include all repos if empty + AssigneeID int64 + PosterID int64 + MentionedID int64 + MilestoneID int64 + IsClosed util.OptionalBool + IsPull util.OptionalBool + LabelIDs []int64 + IncludedLabelNames []string + ExcludedLabelNames []string + SortType string + IssueIDs []int64 // prioritize issues from this repo PriorityRepoID int64 } @@ -1153,6 +1155,14 @@ func (opts *IssuesOptions) setupSession(sess *xorm.Session) { } } } + + if len(opts.IncludedLabelNames) > 0 { + sess.In("issue.id", BuildLabelNamesIssueIDsCondition(opts.IncludedLabelNames)) + } + + if len(opts.ExcludedLabelNames) > 0 { + sess.And(builder.NotIn("issue.id", BuildLabelNamesIssueIDsCondition(opts.ExcludedLabelNames))) + } } // CountIssuesByRepo map from repoID to number of issues matching the options diff --git a/models/issue_label.go b/models/issue_label.go index c111afb2ff..3b516a7aed 100644 --- a/models/issue_label.go +++ b/models/issue_label.go @@ -269,6 +269,17 @@ func GetLabelIDsInRepoByNames(repoID int64, labelNames []string) ([]int64, error Find(&labelIDs) } +// BuildLabelNamesIssueIDsCondition returns a builder where get issue ids match label names +func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder { + return builder.Select("issue_label.issue_id"). + From("issue_label"). + InnerJoin("label", "label.id = issue_label.label_id"). + Where( + builder.In("label.name", labelNames), + ). + GroupBy("issue_label.issue_id") +} + // GetLabelIDsInReposByNames returns a list of labelIDs by names in one of the given // repositories. // it silently ignores label names that do not belong to the repository. diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 2f08ba6ea6..25664e45a9 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -88,6 +88,7 @@ func SearchIssues(ctx *context.APIContext) { opts.Private = true opts.AllLimited = true } + issueCount := 0 for page := 1; ; page++ { opts.Page = page @@ -127,15 +128,6 @@ func SearchIssues(ctx *context.APIContext) { issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword) } - labels := ctx.Query("labels") - if splitted := strings.Split(labels, ","); labels != "" && len(splitted) > 0 { - labelIDs, err = models.GetLabelIDsInReposByNames(repoIDs, splitted) - if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err) - return - } - } - var isPull util.OptionalBool switch ctx.Query("type") { case "pulls": @@ -146,6 +138,12 @@ func SearchIssues(ctx *context.APIContext) { isPull = util.OptionalBoolNone } + labels := strings.TrimSpace(ctx.Query("labels")) + var includedLabelNames []string + if len(labels) > 0 { + includedLabelNames = strings.Split(labels, ",") + } + // Only fetch the issues if we either don't have a keyword or the search returned issues // This would otherwise return all issues if no issues were found by the search. if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { @@ -154,13 +152,13 @@ func SearchIssues(ctx *context.APIContext) { Page: ctx.QueryInt("page"), PageSize: setting.UI.IssuePagingNum, }, - RepoIDs: repoIDs, - IsClosed: isClosed, - IssueIDs: issueIDs, - LabelIDs: labelIDs, - SortType: "priorityrepo", - PriorityRepoID: ctx.QueryInt64("priority_repo_id"), - IsPull: isPull, + RepoIDs: repoIDs, + IsClosed: isClosed, + IssueIDs: issueIDs, + IncludedLabelNames: includedLabelNames, + SortType: "priorityrepo", + PriorityRepoID: ctx.QueryInt64("priority_repo_id"), + IsPull: isPull, }) } |