Limit and Offset params for commits

This commit is contained in:
Kirill Zaitsev 2015-02-13 23:37:21 +03:00
parent bd8dcf8de5
commit 8d6a233744
7 changed files with 142 additions and 19 deletions

View file

@ -21,7 +21,7 @@ type Commitstore interface {
// GetCommitList retrieves a list of latest commits // GetCommitList retrieves a list of latest commits
// from the datastore for the specified repository. // from the datastore for the specified repository.
GetCommitList(repo *model.Repo) ([]*model.Commit, error) GetCommitList(repo *model.Repo, limit, offset int) ([]*model.Commit, error)
// GetCommitListUser retrieves a list of latest commits // GetCommitListUser retrieves a list of latest commits
// from the datastore accessible to the specified user. // from the datastore accessible to the specified user.
@ -29,7 +29,7 @@ type Commitstore interface {
// GetCommitListActivity retrieves an ungrouped list of latest commits // GetCommitListActivity retrieves an ungrouped list of latest commits
// from the datastore accessible to the specified user. // from the datastore accessible to the specified user.
GetCommitListActivity(user *model.User) ([]*model.CommitRepo, error) GetCommitListActivity(user *model.User, limit, offset int) ([]*model.CommitRepo, error)
// GetCommitPrior retrieves the latest commit // GetCommitPrior retrieves the latest commit
// from the datastore for the specified repository and branch. // from the datastore for the specified repository and branch.
@ -74,8 +74,8 @@ func GetCommitLast(c context.Context, repo *model.Repo, branch string) (*model.C
// GetCommitList retrieves a list of latest commits // GetCommitList retrieves a list of latest commits
// from the datastore for the specified repository. // from the datastore for the specified repository.
func GetCommitList(c context.Context, repo *model.Repo) ([]*model.Commit, error) { func GetCommitList(c context.Context, repo *model.Repo, limit, offset int) ([]*model.Commit, error) {
return FromContext(c).GetCommitList(repo) return FromContext(c).GetCommitList(repo, limit, offset)
} }
// GetCommitListUser retrieves a list of latest commits // GetCommitListUser retrieves a list of latest commits
@ -86,8 +86,8 @@ func GetCommitListUser(c context.Context, user *model.User) ([]*model.CommitRepo
// GetCommitListActivity retrieves an ungrouped list of latest commits // GetCommitListActivity retrieves an ungrouped list of latest commits
// from the datastore accessible to the specified user. // from the datastore accessible to the specified user.
func GetCommitListActivity(c context.Context, user *model.User) ([]*model.CommitRepo, error) { func GetCommitListActivity(c context.Context, user *model.User, limit, offset int) ([]*model.CommitRepo, error) {
return FromContext(c).GetCommitListActivity(user) return FromContext(c).GetCommitListActivity(user, limit, offset)
} }
// GetCommitPrior retrieves the latest commit // GetCommitPrior retrieves the latest commit

View file

@ -43,9 +43,9 @@ func (db *Commitstore) GetCommitLast(repo *model.Repo, branch string) (*model.Co
// GetCommitList retrieves a list of latest commits // GetCommitList retrieves a list of latest commits
// from the datastore for the specified repository. // from the datastore for the specified repository.
func (db *Commitstore) GetCommitList(repo *model.Repo) ([]*model.Commit, error) { func (db *Commitstore) GetCommitList(repo *model.Repo, limit, offset int) ([]*model.Commit, error) {
var commits []*model.Commit var commits []*model.Commit
var err = meddler.QueryAll(db, &commits, rebind(commitListQuery), repo.ID) var err = meddler.QueryAll(db, &commits, rebind(commitListQuery), repo.ID, limit, offset)
return commits, err return commits, err
} }
@ -59,9 +59,9 @@ func (db *Commitstore) GetCommitListUser(user *model.User) ([]*model.CommitRepo,
// GetCommitListActivity retrieves an ungrouped list of latest commits // GetCommitListActivity retrieves an ungrouped list of latest commits
// from the datastore accessible to the specified user. // from the datastore accessible to the specified user.
func (db *Commitstore) GetCommitListActivity(user *model.User) ([]*model.CommitRepo, error) { func (db *Commitstore) GetCommitListActivity(user *model.User, limit, offset int) ([]*model.CommitRepo, error) {
var commits []*model.CommitRepo var commits []*model.CommitRepo
var err = meddler.QueryAll(db, &commits, rebind(commitListActivityQuery), user.ID) var err = meddler.QueryAll(db, &commits, rebind(commitListActivityQuery), user.ID, limit, offset)
return commits, err return commits, err
} }
@ -160,7 +160,7 @@ WHERE c.repo_id = r.repo_id
AND r.repo_id = p.repo_id AND r.repo_id = p.repo_id
AND p.user_id = ? AND p.user_id = ?
ORDER BY c.commit_created DESC ORDER BY c.commit_created DESC
LIMIT 20 LIMIT ? OFFSET ?
` `
// SQL query to retrieve the latest Commits across all branches. // SQL query to retrieve the latest Commits across all branches.
@ -169,7 +169,7 @@ SELECT *
FROM commits FROM commits
WHERE repo_id = ? WHERE repo_id = ?
ORDER BY commit_id DESC ORDER BY commit_id DESC
LIMIT 20 LIMIT ? OFFSET ?
` `
// SQL query to retrieve a Commit by branch and sha. // SQL query to retrieve a Commit by branch and sha.

View file

@ -175,7 +175,7 @@ func TestCommitstore(t *testing.T) {
} }
cs.PutCommit(&commit1) cs.PutCommit(&commit1)
cs.PutCommit(&commit2) cs.PutCommit(&commit2)
commits, err := cs.GetCommitList(&model.Repo{ID: 1}) commits, err := cs.GetCommitList(&model.Repo{ID: 1}, 20, 0)
g.Assert(err == nil).IsTrue() g.Assert(err == nil).IsTrue()
g.Assert(len(commits)).Equal(2) g.Assert(len(commits)).Equal(2)
g.Assert(commits[0].ID).Equal(commit2.ID) g.Assert(commits[0].ID).Equal(commit2.ID)
@ -184,6 +184,30 @@ func TestCommitstore(t *testing.T) {
g.Assert(commits[0].Sha).Equal(commit2.Sha) g.Assert(commits[0].Sha).Equal(commit2.Sha)
}) })
g.It("Should get only one last Commit from Commit List for a Repo", func() {
commit1 := model.Commit{
RepoID: 1,
Branch: "foo",
Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac",
Status: model.StatusFailure,
}
commit2 := model.Commit{
RepoID: 1,
Branch: "foo",
Sha: "0a74b46d7d62b737b6906897f48dbeb72cfda222",
Status: model.StatusSuccess,
}
cs.PutCommit(&commit1)
cs.PutCommit(&commit2)
commits, err := cs.GetCommitList(&model.Repo{ID: 1}, 1, 1)
g.Assert(err == nil).IsTrue()
g.Assert(len(commits)).Equal(1)
g.Assert(commits[0].ID).Equal(commit1.ID)
g.Assert(commits[0].RepoID).Equal(commit1.RepoID)
g.Assert(commits[0].Branch).Equal(commit1.Branch)
g.Assert(commits[0].Sha).Equal(commit1.Sha)
})
g.It("Should get the recent Commit List for a User", func() { g.It("Should get the recent Commit List for a User", func() {
repo1 := model.Repo{ repo1 := model.Repo{
UserID: 1, UserID: 1,
@ -268,13 +292,69 @@ func TestCommitstore(t *testing.T) {
g.Assert(commits[1].Sha).Equal(commit4.Sha) g.Assert(commits[1].Sha).Equal(commit4.Sha)
g.Assert(commits[1].Status).Equal(commit4.Status) g.Assert(commits[1].Status).Equal(commit4.Status)
commits, err = cs.GetCommitListActivity(&model.User{ID: 1}) commits, err = cs.GetCommitListActivity(&model.User{ID: 1}, 20, 0)
fmt.Println(commits) fmt.Println(commits)
fmt.Println(err) fmt.Println(err)
g.Assert(err == nil).IsTrue() g.Assert(err == nil).IsTrue()
g.Assert(len(commits)).Equal(3) g.Assert(len(commits)).Equal(3)
}) })
g.It("Should get only one last Commit List for a User", func() {
repo1 := model.Repo{
UserID: 1,
Remote: "enterprise.github.com",
Host: "github.drone.io",
Owner: "bradrydzewski",
Name: "drone",
}
repo2 := model.Repo{
UserID: 1,
Remote: "enterprise.github.com",
Host: "github.drone.io",
Owner: "drone",
Name: "drone",
}
rs.PostRepo(&repo1)
rs.PostRepo(&repo2)
commit1 := model.Commit{
RepoID: repo1.ID,
Branch: "foo",
Sha: "85f8c029b902ed9400bc600bac301a0aadb144ac",
Status: model.StatusFailure,
}
commit2 := model.Commit{
RepoID: repo2.ID,
Branch: "bar",
Sha: "0a74b46d7d62b737b6906897f48dbeb72cfda222",
Status: model.StatusSuccess,
}
cs.PostCommit(&commit1)
cs.PostCommit(&commit2)
perm1 := model.Perm{
RepoID: repo1.ID,
UserID: 1,
Read: true,
Write: true,
Admin: true,
}
perm2 := model.Perm{
RepoID: repo2.ID,
UserID: 1,
Read: true,
Write: true,
Admin: true,
}
ps.PostPerm(&perm1)
ps.PostPerm(&perm2)
commits, err := cs.GetCommitListActivity(&model.User{ID: 1}, 1, 1)
g.Assert(err == nil).IsTrue()
g.Assert(len(commits)).Equal(1)
g.Assert(commits[0].RepoID).Equal(commit2.RepoID)
g.Assert(commits[0].Branch).Equal(commit2.Branch)
g.Assert(commits[0].Sha).Equal(commit2.Sha)
g.Assert(commits[0].Status).Equal(commit2.Status)
})
g.It("Should enforce unique Sha + Branch", func() { g.It("Should enforce unique Sha + Branch", func() {
commit1 := model.Commit{ commit1 := model.Commit{
RepoID: 1, RepoID: 1,

View file

@ -120,7 +120,7 @@ func GetCC(c web.C, w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
return return
} }
commits, err := datastore.GetCommitList(ctx, repo) commits, err := datastore.GetCommitList(ctx, repo, 1, 0)
if err != nil || len(commits) == 0 { if err != nil || len(commits) == 0 {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
return return

View file

@ -16,13 +16,15 @@ import (
// GetCommitList accepts a request to retrieve a list // GetCommitList accepts a request to retrieve a list
// of recent commits by Repo, and retur in JSON format. // of recent commits by Repo, and retur in JSON format.
// //
// GET /api/repos/:host/:owner/:name/commits // GET /api/repos/:host/:owner/:name/commits?limit=:limit&offset=:offset
// //
func GetCommitList(c web.C, w http.ResponseWriter, r *http.Request) { func GetCommitList(c web.C, w http.ResponseWriter, r *http.Request) {
var ctx = context.FromC(c) var ctx = context.FromC(c)
var repo = ToRepo(c) var repo = ToRepo(c)
var limit = ToLimit(r)
var offset = ToOffset(r)
commits, err := datastore.GetCommitList(ctx, repo) commits, err := datastore.GetCommitList(ctx, repo, limit, offset)
if err != nil { if err != nil {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
return return

View file

@ -1,6 +1,9 @@
package handler package handler
import ( import (
"net/http"
"strconv"
"github.com/drone/drone/shared/model" "github.com/drone/drone/shared/model"
"github.com/zenazn/goji/web" "github.com/zenazn/goji/web"
) )
@ -49,3 +52,39 @@ func ToRole(c web.C) *model.Perm {
} }
return p return p
} }
// ToLimit returns the Limit from current request
// query if limit doesn't present set default offset
// equal to 20, maximum limit equal 100
func ToLimit(r *http.Request) int {
if len(r.FormValue("limit")) == 0 {
return 20
}
limit, err := strconv.Atoi(r.FormValue("limit"))
if err != nil {
return 20
}
if limit > 100 {
return 100
}
return limit
}
// ToOffset returns the Offset from current request
// query if offset doesn't present set default offset
// equal to 0
func ToOffset(r *http.Request) int {
if len(r.FormValue("offset")) == 0 {
return 0
}
offset, err := strconv.Atoi(r.FormValue("offset"))
if err != nil {
return 0
}
return offset
}

View file

@ -118,16 +118,18 @@ func GetUserFeed(c web.C, w http.ResponseWriter, r *http.Request) {
// build activity, across all repositories, from the datastore. // build activity, across all repositories, from the datastore.
// The results are encoded and returned in JSON format. // The results are encoded and returned in JSON format.
// //
// GET /api/user/activity // GET /api/user/activity?limit=:limit&offset=:offset
// //
func GetUserActivity(c web.C, w http.ResponseWriter, r *http.Request) { func GetUserActivity(c web.C, w http.ResponseWriter, r *http.Request) {
var ctx = context.FromC(c) var ctx = context.FromC(c)
var limit = ToLimit(r)
var offset = ToOffset(r)
var user = ToUser(c) var user = ToUser(c)
if user == nil { if user == nil {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
return return
} }
repos, err := datastore.GetCommitListActivity(ctx, user) repos, err := datastore.GetCommitListActivity(ctx, user, limit, offset)
if err != nil { if err != nil {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
return return