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>
This commit is contained in:
Lunny Xiao 2020-03-30 13:30:39 +08:00 committed by GitHub
parent 5c3be56f7b
commit f490291bea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 26 deletions

View file

@ -1053,6 +1053,8 @@ type IssuesOptions struct {
IsClosed util.OptionalBool IsClosed util.OptionalBool
IsPull util.OptionalBool IsPull util.OptionalBool
LabelIDs []int64 LabelIDs []int64
IncludedLabelNames []string
ExcludedLabelNames []string
SortType string SortType string
IssueIDs []int64 IssueIDs []int64
// prioritize issues from this repo // prioritize issues from this repo
@ -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 // CountIssuesByRepo map from repoID to number of issues matching the options

View file

@ -269,6 +269,17 @@ func GetLabelIDsInRepoByNames(repoID int64, labelNames []string) ([]int64, error
Find(&labelIDs) 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 // GetLabelIDsInReposByNames returns a list of labelIDs by names in one of the given
// repositories. // repositories.
// it silently ignores label names that do not belong to the repository. // it silently ignores label names that do not belong to the repository.

View file

@ -88,6 +88,7 @@ func SearchIssues(ctx *context.APIContext) {
opts.Private = true opts.Private = true
opts.AllLimited = true opts.AllLimited = true
} }
issueCount := 0 issueCount := 0
for page := 1; ; page++ { for page := 1; ; page++ {
opts.Page = page opts.Page = page
@ -127,15 +128,6 @@ func SearchIssues(ctx *context.APIContext) {
issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword) 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 var isPull util.OptionalBool
switch ctx.Query("type") { switch ctx.Query("type") {
case "pulls": case "pulls":
@ -146,6 +138,12 @@ func SearchIssues(ctx *context.APIContext) {
isPull = util.OptionalBoolNone 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 // 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. // This would otherwise return all issues if no issues were found by the search.
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
@ -157,7 +155,7 @@ func SearchIssues(ctx *context.APIContext) {
RepoIDs: repoIDs, RepoIDs: repoIDs,
IsClosed: isClosed, IsClosed: isClosed,
IssueIDs: issueIDs, IssueIDs: issueIDs,
LabelIDs: labelIDs, IncludedLabelNames: includedLabelNames,
SortType: "priorityrepo", SortType: "priorityrepo",
PriorityRepoID: ctx.QueryInt64("priority_repo_id"), PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
IsPull: isPull, IsPull: isPull,