From 734aa965088fb72330f4ad744c187c614cce3d8b Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 25 Jul 2019 11:55:06 +0100 Subject: [PATCH] Fix #7136: Add paging and extend API GetCommitStatuses (#7141) * Fix #7136: Add paging and extend API GetCommitStatuses * update swagger * Update routers/api/v1/repo/status.go Co-Authored-By: techknowlogick * Update routers/api/v1/repo/status.go Co-Authored-By: techknowlogick * Update routers/api/v1/repo/status.go Co-Authored-By: techknowlogick * Apply suggestions from code review --- models/commit_status.go | 55 ++++++++++++++++++++++++++++++++-- models/commit_status_test.go | 3 +- routers/api/v1/repo/status.go | 51 +++++++++++++++++++++++++++---- templates/swagger/v1_json.tmpl | 38 +++++++++++++++++++++++ 4 files changed, 138 insertions(+), 9 deletions(-) diff --git a/models/commit_status.go b/models/commit_status.go index 74a2756303..ecd319c5fe 100644 --- a/models/commit_status.go +++ b/models/commit_status.go @@ -14,6 +14,8 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + + "github.com/go-xorm/xorm" ) // CommitStatusState holds the state of a Status @@ -132,10 +134,57 @@ func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus { return lastStatus } +// CommitStatusOptions holds the options for query commit statuses +type CommitStatusOptions struct { + Page int + State string + SortType string +} + // GetCommitStatuses returns all statuses for a given commit. -func GetCommitStatuses(repo *Repository, sha string, page int) ([]*CommitStatus, error) { - statuses := make([]*CommitStatus, 0, 10) - return statuses, x.Limit(10, page*10).Where("repo_id = ?", repo.ID).And("sha = ?", sha).Find(&statuses) +func GetCommitStatuses(repo *Repository, sha string, opts *CommitStatusOptions) ([]*CommitStatus, int64, error) { + if opts.Page <= 0 { + opts.Page = 1 + } + + countSession := listCommitStatusesStatement(repo, sha, opts) + maxResults, err := countSession.Count(new(CommitStatus)) + if err != nil { + log.Error("Count PRs: %v", err) + return nil, maxResults, err + } + + statuses := make([]*CommitStatus, 0, ItemsPerPage) + findSession := listCommitStatusesStatement(repo, sha, opts) + sortCommitStatusesSession(findSession, opts.SortType) + findSession.Limit(ItemsPerPage, (opts.Page-1)*ItemsPerPage) + return statuses, maxResults, findSession.Find(&statuses) +} + +func listCommitStatusesStatement(repo *Repository, sha string, opts *CommitStatusOptions) *xorm.Session { + sess := x.Where("repo_id = ?", repo.ID).And("sha = ?", sha) + switch opts.State { + case "pending", "success", "error", "failure", "warning": + sess.And("state = ?", opts.State) + } + return sess +} + +func sortCommitStatusesSession(sess *xorm.Session, sortType string) { + switch sortType { + case "oldest": + sess.Asc("created_unix") + case "recentupdate": + sess.Desc("updated_unix") + case "leastupdate": + sess.Asc("updated_unix") + case "leastindex": + sess.Desc("index") + case "highestindex": + sess.Asc("index") + default: + sess.Desc("created_unix") + } } // GetLatestCommitStatus returns all statuses with a unique context for a given commit. diff --git a/models/commit_status_test.go b/models/commit_status_test.go index 78d2370f9d..580db127f6 100644 --- a/models/commit_status_test.go +++ b/models/commit_status_test.go @@ -17,8 +17,9 @@ func TestGetCommitStatuses(t *testing.T) { sha1 := "1234123412341234123412341234123412341234" - statuses, err := GetCommitStatuses(repo1, sha1, 0) + statuses, maxResults, err := GetCommitStatuses(repo1, sha1, &CommitStatusOptions{}) assert.NoError(t, err) + assert.Equal(t, int(maxResults), 5) if assert.Len(t, statuses, 5) { assert.Equal(t, statuses[0].Context, "ci/awesomeness") assert.Equal(t, statuses[0].State, CommitStatusPending) diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 1aa4f4e1a1..e4afb599ee 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -89,6 +89,23 @@ func GetCommitStatuses(ctx *context.APIContext) { // description: sha of the commit // type: string // required: true + // - name: page + // in: query + // description: page number of results + // type: integer + // required: false + // - name: sort + // in: query + // description: type of sort + // type: string + // enum: [oldest, recentupdate, leastupdate, leastindex, highestindex] + // required: false + // - name: state + // in: query + // description: type of state + // type: string + // enum: [pending, success, error, failure, warning] + // required: false // responses: // "200": // "$ref": "#/responses/StatusList" @@ -118,6 +135,23 @@ func GetCommitStatusesByRef(ctx *context.APIContext) { // description: name of branch/tag/commit // type: string // required: true + // - name: page + // in: query + // description: page number of results + // type: integer + // required: false + // - name: sort + // in: query + // description: type of sort + // type: string + // enum: [oldest, recentupdate, leastupdate, leastindex, highestindex] + // required: false + // - name: state + // in: query + // description: type of state + // type: string + // enum: [pending, success, error, failure, warning] + // required: false // responses: // "200": // "$ref": "#/responses/StatusList" @@ -131,11 +165,13 @@ func getCommitStatuses(ctx *context.APIContext, sha string) { } repo := ctx.Repo.Repository - page := ctx.ParamsInt("page") - - statuses, err := models.GetCommitStatuses(repo, sha, page) + statuses, _, err := models.GetCommitStatuses(repo, sha, &models.CommitStatusOptions{ + Page: ctx.QueryInt("page"), + SortType: ctx.QueryTrim("sort"), + State: ctx.QueryTrim("state"), + }) if err != nil { - ctx.Error(500, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %v", repo.FullName(), sha, page, err)) + ctx.Error(500, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %v", repo.FullName(), sha, ctx.QueryInt("page"), err)) return } @@ -180,6 +216,11 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) { // description: name of branch/tag/commit // type: string // required: true + // - name: page + // in: query + // description: page number of results + // type: integer + // required: false // responses: // "200": // "$ref": "#/responses/Status" @@ -190,7 +231,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) { } repo := ctx.Repo.Repository - page := ctx.ParamsInt("page") + page := ctx.QueryInt("page") statuses, err := models.GetLatestCommitStatus(repo, sha, page) if err != nil { diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index e56fa61eed..43eca15871 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -1561,6 +1561,12 @@ "name": "ref", "in": "path", "required": true + }, + { + "type": "integer", + "description": "page number of results", + "name": "page", + "in": "query" } ], "responses": { @@ -5057,6 +5063,38 @@ "name": "sha", "in": "path", "required": true + }, + { + "type": "integer", + "description": "page number of results", + "name": "page", + "in": "query" + }, + { + "enum": [ + "oldest", + "recentupdate", + "leastupdate", + "leastindex", + "highestindex" + ], + "type": "string", + "description": "type of sort", + "name": "sort", + "in": "query" + }, + { + "enum": [ + "pending", + "success", + "error", + "failure", + "warning" + ], + "type": "string", + "description": "type of state", + "name": "state", + "in": "query" } ], "responses": {