Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed count of filtered issues when api request. #12275

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
208cc08
Improved total count of issue when filtered.
hinoshiba Jul 19, 2020
19dd577
Fixed size of slice when selected 1 repository.
hinoshiba Jul 19, 2020
bd69a4b
Improved function of error check.
hinoshiba Jul 19, 2020
da583f7
improved comment
hinoshiba Jul 19, 2020
8d0a2de
Added parameter of return header.
hinoshiba Jul 20, 2020
3f09965
Updated corresponded to the current vendored of "xorm.io/xorm".
hinoshiba Jul 20, 2020
b4e1f3a
Merge branch 'fixed_count_of_filteredIssues' of github.com:hinoshiba/…
hinoshiba Jul 20, 2020
0211cb5
Dedublicated it by store the Options Struct into a variable.
hinoshiba Jul 20, 2020
bc8cc31
format code
6543 Jul 22, 2020
7a6de11
Merge pull request #1 from 6543-forks/fixed_count_of_filteredIssues_f…
hinoshiba Jul 23, 2020
1507022
Update routers/api/v1/repo/issue.go
hinoshiba Jul 23, 2020
bf89ea7
Update routers/api/v1/repo/issue.go
hinoshiba Jul 23, 2020
82d00de
Updated number of range.
hinoshiba Jul 23, 2020
2d36293
Updated number of range.
hinoshiba Jul 23, 2020
0c3a9d3
Removed total value.
hinoshiba Jul 23, 2020
07d0225
make fmt
hinoshiba Jul 23, 2020
fec7657
Merge branch 'master' into fixed_count_of_filteredIssues
hinoshiba Sep 1, 2020
8335b42
Improved value of sql.
hinoshiba Sep 16, 2020
07f1f8a
Improved value of sql.
hinoshiba Sep 16, 2020
15b7cb2
improved message
hinoshiba Sep 16, 2020
dfc545e
improved message
hinoshiba Sep 16, 2020
46c61e4
improved message
hinoshiba Sep 16, 2020
dc15e1f
fixed message
hinoshiba Sep 16, 2020
ad9cc37
Merge branch 'master' into fixed_count_of_filteredIssues
hinoshiba Sep 16, 2020
dcd08d0
Merge branch 'master' into fixed_count_of_filteredIssues
techknowlogick Sep 24, 2020
630f842
Merge branch 'master' into fixed_count_of_filteredIssues
techknowlogick Sep 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
opts.setupSession(sess)
sortIssuesSession(sess, opts.SortType, opts.PriorityRepoID)

issues := make([]*Issue, 0, setting.UI.IssuePagingNum)
issues := make([]*Issue, 0, opts.ListOptions.PageSize)
if err := sess.Find(&issues); err != nil {
return nil, fmt.Errorf("Find: %v", err)
}
Expand All @@ -1279,6 +1279,27 @@ func Issues(opts *IssuesOptions) ([]*Issue, error) {
return issues, nil
}

// CountIssues number return of issues by given conditions.
func CountIssues(opts *IssuesOptions) (int64, error) {
sess := x.NewSession()
defer sess.Close()

countsSlice := make([]*struct {
RepoID int64
Count int64
}, 0, 1)

sess.Select("COUNT(issue.id) AS count").Table("issue")
opts.setupSession(sess)
if err := sess.Find(&countsSlice); err != nil {
return 0, fmt.Errorf("Find: %v", err)
}
if len(countsSlice) < 1 {
return 0, fmt.Errorf("there is less than one result sql record")
}
return countsSlice[0].Count, nil
}

// GetParticipantsIDsByIssueID returns the IDs of all users who participated in comments of an issue,
// but skips joining with `user` for performance reasons.
// User permissions must be verified elsewhere if required.
Expand Down
70 changes: 42 additions & 28 deletions routers/api/v1/repo/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ func SearchIssues(ctx *context.APIContext) {
opts.AllLimited = true
}

issueCount := 0
for page := 1; ; page++ {
opts.Page = page
repos, count, err := models.SearchRepositoryByName(opts)
Expand All @@ -107,19 +106,12 @@ func SearchIssues(ctx *context.APIContext) {
}
log.Trace("Processing next %d repos of %d", len(repos), count)
for _, repo := range repos {
switch isClosed {
zeripath marked this conversation as resolved.
Show resolved Hide resolved
case util.OptionalBoolTrue:
issueCount += repo.NumClosedIssues
case util.OptionalBoolFalse:
issueCount += repo.NumOpenIssues
case util.OptionalBoolNone:
issueCount += repo.NumIssues
}
repoIDs = append(repoIDs, repo.ID)
}
}

var issues []*models.Issue
var filteredCount int64

keyword := strings.Trim(ctx.Query("q"), " ")
if strings.IndexByte(keyword, 0) >= 0 {
Expand All @@ -129,7 +121,10 @@ func SearchIssues(ctx *context.APIContext) {
var labelIDs []int64
var err error
if len(keyword) > 0 && len(repoIDs) > 0 {
issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword)
if issueIDs, err = issue_indexer.SearchIssuesByKeyword(repoIDs, keyword); err != nil {
ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err)
return
}
}

var isPull util.OptionalBool
Expand All @@ -151,29 +146,36 @@ func SearchIssues(ctx *context.APIContext) {
// 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.
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
issues, err = models.Issues(&models.IssuesOptions{
issuesOpt := &models.IssuesOptions{
ListOptions: models.ListOptions{
Page: ctx.QueryInt("page"),
PageSize: setting.UI.IssuePagingNum,
},

RepoIDs: repoIDs,
IsClosed: isClosed,
IssueIDs: issueIDs,
IncludedLabelNames: includedLabelNames,
SortType: "priorityrepo",
PriorityRepoID: ctx.QueryInt64("priority_repo_id"),
IsPull: isPull,
})
}
}

if err != nil {
ctx.Error(http.StatusInternalServerError, "Issues", err)
return
if issues, err = models.Issues(issuesOpt); err != nil {
ctx.Error(http.StatusInternalServerError, "Issues", err)
return
}

issuesOpt.ListOptions = models.ListOptions{
zeripath marked this conversation as resolved.
Show resolved Hide resolved
Page: -1,
}
if filteredCount, err = models.CountIssues(issuesOpt); err != nil {
ctx.Error(http.StatusInternalServerError, "CountIssues", err)
return
}
}

ctx.SetLinkHeader(issueCount, setting.UI.IssuePagingNum)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", issueCount))
ctx.SetLinkHeader(int(filteredCount), setting.UI.IssuePagingNum)
hinoshiba marked this conversation as resolved.
Show resolved Hide resolved
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", filteredCount))
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link")
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
}
Expand Down Expand Up @@ -241,6 +243,7 @@ func ListIssues(ctx *context.APIContext) {
}

var issues []*models.Issue
var filteredCount int64

keyword := strings.Trim(ctx.Query("q"), " ")
if strings.IndexByte(keyword, 0) >= 0 {
Expand All @@ -251,6 +254,10 @@ func ListIssues(ctx *context.APIContext) {
var err error
if len(keyword) > 0 {
issueIDs, err = issue_indexer.SearchIssuesByKeyword([]int64{ctx.Repo.Repository.ID}, keyword)
if err != nil {
ctx.Error(http.StatusInternalServerError, "SearchIssuesByKeyword", err)
return
}
}

if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 {
Expand Down Expand Up @@ -306,26 +313,33 @@ func ListIssues(ctx *context.APIContext) {
// 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.
if len(keyword) == 0 || len(issueIDs) > 0 || len(labelIDs) > 0 {
issues, err = models.Issues(&models.IssuesOptions{
issuesOpt := &models.IssuesOptions{
ListOptions: listOptions,
RepoIDs: []int64{ctx.Repo.Repository.ID},
IsClosed: isClosed,
IssueIDs: issueIDs,
LabelIDs: labelIDs,
MilestoneIDs: mileIDs,
IsPull: isPull,
})
}
}

if err != nil {
ctx.Error(http.StatusInternalServerError, "Issues", err)
return
if issues, err = models.Issues(issuesOpt); err != nil {
ctx.Error(http.StatusInternalServerError, "Issues", err)
return
}

issuesOpt.ListOptions = models.ListOptions{
hinoshiba marked this conversation as resolved.
Show resolved Hide resolved
Page: -1,
}
if filteredCount, err = models.CountIssues(issuesOpt); err != nil {
ctx.Error(http.StatusInternalServerError, "CountIssues", err)
return
}
}

ctx.SetLinkHeader(ctx.Repo.Repository.NumIssues, listOptions.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", ctx.Repo.Repository.NumIssues))
ctx.SetLinkHeader(int(filteredCount), listOptions.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", filteredCount))
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link")

ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
}

Expand Down