mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	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:
		@@ -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 New Issue
	
	Block a user