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, | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue