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:
parent
5c3be56f7b
commit
f490291bea
3 changed files with 45 additions and 26 deletions
|
@ -1045,16 +1045,18 @@ func GetIssuesByIDs(issueIDs []int64) ([]*Issue, error) {
|
||||||
// IssuesOptions represents options of an issue.
|
// IssuesOptions represents options of an issue.
|
||||||
type IssuesOptions struct {
|
type IssuesOptions struct {
|
||||||
ListOptions
|
ListOptions
|
||||||
RepoIDs []int64 // include all repos if empty
|
RepoIDs []int64 // include all repos if empty
|
||||||
AssigneeID int64
|
AssigneeID int64
|
||||||
PosterID int64
|
PosterID int64
|
||||||
MentionedID int64
|
MentionedID int64
|
||||||
MilestoneID int64
|
MilestoneID int64
|
||||||
IsClosed util.OptionalBool
|
IsClosed util.OptionalBool
|
||||||
IsPull util.OptionalBool
|
IsPull util.OptionalBool
|
||||||
LabelIDs []int64
|
LabelIDs []int64
|
||||||
SortType string
|
IncludedLabelNames []string
|
||||||
IssueIDs []int64
|
ExcludedLabelNames []string
|
||||||
|
SortType string
|
||||||
|
IssueIDs []int64
|
||||||
// prioritize issues from this repo
|
// prioritize issues from this repo
|
||||||
PriorityRepoID int64
|
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
|
// CountIssuesByRepo map from repoID to number of issues matching the options
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -154,13 +152,13 @@ func SearchIssues(ctx *context.APIContext) {
|
||||||
Page: ctx.QueryInt("page"),
|
Page: ctx.QueryInt("page"),
|
||||||
PageSize: setting.UI.IssuePagingNum,
|
PageSize: setting.UI.IssuePagingNum,
|
||||||
},
|
},
|
||||||
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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue