Signed-off-by: 6543 <6543@obermui.de>tags/v1.22.0-rc0
package bleve | package bleve | ||||
import ( | import ( | ||||
"code.gitea.io/gitea/modules/optional" | |||||
"github.com/blevesearch/bleve/v2" | "github.com/blevesearch/bleve/v2" | ||||
"github.com/blevesearch/bleve/v2/search/query" | "github.com/blevesearch/bleve/v2/search/query" | ||||
) | ) | ||||
return q | return q | ||||
} | } | ||||
func NumericRangeInclusiveQuery(min, max *int64, field string) *query.NumericRangeQuery { | |||||
func NumericRangeInclusiveQuery(min, max optional.Option[int64], field string) *query.NumericRangeQuery { | |||||
var minF, maxF *float64 | var minF, maxF *float64 | ||||
var minI, maxI *bool | var minI, maxI *bool | ||||
if min != nil { | |||||
if min.Has() { | |||||
minF = new(float64) | minF = new(float64) | ||||
*minF = float64(*min) | |||||
*minF = float64(min.Value()) | |||||
minI = new(bool) | minI = new(bool) | ||||
*minI = true | *minI = true | ||||
} | } | ||||
if max != nil { | |||||
if max.Has() { | |||||
maxF = new(float64) | maxF = new(float64) | ||||
*maxF = float64(*max) | |||||
*maxF = float64(max.Value()) | |||||
maxI = new(bool) | maxI = new(bool) | ||||
*maxI = true | *maxI = true | ||||
} | } |
queries = append(queries, bleve.NewDisjunctionQuery(milestoneQueries...)) | queries = append(queries, bleve.NewDisjunctionQuery(milestoneQueries...)) | ||||
} | } | ||||
if options.ProjectID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.ProjectID, "project_id")) | |||||
if options.ProjectID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.ProjectID.Value(), "project_id")) | |||||
} | } | ||||
if options.ProjectBoardID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.ProjectBoardID, "project_board_id")) | |||||
if options.ProjectBoardID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.ProjectBoardID.Value(), "project_board_id")) | |||||
} | } | ||||
if options.PosterID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.PosterID, "poster_id")) | |||||
if options.PosterID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.PosterID.Value(), "poster_id")) | |||||
} | } | ||||
if options.AssigneeID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.AssigneeID, "assignee_id")) | |||||
if options.AssigneeID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.AssigneeID.Value(), "assignee_id")) | |||||
} | } | ||||
if options.MentionID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.MentionID, "mention_ids")) | |||||
if options.MentionID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.MentionID.Value(), "mention_ids")) | |||||
} | } | ||||
if options.ReviewedID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.ReviewedID, "reviewed_ids")) | |||||
if options.ReviewedID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.ReviewedID.Value(), "reviewed_ids")) | |||||
} | } | ||||
if options.ReviewRequestedID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.ReviewRequestedID, "review_requested_ids")) | |||||
if options.ReviewRequestedID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.ReviewRequestedID.Value(), "review_requested_ids")) | |||||
} | } | ||||
if options.SubscriberID != nil { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(*options.SubscriberID, "subscriber_ids")) | |||||
if options.SubscriberID.Has() { | |||||
queries = append(queries, inner_bleve.NumericEqualityQuery(options.SubscriberID.Value(), "subscriber_ids")) | |||||
} | } | ||||
if options.UpdatedAfterUnix != nil || options.UpdatedBeforeUnix != nil { | |||||
queries = append(queries, inner_bleve.NumericRangeInclusiveQuery(options.UpdatedAfterUnix, options.UpdatedBeforeUnix, "updated_unix")) | |||||
if options.UpdatedAfterUnix.Has() || options.UpdatedBeforeUnix.Has() { | |||||
queries = append(queries, inner_bleve.NumericRangeInclusiveQuery( | |||||
options.UpdatedAfterUnix, | |||||
options.UpdatedBeforeUnix, | |||||
"updated_unix")) | |||||
} | } | ||||
var indexerQuery query.Query = bleve.NewConjunctionQuery(queries...) | var indexerQuery query.Query = bleve.NewConjunctionQuery(queries...) |
) | ) | ||||
func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_model.IssuesOptions, error) { | func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_model.IssuesOptions, error) { | ||||
// See the comment of issues_model.SearchOptions for the reason why we need to convert | |||||
convertID := func(id *int64) int64 { | |||||
if id == nil { | |||||
return 0 | |||||
} | |||||
if *id == 0 { | |||||
return db.NoConditionID | |||||
} | |||||
return *id | |||||
} | |||||
convertInt64 := func(i *int64) int64 { | |||||
if i == nil { | |||||
return 0 | |||||
} | |||||
return *i | |||||
} | |||||
var sortType string | var sortType string | ||||
switch options.SortBy { | switch options.SortBy { | ||||
case internal.SortByCreatedAsc: | case internal.SortByCreatedAsc: | ||||
sortType = "newest" | sortType = "newest" | ||||
} | } | ||||
// See the comment of issues_model.SearchOptions for the reason why we need to convert | |||||
convertID := func(id optional.Option[int64]) int64 { | |||||
if !id.Has() { | |||||
return 0 | |||||
} | |||||
value := id.Value() | |||||
if value == 0 { | |||||
return db.NoConditionID | |||||
} | |||||
return value | |||||
} | |||||
opts := &issue_model.IssuesOptions{ | opts := &issue_model.IssuesOptions{ | ||||
Paginator: options.Paginator, | Paginator: options.Paginator, | ||||
RepoIDs: options.RepoIDs, | RepoIDs: options.RepoIDs, | ||||
IncludeMilestones: nil, | IncludeMilestones: nil, | ||||
SortType: sortType, | SortType: sortType, | ||||
IssueIDs: nil, | IssueIDs: nil, | ||||
UpdatedAfterUnix: convertInt64(options.UpdatedAfterUnix), | |||||
UpdatedBeforeUnix: convertInt64(options.UpdatedBeforeUnix), | |||||
UpdatedAfterUnix: options.UpdatedAfterUnix.Value(), | |||||
UpdatedBeforeUnix: options.UpdatedBeforeUnix.Value(), | |||||
PriorityRepoID: 0, | PriorityRepoID: 0, | ||||
IsArchived: optional.None[bool](), | IsArchived: optional.None[bool](), | ||||
Org: nil, | Org: nil, |
import ( | import ( | ||||
"code.gitea.io/gitea/models/db" | "code.gitea.io/gitea/models/db" | ||||
issues_model "code.gitea.io/gitea/models/issues" | issues_model "code.gitea.io/gitea/models/issues" | ||||
"code.gitea.io/gitea/modules/optional" | |||||
) | ) | ||||
func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOptions { | func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOptions { | ||||
} | } | ||||
// See the comment of issues_model.SearchOptions for the reason why we need to convert | // See the comment of issues_model.SearchOptions for the reason why we need to convert | ||||
convertID := func(id int64) *int64 { | |||||
convertID := func(id int64) optional.Option[int64] { | |||||
if id > 0 { | if id > 0 { | ||||
return &id | |||||
return optional.Some(id) | |||||
} | } | ||||
if id == db.NoConditionID { | if id == db.NoConditionID { | ||||
var zero int64 | |||||
return &zero | |||||
return optional.None[int64]() | |||||
} | } | ||||
return nil | return nil | ||||
} | } | ||||
searchOpt.SubscriberID = convertID(opts.SubscriberID) | searchOpt.SubscriberID = convertID(opts.SubscriberID) | ||||
if opts.UpdatedAfterUnix > 0 { | if opts.UpdatedAfterUnix > 0 { | ||||
searchOpt.UpdatedAfterUnix = &opts.UpdatedAfterUnix | |||||
searchOpt.UpdatedAfterUnix = optional.Some(opts.UpdatedAfterUnix) | |||||
} | } | ||||
if opts.UpdatedBeforeUnix > 0 { | if opts.UpdatedBeforeUnix > 0 { | ||||
searchOpt.UpdatedBeforeUnix = &opts.UpdatedBeforeUnix | |||||
searchOpt.UpdatedBeforeUnix = optional.Some(opts.UpdatedBeforeUnix) | |||||
} | } | ||||
searchOpt.Paginator = opts.Paginator | searchOpt.Paginator = opts.Paginator |
query.Must(elastic.NewTermsQuery("milestone_id", toAnySlice(options.MilestoneIDs)...)) | query.Must(elastic.NewTermsQuery("milestone_id", toAnySlice(options.MilestoneIDs)...)) | ||||
} | } | ||||
if options.ProjectID != nil { | |||||
query.Must(elastic.NewTermQuery("project_id", *options.ProjectID)) | |||||
if options.ProjectID.Has() { | |||||
query.Must(elastic.NewTermQuery("project_id", options.ProjectID.Value())) | |||||
} | } | ||||
if options.ProjectBoardID != nil { | |||||
query.Must(elastic.NewTermQuery("project_board_id", *options.ProjectBoardID)) | |||||
if options.ProjectBoardID.Has() { | |||||
query.Must(elastic.NewTermQuery("project_board_id", options.ProjectBoardID.Value())) | |||||
} | } | ||||
if options.PosterID != nil { | |||||
query.Must(elastic.NewTermQuery("poster_id", *options.PosterID)) | |||||
if options.PosterID.Has() { | |||||
query.Must(elastic.NewTermQuery("poster_id", options.PosterID.Value())) | |||||
} | } | ||||
if options.AssigneeID != nil { | |||||
query.Must(elastic.NewTermQuery("assignee_id", *options.AssigneeID)) | |||||
if options.AssigneeID.Has() { | |||||
query.Must(elastic.NewTermQuery("assignee_id", options.AssigneeID.Value())) | |||||
} | } | ||||
if options.MentionID != nil { | |||||
query.Must(elastic.NewTermQuery("mention_ids", *options.MentionID)) | |||||
if options.MentionID.Has() { | |||||
query.Must(elastic.NewTermQuery("mention_ids", options.MentionID.Value())) | |||||
} | } | ||||
if options.ReviewedID != nil { | |||||
query.Must(elastic.NewTermQuery("reviewed_ids", *options.ReviewedID)) | |||||
if options.ReviewedID.Has() { | |||||
query.Must(elastic.NewTermQuery("reviewed_ids", options.ReviewedID.Value())) | |||||
} | } | ||||
if options.ReviewRequestedID != nil { | |||||
query.Must(elastic.NewTermQuery("review_requested_ids", *options.ReviewRequestedID)) | |||||
if options.ReviewRequestedID.Has() { | |||||
query.Must(elastic.NewTermQuery("review_requested_ids", options.ReviewRequestedID.Value())) | |||||
} | } | ||||
if options.SubscriberID != nil { | |||||
query.Must(elastic.NewTermQuery("subscriber_ids", *options.SubscriberID)) | |||||
if options.SubscriberID.Has() { | |||||
query.Must(elastic.NewTermQuery("subscriber_ids", options.SubscriberID.Value())) | |||||
} | } | ||||
if options.UpdatedAfterUnix != nil || options.UpdatedBeforeUnix != nil { | |||||
if options.UpdatedAfterUnix.Has() || options.UpdatedBeforeUnix.Has() { | |||||
q := elastic.NewRangeQuery("updated_unix") | q := elastic.NewRangeQuery("updated_unix") | ||||
if options.UpdatedAfterUnix != nil { | |||||
q.Gte(*options.UpdatedAfterUnix) | |||||
if options.UpdatedAfterUnix.Has() { | |||||
q.Gte(options.UpdatedAfterUnix.Value()) | |||||
} | } | ||||
if options.UpdatedBeforeUnix != nil { | |||||
q.Lte(*options.UpdatedBeforeUnix) | |||||
if options.UpdatedBeforeUnix.Has() { | |||||
q.Lte(options.UpdatedBeforeUnix.Value()) | |||||
} | } | ||||
query.Must(q) | query.Must(q) | ||||
} | } |
} | } | ||||
func searchIssueByID(t *testing.T) { | func searchIssueByID(t *testing.T) { | ||||
int64Pointer := func(x int64) *int64 { | |||||
return &x | |||||
} | |||||
tests := []struct { | tests := []struct { | ||||
opts SearchOptions | opts SearchOptions | ||||
expectedIDs []int64 | expectedIDs []int64 | ||||
}{ | }{ | ||||
{ | { | ||||
SearchOptions{ | |||||
PosterID: int64Pointer(1), | |||||
opts: SearchOptions{ | |||||
PosterID: optional.Some(int64(1)), | |||||
}, | }, | ||||
[]int64{11, 6, 3, 2, 1}, | |||||
expectedIDs: []int64{11, 6, 3, 2, 1}, | |||||
}, | }, | ||||
{ | { | ||||
SearchOptions{ | |||||
AssigneeID: int64Pointer(1), | |||||
opts: SearchOptions{ | |||||
AssigneeID: optional.Some(int64(1)), | |||||
}, | }, | ||||
[]int64{6, 1}, | |||||
expectedIDs: []int64{6, 1}, | |||||
}, | }, | ||||
{ | { | ||||
SearchOptions{ | |||||
MentionID: int64Pointer(4), | |||||
opts: SearchOptions{ | |||||
MentionID: optional.Some(int64(4)), | |||||
}, | }, | ||||
[]int64{1}, | |||||
expectedIDs: []int64{1}, | |||||
}, | }, | ||||
{ | { | ||||
SearchOptions{ | |||||
ReviewedID: int64Pointer(1), | |||||
opts: SearchOptions{ | |||||
ReviewedID: optional.Some(int64(1)), | |||||
}, | }, | ||||
[]int64{}, | |||||
expectedIDs: []int64{}, | |||||
}, | }, | ||||
{ | { | ||||
SearchOptions{ | |||||
ReviewRequestedID: int64Pointer(1), | |||||
opts: SearchOptions{ | |||||
ReviewRequestedID: optional.Some(int64(1)), | |||||
}, | }, | ||||
[]int64{12}, | |||||
expectedIDs: []int64{12}, | |||||
}, | }, | ||||
{ | { | ||||
SearchOptions{ | |||||
SubscriberID: int64Pointer(1), | |||||
opts: SearchOptions{ | |||||
SubscriberID: optional.Some(int64(1)), | |||||
}, | }, | ||||
[]int64{11, 6, 5, 3, 2, 1}, | |||||
expectedIDs: []int64{11, 6, 5, 3, 2, 1}, | |||||
}, | }, | ||||
{ | { | ||||
// issue 20 request user 15 and team 5 which user 15 belongs to | // issue 20 request user 15 and team 5 which user 15 belongs to | ||||
// the review request number of issue 20 should be 1 | // the review request number of issue 20 should be 1 | ||||
SearchOptions{ | |||||
ReviewRequestedID: int64Pointer(15), | |||||
opts: SearchOptions{ | |||||
ReviewRequestedID: optional.Some(int64(15)), | |||||
}, | }, | ||||
[]int64{12, 20}, | |||||
expectedIDs: []int64{12, 20}, | |||||
}, | }, | ||||
{ | { | ||||
// user 20 approved the issue 20, so return nothing | // user 20 approved the issue 20, so return nothing | ||||
SearchOptions{ | |||||
ReviewRequestedID: int64Pointer(20), | |||||
opts: SearchOptions{ | |||||
ReviewRequestedID: optional.Some(int64(20)), | |||||
}, | }, | ||||
[]int64{}, | |||||
expectedIDs: []int64{}, | |||||
}, | }, | ||||
} | } | ||||
} | } | ||||
func searchIssueByTime(t *testing.T) { | func searchIssueByTime(t *testing.T) { | ||||
int64Pointer := func(i int64) *int64 { | |||||
return &i | |||||
} | |||||
tests := []struct { | tests := []struct { | ||||
opts SearchOptions | opts SearchOptions | ||||
expectedIDs []int64 | expectedIDs []int64 | ||||
}{ | }{ | ||||
{ | { | ||||
SearchOptions{ | SearchOptions{ | ||||
UpdatedAfterUnix: int64Pointer(0), | |||||
UpdatedAfterUnix: optional.Some(int64(0)), | |||||
}, | }, | ||||
[]int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, | []int64{22, 21, 17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1}, | ||||
}, | }, | ||||
} | } | ||||
func searchIssueInProject(t *testing.T) { | func searchIssueInProject(t *testing.T) { | ||||
int64Pointer := func(i int64) *int64 { | |||||
return &i | |||||
} | |||||
tests := []struct { | tests := []struct { | ||||
opts SearchOptions | opts SearchOptions | ||||
expectedIDs []int64 | expectedIDs []int64 | ||||
}{ | }{ | ||||
{ | { | ||||
SearchOptions{ | SearchOptions{ | ||||
ProjectID: int64Pointer(1), | |||||
ProjectID: optional.Some(int64(1)), | |||||
}, | }, | ||||
[]int64{5, 3, 2, 1}, | []int64{5, 3, 2, 1}, | ||||
}, | }, | ||||
{ | { | ||||
SearchOptions{ | SearchOptions{ | ||||
ProjectBoardID: int64Pointer(1), | |||||
ProjectBoardID: optional.Some(int64(1)), | |||||
}, | }, | ||||
[]int64{1}, | []int64{1}, | ||||
}, | }, | ||||
{ | { | ||||
SearchOptions{ | SearchOptions{ | ||||
ProjectBoardID: int64Pointer(0), // issue with in default board | |||||
ProjectBoardID: optional.Some(int64(0)), // issue with in default board | |||||
}, | }, | ||||
[]int64{2}, | []int64{2}, | ||||
}, | }, |
MilestoneIDs []int64 // milestones the issues have | MilestoneIDs []int64 // milestones the issues have | ||||
ProjectID *int64 // project the issues belong to | |||||
ProjectBoardID *int64 // project board the issues belong to | |||||
ProjectID optional.Option[int64] // project the issues belong to | |||||
ProjectBoardID optional.Option[int64] // project board the issues belong to | |||||
PosterID *int64 // poster of the issues | |||||
PosterID optional.Option[int64] // poster of the issues | |||||
AssigneeID *int64 // assignee of the issues, zero means no assignee | |||||
AssigneeID optional.Option[int64] // assignee of the issues, zero means no assignee | |||||
MentionID *int64 // mentioned user of the issues | |||||
MentionID optional.Option[int64] // mentioned user of the issues | |||||
ReviewedID *int64 // reviewer of the issues | |||||
ReviewRequestedID *int64 // requested reviewer of the issues | |||||
ReviewedID optional.Option[int64] // reviewer of the issues | |||||
ReviewRequestedID optional.Option[int64] // requested reviewer of the issues | |||||
SubscriberID *int64 // subscriber of the issues | |||||
SubscriberID optional.Option[int64] // subscriber of the issues | |||||
UpdatedAfterUnix *int64 | |||||
UpdatedBeforeUnix *int64 | |||||
UpdatedAfterUnix optional.Option[int64] | |||||
UpdatedBeforeUnix optional.Option[int64] | |||||
db.Paginator | db.Paginator | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
ProjectID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
ProjectID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
ProjectID: func() *int64 { | |||||
id := int64(0) | |||||
return &id | |||||
}(), | |||||
ProjectID: optional.Some(int64(0)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
ProjectBoardID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
ProjectBoardID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
ProjectBoardID: func() *int64 { | |||||
id := int64(0) | |||||
return &id | |||||
}(), | |||||
ProjectBoardID: optional.Some(int64(0)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
PosterID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
PosterID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
AssigneeID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
AssigneeID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
AssigneeID: func() *int64 { | |||||
id := int64(0) | |||||
return &id | |||||
}(), | |||||
AssigneeID: optional.Some(int64(0)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
MentionID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
MentionID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
ReviewedID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
ReviewedID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
ReviewRequestedID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
ReviewRequestedID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
SubscriberID: func() *int64 { | |||||
id := int64(1) | |||||
return &id | |||||
}(), | |||||
SubscriberID: optional.Some(int64(1)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) | ||||
Paginator: &db.ListOptions{ | Paginator: &db.ListOptions{ | ||||
PageSize: 5, | PageSize: 5, | ||||
}, | }, | ||||
UpdatedAfterUnix: func() *int64 { | |||||
var t int64 = 20 | |||||
return &t | |||||
}(), | |||||
UpdatedBeforeUnix: func() *int64 { | |||||
var t int64 = 30 | |||||
return &t | |||||
}(), | |||||
UpdatedAfterUnix: optional.Some(int64(20)), | |||||
UpdatedBeforeUnix: optional.Some(int64(30)), | |||||
}, | }, | ||||
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { | ||||
assert.Equal(t, 5, len(result.Hits)) | assert.Equal(t, 5, len(result.Hits)) |
query.And(inner_meilisearch.NewFilterIn("milestone_id", options.MilestoneIDs...)) | query.And(inner_meilisearch.NewFilterIn("milestone_id", options.MilestoneIDs...)) | ||||
} | } | ||||
if options.ProjectID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("project_id", *options.ProjectID)) | |||||
if options.ProjectID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("project_id", options.ProjectID.Value())) | |||||
} | } | ||||
if options.ProjectBoardID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("project_board_id", *options.ProjectBoardID)) | |||||
if options.ProjectBoardID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("project_board_id", options.ProjectBoardID.Value())) | |||||
} | } | ||||
if options.PosterID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("poster_id", *options.PosterID)) | |||||
if options.PosterID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("poster_id", options.PosterID.Value())) | |||||
} | } | ||||
if options.AssigneeID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("assignee_id", *options.AssigneeID)) | |||||
if options.AssigneeID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("assignee_id", options.AssigneeID.Value())) | |||||
} | } | ||||
if options.MentionID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("mention_ids", *options.MentionID)) | |||||
if options.MentionID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("mention_ids", options.MentionID.Value())) | |||||
} | } | ||||
if options.ReviewedID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("reviewed_ids", *options.ReviewedID)) | |||||
if options.ReviewedID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("reviewed_ids", options.ReviewedID.Value())) | |||||
} | } | ||||
if options.ReviewRequestedID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("review_requested_ids", *options.ReviewRequestedID)) | |||||
if options.ReviewRequestedID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("review_requested_ids", options.ReviewRequestedID.Value())) | |||||
} | } | ||||
if options.SubscriberID != nil { | |||||
query.And(inner_meilisearch.NewFilterEq("subscriber_ids", *options.SubscriberID)) | |||||
if options.SubscriberID.Has() { | |||||
query.And(inner_meilisearch.NewFilterEq("subscriber_ids", options.SubscriberID.Value())) | |||||
} | } | ||||
if options.UpdatedAfterUnix != nil { | |||||
query.And(inner_meilisearch.NewFilterGte("updated_unix", *options.UpdatedAfterUnix)) | |||||
if options.UpdatedAfterUnix.Has() { | |||||
query.And(inner_meilisearch.NewFilterGte("updated_unix", options.UpdatedAfterUnix.Value())) | |||||
} | } | ||||
if options.UpdatedBeforeUnix != nil { | |||||
query.And(inner_meilisearch.NewFilterLte("updated_unix", *options.UpdatedBeforeUnix)) | |||||
if options.UpdatedBeforeUnix.Has() { | |||||
query.And(inner_meilisearch.NewFilterLte("updated_unix", options.UpdatedBeforeUnix.Value())) | |||||
} | } | ||||
if options.SortBy == "" { | if options.SortBy == "" { |
} | } | ||||
if since != 0 { | if since != 0 { | ||||
searchOpt.UpdatedAfterUnix = &since | |||||
searchOpt.UpdatedAfterUnix = optional.Some(since) | |||||
} | } | ||||
if before != 0 { | if before != 0 { | ||||
searchOpt.UpdatedBeforeUnix = &before | |||||
searchOpt.UpdatedBeforeUnix = optional.Some(before) | |||||
} | } | ||||
if ctx.IsSigned { | if ctx.IsSigned { | ||||
ctxUserID := ctx.Doer.ID | ctxUserID := ctx.Doer.ID | ||||
if ctx.FormBool("created") { | if ctx.FormBool("created") { | ||||
searchOpt.PosterID = &ctxUserID | |||||
searchOpt.PosterID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("assigned") { | if ctx.FormBool("assigned") { | ||||
searchOpt.AssigneeID = &ctxUserID | |||||
searchOpt.AssigneeID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("mentioned") { | if ctx.FormBool("mentioned") { | ||||
searchOpt.MentionID = &ctxUserID | |||||
searchOpt.MentionID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("review_requested") { | if ctx.FormBool("review_requested") { | ||||
searchOpt.ReviewRequestedID = &ctxUserID | |||||
searchOpt.ReviewRequestedID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("reviewed") { | if ctx.FormBool("reviewed") { | ||||
searchOpt.ReviewedID = &ctxUserID | |||||
searchOpt.ReviewedID = optional.Some(ctxUserID) | |||||
} | } | ||||
} | } | ||||
SortBy: issue_indexer.SortByCreatedDesc, | SortBy: issue_indexer.SortByCreatedDesc, | ||||
} | } | ||||
if since != 0 { | if since != 0 { | ||||
searchOpt.UpdatedAfterUnix = &since | |||||
searchOpt.UpdatedAfterUnix = optional.Some(since) | |||||
} | } | ||||
if before != 0 { | if before != 0 { | ||||
searchOpt.UpdatedBeforeUnix = &before | |||||
searchOpt.UpdatedBeforeUnix = optional.Some(before) | |||||
} | } | ||||
if len(labelIDs) == 1 && labelIDs[0] == 0 { | if len(labelIDs) == 1 && labelIDs[0] == 0 { | ||||
searchOpt.NoLabelOnly = true | searchOpt.NoLabelOnly = true | ||||
} | } | ||||
if createdByID > 0 { | if createdByID > 0 { | ||||
searchOpt.PosterID = &createdByID | |||||
searchOpt.PosterID = optional.Some(createdByID) | |||||
} | } | ||||
if assignedByID > 0 { | if assignedByID > 0 { | ||||
searchOpt.AssigneeID = &assignedByID | |||||
searchOpt.AssigneeID = optional.Some(assignedByID) | |||||
} | } | ||||
if mentionedByID > 0 { | if mentionedByID > 0 { | ||||
searchOpt.MentionID = &mentionedByID | |||||
searchOpt.MentionID = optional.Some(mentionedByID) | |||||
} | } | ||||
ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) | ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) |
} | } | ||||
} | } | ||||
var projectID *int64 | |||||
projectID := optional.None[int64]() | |||||
if v := ctx.FormInt64("project"); v > 0 { | if v := ctx.FormInt64("project"); v > 0 { | ||||
projectID = &v | |||||
projectID = optional.Some(v) | |||||
} | } | ||||
// this api is also used in UI, | // this api is also used in UI, | ||||
} | } | ||||
if since != 0 { | if since != 0 { | ||||
searchOpt.UpdatedAfterUnix = &since | |||||
searchOpt.UpdatedAfterUnix = optional.Some(since) | |||||
} | } | ||||
if before != 0 { | if before != 0 { | ||||
searchOpt.UpdatedBeforeUnix = &before | |||||
searchOpt.UpdatedBeforeUnix = optional.Some(before) | |||||
} | } | ||||
if ctx.IsSigned { | if ctx.IsSigned { | ||||
ctxUserID := ctx.Doer.ID | ctxUserID := ctx.Doer.ID | ||||
if ctx.FormBool("created") { | if ctx.FormBool("created") { | ||||
searchOpt.PosterID = &ctxUserID | |||||
searchOpt.PosterID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("assigned") { | if ctx.FormBool("assigned") { | ||||
searchOpt.AssigneeID = &ctxUserID | |||||
searchOpt.AssigneeID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("mentioned") { | if ctx.FormBool("mentioned") { | ||||
searchOpt.MentionID = &ctxUserID | |||||
searchOpt.MentionID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("review_requested") { | if ctx.FormBool("review_requested") { | ||||
searchOpt.ReviewRequestedID = &ctxUserID | |||||
searchOpt.ReviewRequestedID = optional.Some(ctxUserID) | |||||
} | } | ||||
if ctx.FormBool("reviewed") { | if ctx.FormBool("reviewed") { | ||||
searchOpt.ReviewedID = &ctxUserID | |||||
searchOpt.ReviewedID = optional.Some(ctxUserID) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
var projectID *int64 | |||||
projectID := optional.None[int64]() | |||||
if v := ctx.FormInt64("project"); v > 0 { | if v := ctx.FormInt64("project"); v > 0 { | ||||
projectID = &v | |||||
projectID = optional.Some(v) | |||||
} | } | ||||
isPull := optional.None[bool]() | isPull := optional.None[bool]() | ||||
SortBy: issue_indexer.SortByCreatedDesc, | SortBy: issue_indexer.SortByCreatedDesc, | ||||
} | } | ||||
if since != 0 { | if since != 0 { | ||||
searchOpt.UpdatedAfterUnix = &since | |||||
searchOpt.UpdatedAfterUnix = optional.Some(since) | |||||
} | } | ||||
if before != 0 { | if before != 0 { | ||||
searchOpt.UpdatedBeforeUnix = &before | |||||
searchOpt.UpdatedBeforeUnix = optional.Some(before) | |||||
} | } | ||||
if len(labelIDs) == 1 && labelIDs[0] == 0 { | if len(labelIDs) == 1 && labelIDs[0] == 0 { | ||||
searchOpt.NoLabelOnly = true | searchOpt.NoLabelOnly = true | ||||
} | } | ||||
if createdByID > 0 { | if createdByID > 0 { | ||||
searchOpt.PosterID = &createdByID | |||||
searchOpt.PosterID = optional.Some(createdByID) | |||||
} | } | ||||
if assignedByID > 0 { | if assignedByID > 0 { | ||||
searchOpt.AssigneeID = &assignedByID | |||||
searchOpt.AssigneeID = optional.Some(assignedByID) | |||||
} | } | ||||
if mentionedByID > 0 { | if mentionedByID > 0 { | ||||
searchOpt.MentionID = &mentionedByID | |||||
searchOpt.MentionID = optional.Some(mentionedByID) | |||||
} | } | ||||
ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) | ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) |
case issues_model.FilterModeYourRepositories: | case issues_model.FilterModeYourRepositories: | ||||
openClosedOpts.AllPublic = false | openClosedOpts.AllPublic = false | ||||
case issues_model.FilterModeAssign: | case issues_model.FilterModeAssign: | ||||
openClosedOpts.AssigneeID = &doerID | |||||
openClosedOpts.AssigneeID = optional.Some(doerID) | |||||
case issues_model.FilterModeCreate: | case issues_model.FilterModeCreate: | ||||
openClosedOpts.PosterID = &doerID | |||||
openClosedOpts.PosterID = optional.Some(doerID) | |||||
case issues_model.FilterModeMention: | case issues_model.FilterModeMention: | ||||
openClosedOpts.MentionID = &doerID | |||||
openClosedOpts.MentionID = optional.Some(doerID) | |||||
case issues_model.FilterModeReviewRequested: | case issues_model.FilterModeReviewRequested: | ||||
openClosedOpts.ReviewRequestedID = &doerID | |||||
openClosedOpts.ReviewRequestedID = optional.Some(doerID) | |||||
case issues_model.FilterModeReviewed: | case issues_model.FilterModeReviewed: | ||||
openClosedOpts.ReviewedID = &doerID | |||||
openClosedOpts.ReviewedID = optional.Some(doerID) | |||||
} | } | ||||
openClosedOpts.IsClosed = optional.Some(false) | openClosedOpts.IsClosed = optional.Some(false) | ||||
ret.OpenCount, err = issue_indexer.CountIssues(ctx, openClosedOpts) | ret.OpenCount, err = issue_indexer.CountIssues(ctx, openClosedOpts) | ||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = &doerID })) | |||||
ret.AssignCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.AssigneeID = optional.Some(doerID) })) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = &doerID })) | |||||
ret.CreateCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.PosterID = optional.Some(doerID) })) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
ret.MentionCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.MentionID = &doerID })) | |||||
ret.MentionCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.MentionID = optional.Some(doerID) })) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
ret.ReviewRequestedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewRequestedID = &doerID })) | |||||
ret.ReviewRequestedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewRequestedID = optional.Some(doerID) })) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
ret.ReviewedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewedID = &doerID })) | |||||
ret.ReviewedCount, err = issue_indexer.CountIssues(ctx, opts.Copy(func(o *issue_indexer.SearchOptions) { o.ReviewedID = optional.Some(doerID) })) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } |