mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-01-09 17:15:31 +00:00
added helper queries for user builds
This commit is contained in:
parent
4435d7f2f6
commit
130c133b92
9 changed files with 103 additions and 39 deletions
|
@ -4,11 +4,11 @@ type Feed struct {
|
||||||
Owner string `json:"owner" meddler:"repo_owner"`
|
Owner string `json:"owner" meddler:"repo_owner"`
|
||||||
Name string `json:"name" meddler:"repo_name"`
|
Name string `json:"name" meddler:"repo_name"`
|
||||||
FullName string `json:"full_name" meddler:"repo_full_name"`
|
FullName string `json:"full_name" meddler:"repo_full_name"`
|
||||||
Avatar string `json:"avatar_url" meddler:"repo_avatar"`
|
|
||||||
|
|
||||||
Number int `json:"number" meddler:"build_number"`
|
Number int `json:"number" meddler:"build_number"`
|
||||||
Event string `json:"event" meddler:"build_event"`
|
Event string `json:"event" meddler:"build_event"`
|
||||||
Status string `json:"status" meddler:"build_status"`
|
Status string `json:"status" meddler:"build_status"`
|
||||||
|
Created int64 `json:"created_at" meddler:"build_created"`
|
||||||
Started int64 `json:"started_at" meddler:"build_started"`
|
Started int64 `json:"started_at" meddler:"build_started"`
|
||||||
Finished int64 `json:"finished_at" meddler:"build_finished"`
|
Finished int64 `json:"finished_at" meddler:"build_finished"`
|
||||||
Commit string `json:"commit" meddler:"build_commit"`
|
Commit string `json:"commit" meddler:"build_commit"`
|
||||||
|
@ -19,5 +19,6 @@ type Feed struct {
|
||||||
Title string `json:"title" meddler:"build_title"`
|
Title string `json:"title" meddler:"build_title"`
|
||||||
Message string `json:"message" meddler:"build_message"`
|
Message string `json:"message" meddler:"build_message"`
|
||||||
Author string `json:"author" meddler:"build_author"`
|
Author string `json:"author" meddler:"build_author"`
|
||||||
|
Avatar string `json:"author_avatar" meddler:"build_avatar"`
|
||||||
Email string `json:"author_email" meddler:"build_email"`
|
Email string `json:"author_email" meddler:"build_email"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package model
|
||||||
import (
|
import (
|
||||||
"github.com/drone/drone/shared/database"
|
"github.com/drone/drone/shared/database"
|
||||||
"github.com/russross/meddler"
|
"github.com/russross/meddler"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RepoLite struct {
|
type RepoLite struct {
|
||||||
|
@ -40,14 +41,35 @@ func GetRepo(db meddler.DB, id int64) (*Repo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRepoName(db meddler.DB, owner, name string) (*Repo, error) {
|
func GetRepoName(db meddler.DB, owner, name string) (*Repo, error) {
|
||||||
|
return GetRepoFullName(db, owner+"/"+name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRepoFullName(db meddler.DB, name string) (*Repo, error) {
|
||||||
var repo = new(Repo)
|
var repo = new(Repo)
|
||||||
var err = meddler.QueryRow(db, repo, database.Rebind(repoNameQuery), owner, name)
|
var err = meddler.QueryRow(db, repo, database.Rebind(repoNameQuery), name)
|
||||||
return repo, err
|
return repo, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRepoList(db meddler.DB, user *User) ([]*Repo, error) {
|
func GetRepoList(db meddler.DB, user *User) ([]*Repo, error) {
|
||||||
|
// we don't have real-time access to the intersection
|
||||||
|
// of github repos and drone repos. So we cheat by simply
|
||||||
|
// getting the distinct list of repos that the user
|
||||||
|
// has created builds for.
|
||||||
var repos = []*Repo{}
|
var repos = []*Repo{}
|
||||||
var err = meddler.QueryAll(db, &repos, database.Rebind(repoListQuery), user.ID)
|
var err = meddler.QueryAll(db, &repos, database.Rebind(repoListQuery), user.Login)
|
||||||
|
return repos, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRepoListOf(db meddler.DB, listof []string) ([]*Repo, error) {
|
||||||
|
var repos = []*Repo{}
|
||||||
|
var qs = make([]string, len(listof), len(listof))
|
||||||
|
var in = make([]interface{}, len(listof), len(listof))
|
||||||
|
for i, repo := range listof {
|
||||||
|
qs[i] = "?"
|
||||||
|
in[i] = repo
|
||||||
|
}
|
||||||
|
var stmt = "SELECT * FROM repos WHERE repo_id IN (" + strings.Join(qs, ",") + ")"
|
||||||
|
var err = meddler.QueryAll(db, &repos, database.Rebind(stmt), in...)
|
||||||
return repos, err
|
return repos, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,12 +91,11 @@ const repoTable = "repos"
|
||||||
const repoNameQuery = `
|
const repoNameQuery = `
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM repos
|
FROM repos
|
||||||
WHERE repo_owner = ?
|
WHERE repo_full_name = ?
|
||||||
AND repo_name = ?
|
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
`
|
`
|
||||||
|
|
||||||
const repoListQuery = `
|
const repoStarsQuery = `
|
||||||
SELECT r.*
|
SELECT r.*
|
||||||
FROM
|
FROM
|
||||||
repos r
|
repos r
|
||||||
|
@ -83,6 +104,16 @@ WHERE r.repo_id = s.star_repo_id
|
||||||
AND s.star_user_id = ?
|
AND s.star_user_id = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const repoListQuery = `
|
||||||
|
SELECT *
|
||||||
|
FROM repos
|
||||||
|
WHERE repo_id IN (
|
||||||
|
SELECT DISTINCT build_repo_id
|
||||||
|
FROM builds
|
||||||
|
WHERE build_author = ?
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
const repoDeleteStmt = `
|
const repoDeleteStmt = `
|
||||||
DELETE FROM repos
|
DELETE FROM repos
|
||||||
WHERE repo_id = ?
|
WHERE repo_id = ?
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestRepostore(t *testing.T) {
|
||||||
// before each test be sure to purge the package
|
// before each test be sure to purge the package
|
||||||
// table data from the database.
|
// table data from the database.
|
||||||
g.BeforeEach(func() {
|
g.BeforeEach(func() {
|
||||||
db.Exec("DELETE FROM stars")
|
db.Exec("DELETE FROM builds")
|
||||||
db.Exec("DELETE FROM repos")
|
db.Exec("DELETE FROM repos")
|
||||||
db.Exec("DELETE FROM users")
|
db.Exec("DELETE FROM users")
|
||||||
})
|
})
|
||||||
|
@ -101,8 +101,9 @@ func TestRepostore(t *testing.T) {
|
||||||
}
|
}
|
||||||
CreateRepo(db, &repo1)
|
CreateRepo(db, &repo1)
|
||||||
CreateRepo(db, &repo2)
|
CreateRepo(db, &repo2)
|
||||||
CreateStar(db, &User{ID: 1}, &repo1)
|
CreateBuild(db, &Build{RepoID: repo1.ID, Author: "bradrydzewski"})
|
||||||
repos, err := GetRepoList(db, &User{ID: 1})
|
CreateBuild(db, &Build{RepoID: repo1.ID, Author: "johnsmith"})
|
||||||
|
repos, err := GetRepoList(db, &User{ID: 1, Login: "bradrydzewski"})
|
||||||
g.Assert(err == nil).IsTrue()
|
g.Assert(err == nil).IsTrue()
|
||||||
g.Assert(len(repos)).Equal(1)
|
g.Assert(len(repos)).Equal(1)
|
||||||
g.Assert(repos[0].UserID).Equal(repo1.UserID)
|
g.Assert(repos[0].UserID).Equal(repo1.UserID)
|
||||||
|
|
|
@ -37,7 +37,7 @@ func GetUserList(db meddler.DB) ([]*User, error) {
|
||||||
|
|
||||||
func GetUserFeed(db meddler.DB, user *User, limit, offset int) ([]*Feed, error) {
|
func GetUserFeed(db meddler.DB, user *User, limit, offset int) ([]*Feed, error) {
|
||||||
var feed = []*Feed{}
|
var feed = []*Feed{}
|
||||||
var err = meddler.QueryAll(db, &feed, database.Rebind(userFeedQuery), user.ID, limit, offset)
|
var err = meddler.QueryAll(db, &feed, database.Rebind(userFeedQuery), user.Login, limit, offset)
|
||||||
return feed, err
|
return feed, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,15 +85,45 @@ DELETE FROM users
|
||||||
WHERE user_id=?
|
WHERE user_id=?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
// this query was referenced from
|
||||||
|
// http://stackoverflow.com/questions/2111384/sql-join-selecting-the-last-records-in-a-one-to-many-relationship/2111420#2111420
|
||||||
|
// const userRepoLatestQuery = `
|
||||||
|
// SELECT
|
||||||
|
// r.repo_owner
|
||||||
|
// ,r.repo_name
|
||||||
|
// ,r.repo_full_name
|
||||||
|
// ,r.repo_avatar
|
||||||
|
// ,b.build_number
|
||||||
|
// ,b.build_event
|
||||||
|
// ,b.build_status
|
||||||
|
// ,b.build_created
|
||||||
|
// ,b.build_started
|
||||||
|
// ,b.build_finished
|
||||||
|
// ,b.build_commit
|
||||||
|
// ,b.build_branch
|
||||||
|
// ,b.build_ref
|
||||||
|
// ,b.build_refspec
|
||||||
|
// ,b.build_remote
|
||||||
|
// ,b.build_title
|
||||||
|
// ,b.build_message
|
||||||
|
// ,b.build_author
|
||||||
|
// ,b.build_email
|
||||||
|
// FROM repos r
|
||||||
|
// JOIN builds b ON (r.repo_id = b.build_repo_id)
|
||||||
|
// LEFT OUTER JOIN builds bb ON (r.repo_id = bb.build_repo_id AND
|
||||||
|
// (b.build_number < bb.build_number OR b.build_number = bb.build_number AND b.build_id < bb.build_id AND b.build_author=?))
|
||||||
|
// WHERE bb.build_id IS NULL;
|
||||||
|
// `
|
||||||
|
|
||||||
const userFeedQuery = `
|
const userFeedQuery = `
|
||||||
SELECT
|
SELECT
|
||||||
repo_owner
|
repo_owner
|
||||||
,repo_name
|
,repo_name
|
||||||
,repo_full_name
|
,repo_full_name
|
||||||
,repo_avatar
|
|
||||||
,build_number
|
,build_number
|
||||||
,build_event
|
,build_event
|
||||||
,build_status
|
,build_status
|
||||||
|
,build_created
|
||||||
,build_started
|
,build_started
|
||||||
,build_finished
|
,build_finished
|
||||||
,build_commit
|
,build_commit
|
||||||
|
@ -105,13 +135,12 @@ SELECT
|
||||||
,build_message
|
,build_message
|
||||||
,build_author
|
,build_author
|
||||||
,build_email
|
,build_email
|
||||||
|
,build_avatar
|
||||||
FROM
|
FROM
|
||||||
builds b
|
builds b
|
||||||
,repos r
|
,repos r
|
||||||
,stars s
|
|
||||||
WHERE b.build_repo_id = r.repo_id
|
WHERE b.build_repo_id = r.repo_id
|
||||||
AND r.repo_id = s.star_repo_id
|
AND b.build_author = ?
|
||||||
AND s.star_user_id = ?
|
ORDER BY b.build_id DESC
|
||||||
ORDER BY b.build_number DESC
|
|
||||||
LIMIT ? OFFSET ?
|
LIMIT ? OFFSET ?
|
||||||
`
|
`
|
||||||
|
|
|
@ -179,25 +179,27 @@ func TestUserstore(t *testing.T) {
|
||||||
}
|
}
|
||||||
CreateRepo(db, repo1)
|
CreateRepo(db, repo1)
|
||||||
CreateRepo(db, repo2)
|
CreateRepo(db, repo2)
|
||||||
CreateStar(db, &User{ID: 1}, repo1)
|
|
||||||
|
|
||||||
build1 := &Build{
|
build1 := &Build{
|
||||||
RepoID: repo1.ID,
|
RepoID: repo1.ID,
|
||||||
Status: StatusFailure,
|
Status: StatusFailure,
|
||||||
|
Author: "bradrydzewski",
|
||||||
}
|
}
|
||||||
build2 := &Build{
|
build2 := &Build{
|
||||||
RepoID: repo1.ID,
|
RepoID: repo1.ID,
|
||||||
Status: StatusSuccess,
|
Status: StatusSuccess,
|
||||||
|
Author: "bradrydzewski",
|
||||||
}
|
}
|
||||||
build3 := &Build{
|
build3 := &Build{
|
||||||
RepoID: repo2.ID,
|
RepoID: repo2.ID,
|
||||||
Status: StatusSuccess,
|
Status: StatusSuccess,
|
||||||
|
Author: "octocat",
|
||||||
}
|
}
|
||||||
CreateBuild(db, build1)
|
CreateBuild(db, build1)
|
||||||
CreateBuild(db, build2)
|
CreateBuild(db, build2)
|
||||||
CreateBuild(db, build3)
|
CreateBuild(db, build3)
|
||||||
|
|
||||||
builds, err := GetUserFeed(db, &User{ID: 1}, 20, 0)
|
builds, err := GetUserFeed(db, &User{ID: 1, Login: "bradrydzewski"}, 20, 0)
|
||||||
g.Assert(err == nil).IsTrue()
|
g.Assert(err == nil).IsTrue()
|
||||||
g.Assert(len(builds)).Equal(2)
|
g.Assert(len(builds)).Equal(2)
|
||||||
g.Assert(builds[0].Owner).Equal("bradrydzewski")
|
g.Assert(builds[0].Owner).Equal("bradrydzewski")
|
||||||
|
|
|
@ -54,10 +54,10 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
||||||
{
|
{
|
||||||
user.Use(session.MustUser())
|
user.Use(session.MustUser())
|
||||||
user.GET("", controller.GetSelf)
|
user.GET("", controller.GetSelf)
|
||||||
user.GET("/feed", controller.GetFeed)
|
user.GET("/builds", controller.GetFeed)
|
||||||
user.GET("/repos", controller.GetRepos)
|
user.GET("/repos", controller.GetRepos)
|
||||||
user.POST("/token", controller.PostToken)
|
|
||||||
user.GET("/repos/remote", controller.GetRemoteRepos)
|
user.GET("/repos/remote", controller.GetRemoteRepos)
|
||||||
|
user.POST("/token", controller.PostToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
users := e.Group("/api/users")
|
users := e.Group("/api/users")
|
||||||
|
|
|
@ -33,7 +33,7 @@ CREATE TABLE repos (
|
||||||
,repo_allow_tags BOOLEAN
|
,repo_allow_tags BOOLEAN
|
||||||
,repo_hash VARCHAR(500)
|
,repo_hash VARCHAR(500)
|
||||||
|
|
||||||
,UNIQUE(repo_owner, repo_name)
|
,UNIQUE(repo_full_name)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE stars (
|
CREATE TABLE stars (
|
||||||
|
|
|
@ -33,7 +33,7 @@ CREATE TABLE repos (
|
||||||
,repo_allow_tags BOOLEAN
|
,repo_allow_tags BOOLEAN
|
||||||
,repo_hash VARCHAR(500)
|
,repo_hash VARCHAR(500)
|
||||||
|
|
||||||
,UNIQUE(repo_owner, repo_name)
|
,UNIQUE(repo_full_name)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE stars (
|
CREATE TABLE stars (
|
||||||
|
|
|
@ -33,7 +33,7 @@ CREATE TABLE repos (
|
||||||
,repo_allow_tags BOOLEAN
|
,repo_allow_tags BOOLEAN
|
||||||
,repo_hash TEXT
|
,repo_hash TEXT
|
||||||
|
|
||||||
,UNIQUE(repo_owner, repo_name)
|
,UNIQUE(repo_full_name)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE stars (
|
CREATE TABLE stars (
|
||||||
|
|
Loading…
Reference in a new issue