diff --git a/server/datastore/commit.go b/server/datastore/commit.go index a9e08609c..dd99acb08 100644 --- a/server/datastore/commit.go +++ b/server/datastore/commit.go @@ -27,6 +27,11 @@ type Commitstore interface { // from the datastore accessible to the specified user. GetCommitListUser(user *model.User) ([]*model.CommitRepo, error) + // GetCommitListUserVerbose retrieves a list of latest commits + // from the datastore accessible to the specified user and includes + // any active builds that may be running. + GetCommitListUserVerbose(user *model.User) ([]*model.CommitRepo, error) + // PostCommit saves a commit in the datastore. PostCommit(commit *model.Commit) error @@ -72,6 +77,13 @@ func GetCommitListUser(c context.Context, user *model.User) ([]*model.CommitRepo return FromContext(c).GetCommitListUser(user) } +// GetCommitListUserVerbose retrieves a list of latest commits +// from the datastore accessible to the specified user and includes +// any active builds that may be running. +func GetCommitListUserVerbose(c context.Context, user *model.User) ([]*model.CommitRepo, error) { + return FromContext(c).GetCommitListUserVerbose(user) +} + // PostCommit saves a commit in the datastore. func PostCommit(c context.Context, commit *model.Commit) error { return FromContext(c).PostCommit(commit) diff --git a/server/datastore/database/commit.go b/server/datastore/database/commit.go index 19603c97f..041f889aa 100644 --- a/server/datastore/database/commit.go +++ b/server/datastore/database/commit.go @@ -56,6 +56,15 @@ func (db *Commitstore) GetCommitListUser(user *model.User) ([]*model.CommitRepo, return commits, err } +// GetCommitListUserVerbose retrieves a list of latest commits +// from the datastore accessible to the specified user and including +// any active builds +func (db *Commitstore) GetCommitListUserVerbose(user *model.User) ([]*model.CommitRepo, error) { + var commits []*model.CommitRepo + var err = meddler.QueryAll(db, &commits, rebind(commitListUserVerboseQuery), user.ID) + return commits, err +} + // PostCommit saves a commit in the datastore. func (db *Commitstore) PostCommit(commit *model.Commit) error { if commit.Created == 0 { @@ -118,6 +127,28 @@ WHERE c.repo_id = r.repo_id ) ORDER BY c.commit_created DESC LIMIT 5; ` +// SQL query to retrieve the latest Commits accessible +// to ta specific user account. This query includes many +// results and doesn't filter out active builds. +const commitListUserVerboseQuery = ` +SELECT r.repo_remote, r.repo_host, r.repo_owner, r.repo_name, c.* +FROM + commits c +,repos r +WHERE c.repo_id = r.repo_id + AND c.commit_id IN ( + SELECT max(c.commit_id) + FROM + commits c + ,repos r + ,perms p + WHERE c.repo_id = r.repo_id + AND r.repo_id = p.repo_id + AND p.user_id = ? + GROUP BY r.repo_id +) ORDER BY c.commit_created DESC LIMIT 20; +` + // SQL query to retrieve the latest Commits across all branches. const commitListQuery = ` SELECT * diff --git a/server/datastore/database/commit_test.go b/server/datastore/database/commit_test.go index 51a04b942..8410f8e9f 100644 --- a/server/datastore/database/commit_test.go +++ b/server/datastore/database/commit_test.go @@ -228,6 +228,13 @@ func TestCommitstore(t *testing.T) { g.Assert(commits[0].RepoID).Equal(commit1.RepoID) g.Assert(commits[0].Branch).Equal(commit1.Branch) g.Assert(commits[0].Sha).Equal(commit1.Sha) + + verboseCommits, err := cs.GetCommitListUserVerbose(&model.User{ID: 1}) + g.Assert(err == nil).IsTrue() + g.Assert(len(verboseCommits)).Equal(2) + g.Assert(verboseCommits[0].RepoID).Equal(commit1.RepoID) + g.Assert(verboseCommits[0].Branch).Equal(commit1.Branch) + g.Assert(verboseCommits[0].Sha).Equal(commit1.Sha) }) g.It("Should enforce unique Sha + Branch", func() { diff --git a/server/handler/user.go b/server/handler/user.go index e5e8a7348..68a6b78d4 100644 --- a/server/handler/user.go +++ b/server/handler/user.go @@ -114,6 +114,29 @@ func GetUserFeed(c web.C, w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(&repos) } +// GetUserVerboseFeed accepts a request to get the user's latest +// build feed, across all repositories, from the datastore. It differs +// from GetUserFeed in that it returns more results and includes +// active builds. +// The results are encoded and returned in JSON format. +// +// GET /api/user/feed/verbose +// +func GetUserVerboseFeed(c web.C, w http.ResponseWriter, r *http.Request) { + var ctx = context.FromC(c) + var user = ToUser(c) + if user == nil { + w.WriteHeader(http.StatusUnauthorized) + return + } + repos, err := datastore.GetCommitListUserVerbose(ctx, user) + if err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + json.NewEncoder(w).Encode(&repos) +} + // PostUserSync accepts a request to post user sync // // POST /api/user/sync diff --git a/server/router/router.go b/server/router/router.go index 651a0146c..ef2a9db57 100644 --- a/server/router/router.go +++ b/server/router/router.go @@ -56,6 +56,7 @@ func New() *web.Mux { user := web.New() user.Use(middleware.RequireUser) + user.Get("/api/user/feed/verbose", handler.GetUserVerboseFeed) user.Get("/api/user/feed", handler.GetUserFeed) user.Get("/api/user/repos", handler.GetUserRepos) user.Post("/api/user/sync", handler.PostUserSync)