User specific repoID or xorm builder conditions for issue search (#19475)

* extend models.IssuesOptions to have more specific repo filter options

* use new options

* unrelated refactor

* rm RepoIDs
This commit is contained in:
6543 2022-04-25 16:06:24 +02:00 committed by GitHub
parent fe274c148b
commit ddbbe6e15c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 25 additions and 34 deletions

View file

@ -1194,7 +1194,8 @@ func GetIssuesByIDs(issueIDs []int64) ([]*Issue, error) {
// IssuesOptions represents options of an issue. // IssuesOptions represents options of an issue.
type IssuesOptions struct { type IssuesOptions struct {
db.ListOptions db.ListOptions
RepoIDs []int64 // include all repos if empty RepoID int64 // overwrites RepoCond if not 0
RepoCond builder.Cond
AssigneeID int64 AssigneeID int64
PosterID int64 PosterID int64
MentionedID int64 MentionedID int64
@ -1285,15 +1286,15 @@ func (opts *IssuesOptions) setupSessionNoLimit(sess *xorm.Session) {
sess.In("issue.id", opts.IssueIDs) sess.In("issue.id", opts.IssueIDs)
} }
if len(opts.RepoIDs) > 0 { if opts.RepoID != 0 {
applyReposCondition(sess, opts.RepoIDs) opts.RepoCond = builder.Eq{"issue.repo_id": opts.RepoID}
}
if opts.RepoCond != nil {
sess.And(opts.RepoCond)
} }
switch opts.IsClosed { if !opts.IsClosed.IsNone() {
case util.OptionalBoolTrue: sess.And("issue.is_closed=?", opts.IsClosed.IsTrue())
sess.And("issue.is_closed=?", true)
case util.OptionalBoolFalse:
sess.And("issue.is_closed=?", false)
} }
if opts.AssigneeID > 0 { if opts.AssigneeID > 0 {
@ -1412,10 +1413,6 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organizati
return cond return cond
} }
func applyReposCondition(sess *xorm.Session, repoIDs []int64) *xorm.Session {
return sess.In("issue.repo_id", repoIDs)
}
func applyAssigneeCondition(sess *xorm.Session, assigneeID int64) *xorm.Session { func applyAssigneeCondition(sess *xorm.Session, assigneeID int64) *xorm.Session {
return sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). return sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id").
And("issue_assignees.assignee_id = ?", assigneeID) And("issue_assignees.assignee_id = ?", assigneeID)

View file

@ -57,12 +57,9 @@ func (label *Label) CalOpenIssues() {
// CalOpenOrgIssues calculates the open issues of a label for a specific repo // CalOpenOrgIssues calculates the open issues of a label for a specific repo
func (label *Label) CalOpenOrgIssues(repoID, labelID int64) { func (label *Label) CalOpenOrgIssues(repoID, labelID int64) {
repoIDs := []int64{repoID}
labelIDs := []int64{labelID}
counts, _ := CountIssuesByRepo(&IssuesOptions{ counts, _ := CountIssuesByRepo(&IssuesOptions{
RepoIDs: repoIDs, RepoID: repoID,
LabelIDs: labelIDs, LabelIDs: []int64{labelID},
}) })
for _, count := range counts { for _, count := range counts {

View file

@ -21,6 +21,7 @@ import (
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"xorm.io/builder"
) )
func TestIssue_ReplaceLabels(t *testing.T) { func TestIssue_ReplaceLabels(t *testing.T) {
@ -157,7 +158,7 @@ func TestIssues(t *testing.T) {
}, },
{ {
IssuesOptions{ IssuesOptions{
RepoIDs: []int64{1, 3}, RepoCond: builder.In("repo_id", 1, 3),
SortType: "oldest", SortType: "oldest",
ListOptions: db.ListOptions{ ListOptions: db.ListOptions{
Page: 1, Page: 1,
@ -344,7 +345,7 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) {
}, },
{ {
IssuesOptions{ IssuesOptions{
RepoIDs: []int64{1, 2}, RepoCond: builder.In("repo_id", 1, 2),
}, },
[]int64{1, 2}, []int64{1, 2},
}, },

View file

@ -321,7 +321,7 @@ func populateIssueIndexer(ctx context.Context) {
// UpdateRepoIndexer add/update all issues of the repositories // UpdateRepoIndexer add/update all issues of the repositories
func UpdateRepoIndexer(repo *repo_model.Repository) { func UpdateRepoIndexer(repo *repo_model.Repository) {
is, err := models.Issues(&models.IssuesOptions{ is, err := models.Issues(&models.IssuesOptions{
RepoIDs: []int64{repo.ID}, RepoID: repo.ID,
IsClosed: util.OptionalBoolNone, IsClosed: util.OptionalBoolNone,
IsPull: util.OptionalBoolNone, IsPull: util.OptionalBoolNone,
}) })

View file

@ -175,6 +175,7 @@ func SearchIssues(ctx *context.APIContext) {
opts.TeamID = team.ID opts.TeamID = team.ID
} }
repoCond := models.SearchRepositoryCondition(opts)
repoIDs, _, err := models.SearchRepositoryIDs(opts) repoIDs, _, err := models.SearchRepositoryIDs(opts)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err) ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err)
@ -235,7 +236,7 @@ func SearchIssues(ctx *context.APIContext) {
Page: ctx.FormInt("page"), Page: ctx.FormInt("page"),
PageSize: limit, PageSize: limit,
}, },
RepoIDs: repoIDs, RepoCond: repoCond,
IsClosed: isClosed, IsClosed: isClosed,
IssueIDs: issueIDs, IssueIDs: issueIDs,
IncludedLabelNames: includedLabelNames, IncludedLabelNames: includedLabelNames,
@ -462,7 +463,7 @@ func ListIssues(ctx *context.APIContext) {
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
issuesOpt := &models.IssuesOptions{ issuesOpt := &models.IssuesOptions{
ListOptions: listOptions, ListOptions: listOptions,
RepoIDs: []int64{ctx.Repo.Repository.ID}, RepoID: ctx.Repo.Repository.ID,
IsClosed: isClosed, IsClosed: isClosed,
IssueIDs: issueIDs, IssueIDs: issueIDs,
LabelIDs: labelIDs, LabelIDs: labelIDs,

View file

@ -232,7 +232,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
Page: pager.Paginater.Current(), Page: pager.Paginater.Current(),
PageSize: setting.UI.IssuePagingNum, PageSize: setting.UI.IssuePagingNum,
}, },
RepoIDs: []int64{repo.ID}, RepoID: repo.ID,
AssigneeID: assigneeID, AssigneeID: assigneeID,
PosterID: posterID, PosterID: posterID,
MentionedID: mentionedID, MentionedID: mentionedID,
@ -2167,6 +2167,7 @@ func SearchIssues(ctx *context.Context) {
opts.TeamID = team.ID opts.TeamID = team.ID
} }
repoCond := models.SearchRepositoryCondition(opts)
repoIDs, _, err := models.SearchRepositoryIDs(opts) repoIDs, _, err := models.SearchRepositoryIDs(opts)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err.Error()) ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err.Error())
@ -2227,7 +2228,7 @@ func SearchIssues(ctx *context.Context) {
Page: ctx.FormInt("page"), Page: ctx.FormInt("page"),
PageSize: limit, PageSize: limit,
}, },
RepoIDs: repoIDs, RepoCond: repoCond,
IsClosed: isClosed, IsClosed: isClosed,
IssueIDs: issueIDs, IssueIDs: issueIDs,
IncludedLabelNames: includedLabelNames, IncludedLabelNames: includedLabelNames,
@ -2403,7 +2404,7 @@ func ListIssues(ctx *context.Context) {
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 { if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
issuesOpt := &models.IssuesOptions{ issuesOpt := &models.IssuesOptions{
ListOptions: listOptions, ListOptions: listOptions,
RepoIDs: []int64{ctx.Repo.Repository.ID}, RepoID: ctx.Repo.Repository.ID,
IsClosed: isClosed, IsClosed: isClosed,
IssueIDs: issueIDs, IssueIDs: issueIDs,
LabelIDs: labelIDs, LabelIDs: labelIDs,

View file

@ -463,13 +463,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// to check if it's in the team(which possible isn't the case). // to check if it's in the team(which possible isn't the case).
opts.User = nil opts.User = nil
} }
userRepoIDs, _, err := models.SearchRepositoryIDs(repoOpts) opts.RepoCond = models.SearchRepositoryCondition(repoOpts)
if err != nil {
ctx.ServerError("models.SearchRepositoryIDs: %v", err)
return
}
opts.RepoIDs = userRepoIDs
} }
// keyword holds the search term entered into the search field. // keyword holds the search term entered into the search field.
@ -533,7 +527,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// Gets set when clicking filters on the issues overview page. // Gets set when clicking filters on the issues overview page.
repoIDs := getRepoIDs(ctx.FormString("repos")) repoIDs := getRepoIDs(ctx.FormString("repos"))
if len(repoIDs) > 0 { if len(repoIDs) > 0 {
opts.RepoIDs = repoIDs opts.RepoCond = builder.In("issue.repo_id", repoIDs)
} }
// ------------------------------ // ------------------------------

View file

@ -105,7 +105,7 @@ func TestGiteaUploadRepo(t *testing.T) {
assert.Len(t, releases, 1) assert.Len(t, releases, 1)
issues, err := models.Issues(&models.IssuesOptions{ issues, err := models.Issues(&models.IssuesOptions{
RepoIDs: []int64{repo.ID}, RepoID: repo.ID,
IsPull: util.OptionalBoolFalse, IsPull: util.OptionalBoolFalse,
SortType: "oldest", SortType: "oldest",
}) })