diff --git a/model/feed.go b/model/feed.go index 56dd8d0a7..8e766e219 100644 --- a/model/feed.go +++ b/model/feed.go @@ -8,20 +8,20 @@ type Feed struct { Name string `json:"name" meddler:"repo_name"` FullName string `json:"full_name" meddler:"repo_full_name"` - Number int `json:"number" meddler:"build_number"` - Event string `json:"event" meddler:"build_event"` - Status string `json:"status" meddler:"build_status"` - Created int64 `json:"created_at" meddler:"build_created"` - Started int64 `json:"started_at" meddler:"build_started"` - Finished int64 `json:"finished_at" meddler:"build_finished"` - Commit string `json:"commit" meddler:"build_commit"` - Branch string `json:"branch" meddler:"build_branch"` - Ref string `json:"ref" meddler:"build_ref"` - Refspec string `json:"refspec" meddler:"build_refspec"` - Remote string `json:"remote" meddler:"build_remote"` - Title string `json:"title" meddler:"build_title"` - Message string `json:"message" meddler:"build_message"` - Author string `json:"author" meddler:"build_author"` - Avatar string `json:"author_avatar" meddler:"build_avatar"` - Email string `json:"author_email" meddler:"build_email"` + Number int `json:"number,omitempty" meddler:"build_number,zeroisnull"` + Event string `json:"event,omitempty" meddler:"build_event,zeroisnull"` + Status string `json:"status,omitempty" meddler:"build_status,zeroisnull"` + Created int64 `json:"created_at,omitempty" meddler:"build_created,zeroisnull"` + Started int64 `json:"started_at,omitempty" meddler:"build_started,zeroisnull"` + Finished int64 `json:"finished_at,omitempty" meddler:"build_finished,zeroisnull"` + Commit string `json:"commit,omitempty" meddler:"build_commit,zeroisnull"` + Branch string `json:"branch,omitempty" meddler:"build_branch,zeroisnull"` + Ref string `json:"ref,omitempty" meddler:"build_ref,zeroisnull"` + Refspec string `json:"refspec,omitempty" meddler:"build_refspec,zeroisnull"` + Remote string `json:"remote,omitempty" meddler:"build_remote,zeroisnull"` + Title string `json:"title,omitempty" meddler:"build_title,zeroisnull"` + Message string `json:"message,omitempty" meddler:"build_message,zeroisnull"` + Author string `json:"author,omitempty" meddler:"build_author,zeroisnull"` + Avatar string `json:"author_avatar,omitempty" meddler:"build_avatar,zeroisnull"` + Email string `json:"author_email,omitempty" meddler:"build_email,zeroisnull"` } diff --git a/server/user.go b/server/user.go index 9f4a377e3..0504b1aea 100644 --- a/server/user.go +++ b/server/user.go @@ -21,13 +21,15 @@ func GetSelf(c *gin.Context) { } func GetFeed(c *gin.Context) { + latest, _ := strconv.ParseBool(c.Query("latest")) + repos, err := cache.GetRepos(c, session.User(c)) if err != nil { c.String(500, "Error fetching repository list. %s", err) return } - feed, err := store.GetUserFeed(c, repos) + feed, err := store.GetUserFeed(c, repos, latest) if err != nil { c.String(500, "Error fetching feed. %s", err) return diff --git a/store/datastore/repos.go b/store/datastore/repos.go index 564995490..ec800338b 100644 --- a/store/datastore/repos.go +++ b/store/datastore/repos.go @@ -63,17 +63,6 @@ WHERE repo_full_name = ? LIMIT 1; ` -const repoListQuery = ` -SELECT * -FROM repos -WHERE repo_id IN ( - SELECT DISTINCT build_repo_id - FROM builds - WHERE build_author = ? -) -ORDER BY repo_full_name -` - const repoListOfQuery = ` SELECT * FROM repos diff --git a/store/datastore/users.go b/store/datastore/users.go index 9b2a68365..d448e25c5 100644 --- a/store/datastore/users.go +++ b/store/datastore/users.go @@ -41,6 +41,22 @@ func (db *datastore) GetUserFeed(listof []*model.RepoLite) ([]*model.Feed, error return feed, err } +func (db *datastore) GetUserFeedLatest(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(userFeedLatest, stmt), args...) + return feed, err +} + func (db *datastore) GetUserCount() (int, error) { var count int var err = db.QueryRow(rebind(userCountQuery)).Scan(&count) @@ -114,3 +130,36 @@ WHERE b.build_repo_id = r.repo_id ORDER BY b.build_id DESC LIMIT 50 ` + +// thanks to this article for helping me find a sane sql query +// https://www.periscopedata.com/blog/4-ways-to-join-only-the-first-row-in-sql.html + +const userFeedLatest = ` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos LEFT OUTER JOIN builds ON build_id = ( + SELECT build_id FROM builds + WHERE builds.build_repo_id = repos.repo_id + ORDER BY build_id DESC + LIMIT 1 +) +WHERE repo_full_name IN (%s) +` diff --git a/store/store.go b/store/store.go index 855544314..7c7e1de19 100644 --- a/store/store.go +++ b/store/store.go @@ -21,6 +21,10 @@ type Store interface { // GetUserFeed gets a user activity feed. GetUserFeed([]*model.RepoLite) ([]*model.Feed, error) + // GetUserFeedLatest gets a user activity feed for all repositories including + // only the latest build for each repository. + GetUserFeedLatest(listof []*model.RepoLite) ([]*model.Feed, error) + // GetUserCount gets a count of all users in the system. GetUserCount() (int, error) @@ -146,7 +150,10 @@ func GetUserList(c context.Context) ([]*model.User, error) { } // GetUserFeed gets a user activity feed. -func GetUserFeed(c context.Context, listof []*model.RepoLite) ([]*model.Feed, error) { +func GetUserFeed(c context.Context, listof []*model.RepoLite, latest bool) ([]*model.Feed, error) { + if latest { + return FromContext(c).GetUserFeedLatest(listof) + } return FromContext(c).GetUserFeed(listof) }