re-enabled build feed

This commit is contained in:
Brad Rydzewski 2015-10-21 16:39:43 -07:00
parent 45ee7853d0
commit 2f071bb2cf
8 changed files with 148 additions and 68 deletions

View file

@ -30,7 +30,7 @@ gen_template:
go generate github.com/drone/drone/template
gen_migrations:
go generate github.com/drone/drone/shared/database
go generate github.com/drone/drone/store/migration
build:
go build

View file

@ -18,12 +18,28 @@ func GetSelf(c *gin.Context) {
func GetFeed(c *gin.Context) {
user := session.User(c)
feed, err := store.GetUserFeed(c, user, 25, 0)
remote := remote.FromContext(c)
var repos []*model.RepoLite
// get the repository list from the cache
reposv, ok := c.Get("repos")
if ok {
repos = reposv.([]*model.RepoLite)
} else {
var err error
repos, err = remote.Repos(user)
if err != nil {
c.String(400, err.Error())
return
}
}
feed, err := store.GetUserFeed(c, repos)
if err != nil {
c.AbortWithStatus(http.StatusInternalServerError)
c.String(400, err.Error())
return
}
c.IndentedJSON(http.StatusOK, feed)
c.JSON(200, feed)
}
func GetRepos(c *gin.Context) {

View file

@ -62,7 +62,7 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
{
user.Use(session.MustUser())
user.GET("", controller.GetSelf)
// user.GET("/builds", controller.GetFeed)
user.GET("/feed", controller.GetFeed)
user.GET("/repos", cache.Repos, controller.GetRepos)
user.GET("/repos/remote", cache.Repos, controller.GetRemoteRepos)
user.POST("/token", controller.PostToken)

View file

@ -2,7 +2,7 @@ package datastore
import (
"database/sql"
"strings"
"fmt"
"github.com/drone/drone/model"
"github.com/russross/meddler"
@ -25,20 +25,18 @@ func (db *repostore) GetName(name string) (*model.Repo, error) {
}
func (db *repostore) GetListOf(listof []*model.RepoLite) ([]*model.Repo, error) {
var repos = []*model.Repo{}
var size = len(listof)
if size > 999 {
size = 999
listof = listof[:999]
var (
repos []*model.Repo
args []interface{}
stmt string
)
switch meddler.Default {
case meddler.PostgreSQL:
stmt, args = toListPosgres(listof)
default:
stmt, args = toList(listof)
}
var qs = make([]string, size, size)
var in = make([]interface{}, size, size)
for i, repo := range listof {
qs[i] = "?"
in[i] = repo.FullName
}
var stmt = "SELECT * FROM repos WHERE repo_full_name IN (" + strings.Join(qs, ",") + ") ORDER BY repo_name"
var err = meddler.QueryAll(db, &repos, rebind(stmt), in...)
err := meddler.QueryAll(db, &repos, fmt.Sprintf(repoListOfQuery, stmt), args...)
return repos, err
}
@ -81,6 +79,13 @@ WHERE repo_id IN (
ORDER BY repo_full_name
`
const repoListOfQuery = `
SELECT *
FROM repos
WHERE repo_full_name IN (" + stmt + ")
ORDER BY repo_name
`
const repoCountQuery = `
SELECT COUNT(*) FROM repos
`

View file

@ -2,6 +2,7 @@ package datastore
import (
"database/sql"
"fmt"
"github.com/drone/drone/model"
"github.com/russross/meddler"
@ -29,11 +30,20 @@ func (db *userstore) GetList() ([]*model.User, error) {
return users, err
}
func (db *userstore) GetFeed(user *model.User, limit, offset int) ([]*model.Feed, error) {
// var feed = []*Feed{}
// var err = meddler.QueryAll(db, &feed, rebind(userFeedQuery), user.Login, limit, offset)
// return feed, err
return nil, nil
func (db *userstore) GetFeed(listof []*model.RepoLite) ([]*model.Feed, error) {
var (
feed []*model.Feed
args []interface{}
stmt string
)
switch meddler.Default {
case meddler.PostgreSQL:
stmt, args = toListPosgres(listof)
default:
stmt, args = toList(listof)
}
err := meddler.QueryAll(db, &feed, fmt.Sprintf(userFeedQuery, stmt), args...)
return feed, err
}
func (db *userstore) Count() (int, error) {
@ -105,7 +115,7 @@ FROM
builds b
,repos r
WHERE b.build_repo_id = r.repo_id
AND b.build_author = ?
AND r.repo_full_name IN (%s)
ORDER BY b.build_id DESC
LIMIT ? OFFSET ?
LIMIT 25
`

View file

@ -164,46 +164,59 @@ func Test_userstore(t *testing.T) {
g.Assert(err3 == nil).IsFalse()
})
// g.It("Should get the Build feed for a User", func() {
// repo1 := &Repo{
// UserID: 1,
// Owner: "bradrydzewski",
// Name: "drone",
// FullName: "bradrydzewski/drone",
// }
// repo2 := &Repo{
// UserID: 2,
// Owner: "drone",
// Name: "drone",
// FullName: "drone/drone",
// }
// CreateRepo(db, repo1)
// CreateRepo(db, repo2)
g.It("Should get the Build feed for a User", func() {
repo1 := &model.Repo{
UserID: 1,
Owner: "bradrydzewski",
Name: "drone",
FullName: "bradrydzewski/drone",
}
repo2 := &model.Repo{
UserID: 2,
Owner: "drone",
Name: "drone",
FullName: "drone/drone",
}
repo3 := &model.Repo{
UserID: 2,
Owner: "octocat",
Name: "hello-world",
FullName: "octocat/hello-world",
}
s.Repos().Create(repo1)
s.Repos().Create(repo2)
s.Repos().Create(repo3)
// build1 := &Build{
// RepoID: repo1.ID,
// Status: StatusFailure,
// Author: "bradrydzewski",
// }
// build2 := &Build{
// RepoID: repo1.ID,
// Status: StatusSuccess,
// Author: "bradrydzewski",
// }
// build3 := &Build{
// RepoID: repo2.ID,
// Status: StatusSuccess,
// Author: "octocat",
// }
// CreateBuild(db, build1)
// CreateBuild(db, build2)
// CreateBuild(db, build3)
build1 := &model.Build{
RepoID: repo1.ID,
Status: model.StatusFailure,
}
build2 := &model.Build{
RepoID: repo1.ID,
Status: model.StatusSuccess,
}
build3 := &model.Build{
RepoID: repo2.ID,
Status: model.StatusSuccess,
}
build4 := &model.Build{
RepoID: repo3.ID,
Status: model.StatusSuccess,
}
s.Builds().Create(build1)
s.Builds().Create(build2)
s.Builds().Create(build3)
s.Builds().Create(build4)
// builds, err := GetUserFeed(db, &User{ID: 1, Login: "bradrydzewski"}, 20, 0)
// g.Assert(err == nil).IsTrue()
// g.Assert(len(builds)).Equal(2)
// g.Assert(builds[0].Owner).Equal("bradrydzewski")
// g.Assert(builds[0].Name).Equal("drone")
// })
builds, err := s.Users().GetFeed([]*model.RepoLite{
{FullName: "bradrydzewski/drone"},
{FullName: "drone/drone"},
})
g.Assert(err == nil).IsTrue()
g.Assert(len(builds)).Equal(3)
g.Assert(builds[0].FullName).Equal(repo2.FullName)
g.Assert(builds[1].FullName).Equal(repo1.FullName)
g.Assert(builds[2].FullName).Equal(repo1.FullName)
})
})
}

View file

@ -2,7 +2,9 @@ package datastore
import (
"strconv"
"strings"
"github.com/drone/drone/model"
"github.com/russross/meddler"
)
@ -33,3 +35,37 @@ func rebind(query string) string {
}
return string(rqb)
}
// helper function that converts a simple repsitory list
// to a sql IN statment.
func toList(listof []*model.RepoLite) (string, []interface{}) {
var size = len(listof)
if size > 999 {
size = 999
listof = listof[:999]
}
var qs = make([]string, size, size)
var in = make([]interface{}, size, size)
for i, repo := range listof {
qs[i] = "$" + strconv.Itoa(i+1)
in[i] = repo.FullName
}
return strings.Join(qs, ","), in
}
// helper function that converts a simple repsitory list
// to a sql IN statment compatible with postgres.
func toListPosgres(listof []*model.RepoLite) (string, []interface{}) {
var size = len(listof)
if size > 999 {
size = 999
listof = listof[:999]
}
var qs = make([]string, size, size)
var in = make([]interface{}, size, size)
for i, repo := range listof {
qs[i] = "$" + strconv.Itoa(i+1)
in[i] = repo.FullName
}
return strings.Join(qs, ","), in
}

View file

@ -16,7 +16,7 @@ type UserStore interface {
GetList() ([]*model.User, error)
// GetFeed gets a user activity feed.
GetFeed(*model.User, int, int) ([]*model.Feed, error)
GetFeed([]*model.RepoLite) ([]*model.Feed, error)
// Count gets a count of all users in the system.
Count() (int, error)
@ -43,8 +43,8 @@ func GetUserList(c context.Context) ([]*model.User, error) {
return FromContext(c).Users().GetList()
}
func GetUserFeed(c context.Context, user *model.User, limit, offset int) ([]*model.Feed, error) {
return FromContext(c).Users().GetFeed(user, limit, offset)
func GetUserFeed(c context.Context, listof []*model.RepoLite) ([]*model.Feed, error) {
return FromContext(c).Users().GetFeed(listof)
}
func CountUsers(c context.Context) (int, error) {