diff --git a/server/datastore/commit.go b/server/datastore/commit.go index 8a21a961..f544db27 100644 --- a/server/datastore/commit.go +++ b/server/datastore/commit.go @@ -21,7 +21,7 @@ type Commitstore interface { // GetCommitList retrieves a list of latest commits // 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 // from the datastore accessible to the specified user. @@ -29,7 +29,7 @@ type Commitstore interface { // GetCommitListActivity retrieves an ungrouped list of latest commits // 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 // 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 // from the datastore for the specified repository. -func GetCommitList(c context.Context, repo *model.Repo) ([]*model.Commit, error) { - return FromContext(c).GetCommitList(repo) +func GetCommitList(c context.Context, repo *model.Repo, limit, offset int) ([]*model.Commit, error) { + return FromContext(c).GetCommitList(repo, limit, offset) } // 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 // from the datastore accessible to the specified user. -func GetCommitListActivity(c context.Context, user *model.User) ([]*model.CommitRepo, error) { - return FromContext(c).GetCommitListActivity(user) +func GetCommitListActivity(c context.Context, user *model.User, limit, offset int) ([]*model.CommitRepo, error) { + return FromContext(c).GetCommitListActivity(user, limit, offset) } // GetCommitPrior retrieves the latest commit diff --git a/server/datastore/database/commit.go b/server/datastore/database/commit.go index d36e02ae..a779622c 100644 --- a/server/datastore/database/commit.go +++ b/server/datastore/database/commit.go @@ -43,9 +43,9 @@ func (db *Commitstore) GetCommitLast(repo *model.Repo, branch string) (*model.Co // GetCommitList retrieves a list of latest commits // 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 err = meddler.QueryAll(db, &commits, rebind(commitListQuery), repo.ID) + var err = meddler.QueryAll(db, &commits, rebind(commitListQuery), repo.ID, limit, offset) return commits, err } @@ -59,9 +59,9 @@ func (db *Commitstore) GetCommitListUser(user *model.User) ([]*model.CommitRepo, // GetCommitListActivity retrieves an ungrouped list of latest commits // 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 err = meddler.QueryAll(db, &commits, rebind(commitListActivityQuery), user.ID) + var err = meddler.QueryAll(db, &commits, rebind(commitListActivityQuery), user.ID, limit, offset) return commits, err } @@ -160,7 +160,7 @@ WHERE c.repo_id = r.repo_id AND r.repo_id = p.repo_id AND p.user_id = ? ORDER BY c.commit_created DESC -LIMIT 20 +LIMIT ? OFFSET ? ` // SQL query to retrieve the latest Commits across all branches. @@ -169,7 +169,7 @@ SELECT * FROM commits WHERE repo_id = ? ORDER BY commit_id DESC -LIMIT 20 +LIMIT ? OFFSET ? ` // SQL query to retrieve a Commit by branch and sha. diff --git a/server/datastore/database/commit_test.go b/server/datastore/database/commit_test.go index 8591e18e..3b9501d4 100644 --- a/server/datastore/database/commit_test.go +++ b/server/datastore/database/commit_test.go @@ -175,7 +175,7 @@ func TestCommitstore(t *testing.T) { } cs.PutCommit(&commit1) 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(len(commits)).Equal(2) 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.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() { repo1 := model.Repo{ UserID: 1, @@ -268,13 +292,69 @@ func TestCommitstore(t *testing.T) { g.Assert(commits[1].Sha).Equal(commit4.Sha) 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(err) g.Assert(err == nil).IsTrue() 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() { commit1 := model.Commit{ RepoID: 1, diff --git a/server/handler/badge.go b/server/handler/badge.go index 3dcd6229..cf98eb6e 100644 --- a/server/handler/badge.go +++ b/server/handler/badge.go @@ -120,7 +120,7 @@ func GetCC(c web.C, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) return } - commits, err := datastore.GetCommitList(ctx, repo) + commits, err := datastore.GetCommitList(ctx, repo, 1, 0) if err != nil || len(commits) == 0 { w.WriteHeader(http.StatusNotFound) return diff --git a/server/handler/commit.go b/server/handler/commit.go index d0c341c0..1b512784 100644 --- a/server/handler/commit.go +++ b/server/handler/commit.go @@ -16,13 +16,15 @@ import ( // GetCommitList accepts a request to retrieve a list // 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) { var ctx = context.FromC(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 { w.WriteHeader(http.StatusNotFound) return diff --git a/server/handler/context.go b/server/handler/context.go index ac36ef6e..bee9f91b 100644 --- a/server/handler/context.go +++ b/server/handler/context.go @@ -1,6 +1,9 @@ package handler import ( + "net/http" + "strconv" + "github.com/drone/drone/shared/model" "github.com/zenazn/goji/web" ) @@ -49,3 +52,39 @@ func ToRole(c web.C) *model.Perm { } 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 +} diff --git a/server/handler/user.go b/server/handler/user.go index 85e86127..efd2ef06 100644 --- a/server/handler/user.go +++ b/server/handler/user.go @@ -118,16 +118,18 @@ func GetUserFeed(c web.C, w http.ResponseWriter, r *http.Request) { // build activity, across all repositories, from the datastore. // 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) { var ctx = context.FromC(c) + var limit = ToLimit(r) + var offset = ToOffset(r) var user = ToUser(c) if user == nil { w.WriteHeader(http.StatusUnauthorized) return } - repos, err := datastore.GetCommitListActivity(ctx, user) + repos, err := datastore.GetCommitListActivity(ctx, user, limit, offset) if err != nil { w.WriteHeader(http.StatusNotFound) return