mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-10-22 05:47:57 +00:00
didn't realize gin supports net.Context. Change to support Context pattern!
This commit is contained in:
71
store/builds.go
Normal file
71
store/builds.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type BuildStore interface {
|
||||
// Get gets a build by unique ID.
|
||||
Get(int64) (*model.Build, error)
|
||||
|
||||
// GetNumber gets a build by number.
|
||||
GetNumber(*model.Repo, int) (*model.Build, error)
|
||||
|
||||
// GetRef gets a build by its ref.
|
||||
GetRef(*model.Repo, string) (*model.Build, error)
|
||||
|
||||
// GetCommit gets a build by its commit sha.
|
||||
GetCommit(*model.Repo, string, string) (*model.Build, error)
|
||||
|
||||
// GetLast gets the last build for the branch.
|
||||
GetLast(*model.Repo, string) (*model.Build, error)
|
||||
|
||||
// GetLastBefore gets the last build before build number N.
|
||||
GetLastBefore(*model.Repo, string, int64) (*model.Build, error)
|
||||
|
||||
// GetList gets a list of builds for the repository
|
||||
GetList(*model.Repo) ([]*model.Build, error)
|
||||
|
||||
// Create creates a new build and jobs.
|
||||
Create(*model.Build, ...*model.Job) error
|
||||
|
||||
// Update updates a build.
|
||||
Update(*model.Build) error
|
||||
}
|
||||
|
||||
func GetBuild(c context.Context, id int64) (*model.Build, error) {
|
||||
return FromContext(c).Builds().Get(id)
|
||||
}
|
||||
|
||||
func GetBuildNumber(c context.Context, repo *model.Repo, num int) (*model.Build, error) {
|
||||
return FromContext(c).Builds().GetNumber(repo, num)
|
||||
}
|
||||
|
||||
func GetBuildRef(c context.Context, repo *model.Repo, ref string) (*model.Build, error) {
|
||||
return FromContext(c).Builds().GetRef(repo, ref)
|
||||
}
|
||||
|
||||
func GetBuildCommit(c context.Context, repo *model.Repo, sha, branch string) (*model.Build, error) {
|
||||
return FromContext(c).Builds().GetCommit(repo, sha, branch)
|
||||
}
|
||||
|
||||
func GetBuildLast(c context.Context, repo *model.Repo, branch string) (*model.Build, error) {
|
||||
return FromContext(c).Builds().GetLast(repo, branch)
|
||||
}
|
||||
|
||||
func GetBuildLastBefore(c context.Context, repo *model.Repo, branch string, number int64) (*model.Build, error) {
|
||||
return FromContext(c).Builds().GetLastBefore(repo, branch, number)
|
||||
}
|
||||
|
||||
func GetBuildList(c context.Context, repo *model.Repo) ([]*model.Build, error) {
|
||||
return FromContext(c).Builds().GetList(repo)
|
||||
}
|
||||
|
||||
func CreateBuild(c context.Context, build *model.Build, jobs ...*model.Job) error {
|
||||
return FromContext(c).Builds().Create(build, jobs...)
|
||||
}
|
||||
|
||||
func UpdateBuild(c context.Context, build *model.Build) error {
|
||||
return FromContext(c).Builds().Update(build)
|
||||
}
|
23
store/context.go
Normal file
23
store/context.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const key = "store"
|
||||
|
||||
// Setter defines a context that enables setting values.
|
||||
type Setter interface {
|
||||
Set(string, interface{})
|
||||
}
|
||||
|
||||
// FromContext returns the Store associated with this context.
|
||||
func FromContext(c context.Context) Store {
|
||||
return c.Value(key).(Store)
|
||||
}
|
||||
|
||||
// ToContext adds the Store to this context if it supports
|
||||
// the Setter interface.
|
||||
func ToContext(c Setter, store Store) {
|
||||
c.Set(key, store)
|
||||
}
|
141
store/datastore/builds.go
Normal file
141
store/datastore/builds.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
type buildstore struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func (db *buildstore) Get(id int64) (*model.Build, error) {
|
||||
var build = new(model.Build)
|
||||
var err = meddler.Load(db, buildTable, build, id)
|
||||
return build, err
|
||||
}
|
||||
|
||||
func (db *buildstore) GetNumber(repo *model.Repo, num int) (*model.Build, error) {
|
||||
var build = new(model.Build)
|
||||
var err = meddler.QueryRow(db, build, rebind(buildNumberQuery), repo.ID, num)
|
||||
return build, err
|
||||
}
|
||||
|
||||
func (db *buildstore) GetRef(repo *model.Repo, ref string) (*model.Build, error) {
|
||||
var build = new(model.Build)
|
||||
var err = meddler.QueryRow(db, build, rebind(buildRefQuery), repo.ID, ref)
|
||||
return build, err
|
||||
}
|
||||
|
||||
func (db *buildstore) GetCommit(repo *model.Repo, sha, branch string) (*model.Build, error) {
|
||||
var build = new(model.Build)
|
||||
var err = meddler.QueryRow(db, build, rebind(buildCommitQuery), repo.ID, sha, branch)
|
||||
return build, err
|
||||
}
|
||||
|
||||
func (db *buildstore) GetLast(repo *model.Repo, branch string) (*model.Build, error) {
|
||||
var build = new(model.Build)
|
||||
var err = meddler.QueryRow(db, build, rebind(buildLastQuery), repo.ID, branch)
|
||||
return build, err
|
||||
}
|
||||
|
||||
func (db *buildstore) GetLastBefore(repo *model.Repo, branch string, num int64) (*model.Build, error) {
|
||||
var build = new(model.Build)
|
||||
var err = meddler.QueryRow(db, build, rebind(buildLastBeforeQuery), repo.ID, branch, num)
|
||||
return build, err
|
||||
}
|
||||
|
||||
func (db *buildstore) GetList(repo *model.Repo) ([]*model.Build, error) {
|
||||
var builds = []*model.Build{}
|
||||
var err = meddler.QueryAll(db, &builds, rebind(buildListQuery), repo.ID)
|
||||
return builds, err
|
||||
}
|
||||
|
||||
func (db *buildstore) Create(build *model.Build, jobs ...*model.Job) error {
|
||||
var number int
|
||||
db.QueryRow(rebind(buildNumberLast), build.RepoID).Scan(&number)
|
||||
build.Number = number + 1
|
||||
build.Created = time.Now().UTC().Unix()
|
||||
build.Enqueued = build.Created
|
||||
err := meddler.Insert(db, buildTable, build)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, job := range jobs {
|
||||
job.BuildID = build.ID
|
||||
job.Number = i + 1
|
||||
job.Enqueued = build.Created
|
||||
err = meddler.Insert(db, jobTable, job)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *buildstore) Update(build *model.Build) error {
|
||||
return meddler.Update(db, buildTable, build)
|
||||
}
|
||||
|
||||
const buildTable = "builds"
|
||||
|
||||
const buildListQuery = `
|
||||
SELECT *
|
||||
FROM builds
|
||||
WHERE build_repo_id = ?
|
||||
ORDER BY build_number DESC
|
||||
LIMIT 50
|
||||
`
|
||||
|
||||
const buildNumberQuery = `
|
||||
SELECT *
|
||||
FROM builds
|
||||
WHERE build_repo_id = ?
|
||||
AND build_number = ?
|
||||
LIMIT 1;
|
||||
`
|
||||
|
||||
const buildLastQuery = `
|
||||
SELECT *
|
||||
FROM builds
|
||||
WHERE build_repo_id = ?
|
||||
AND build_branch = ?
|
||||
ORDER BY build_number DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
const buildLastBeforeQuery = `
|
||||
SELECT *
|
||||
FROM builds
|
||||
WHERE build_repo_id = ?
|
||||
AND build_branch = ?
|
||||
AND build_id < ?
|
||||
ORDER BY build_number DESC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
const buildCommitQuery = `
|
||||
SELECT *
|
||||
FROM builds
|
||||
WHERE build_repo_id = ?
|
||||
AND build_commit = ?
|
||||
AND build_branch = ?
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
const buildRefQuery = `
|
||||
SELECT *
|
||||
FROM builds
|
||||
WHERE build_repo_id = ?
|
||||
AND build_ref = ?
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
const buildNumberLast = `
|
||||
SELECT MAX(build_number)
|
||||
FROM builds
|
||||
WHERE build_repo_id = ?
|
||||
`
|
243
store/datastore/builds_test.go
Normal file
243
store/datastore/builds_test.go
Normal file
@@ -0,0 +1,243 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_buildstore(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Builds", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec("DELETE FROM builds")
|
||||
db.Exec("DELETE FROM jobs")
|
||||
})
|
||||
|
||||
g.It("Should Post a Build", func() {
|
||||
build := model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusSuccess,
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||
}
|
||||
err := s.Builds().Create(&build, []*model.Job{}...)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(build.ID != 0).IsTrue()
|
||||
g.Assert(build.Number).Equal(1)
|
||||
g.Assert(build.Commit).Equal("85f8c029b902ed9400bc600bac301a0aadb144ac")
|
||||
})
|
||||
|
||||
g.It("Should Put a Build", func() {
|
||||
build := model.Build{
|
||||
RepoID: 1,
|
||||
Number: 5,
|
||||
Status: model.StatusSuccess,
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||
}
|
||||
s.Builds().Create(&build, []*model.Job{}...)
|
||||
build.Status = model.StatusRunning
|
||||
err1 := s.Builds().Update(&build)
|
||||
getbuild, err2 := s.Builds().Get(build.ID)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(build.ID).Equal(getbuild.ID)
|
||||
g.Assert(build.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build.Status).Equal(getbuild.Status)
|
||||
g.Assert(build.Number).Equal(getbuild.Number)
|
||||
})
|
||||
|
||||
g.It("Should Get a Build", func() {
|
||||
build := model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusSuccess,
|
||||
}
|
||||
s.Builds().Create(&build, []*model.Job{}...)
|
||||
getbuild, err := s.Builds().Get(build.ID)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(build.ID).Equal(getbuild.ID)
|
||||
g.Assert(build.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build.Status).Equal(getbuild.Status)
|
||||
})
|
||||
|
||||
g.It("Should Get a Build by Number", func() {
|
||||
build1 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
}
|
||||
build2 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
}
|
||||
err1 := s.Builds().Create(build1, []*model.Job{}...)
|
||||
err2 := s.Builds().Create(build2, []*model.Job{}...)
|
||||
getbuild, err3 := s.Builds().GetNumber(&model.Repo{ID: 1}, build2.Number)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(build2.ID).Equal(getbuild.ID)
|
||||
g.Assert(build2.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build2.Number).Equal(getbuild.Number)
|
||||
})
|
||||
|
||||
g.It("Should Get a Build by Ref", func() {
|
||||
build1 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
Ref: "refs/pull/5",
|
||||
}
|
||||
build2 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
Ref: "refs/pull/6",
|
||||
}
|
||||
err1 := s.Builds().Create(build1, []*model.Job{}...)
|
||||
err2 := s.Builds().Create(build2, []*model.Job{}...)
|
||||
getbuild, err3 := s.Builds().GetRef(&model.Repo{ID: 1}, "refs/pull/6")
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(build2.ID).Equal(getbuild.ID)
|
||||
g.Assert(build2.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build2.Number).Equal(getbuild.Number)
|
||||
g.Assert(build2.Ref).Equal(getbuild.Ref)
|
||||
})
|
||||
|
||||
g.It("Should Get a Build by Ref", func() {
|
||||
build1 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
Ref: "refs/pull/5",
|
||||
}
|
||||
build2 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
Ref: "refs/pull/6",
|
||||
}
|
||||
err1 := s.Builds().Create(build1, []*model.Job{}...)
|
||||
err2 := s.Builds().Create(build2, []*model.Job{}...)
|
||||
getbuild, err3 := s.Builds().GetRef(&model.Repo{ID: 1}, "refs/pull/6")
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(build2.ID).Equal(getbuild.ID)
|
||||
g.Assert(build2.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build2.Number).Equal(getbuild.Number)
|
||||
g.Assert(build2.Ref).Equal(getbuild.Ref)
|
||||
})
|
||||
|
||||
g.It("Should Get a Build by Commit", func() {
|
||||
build1 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
Branch: "master",
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||
}
|
||||
build2 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusPending,
|
||||
Branch: "dev",
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa",
|
||||
}
|
||||
err1 := s.Builds().Create(build1, []*model.Job{}...)
|
||||
err2 := s.Builds().Create(build2, []*model.Job{}...)
|
||||
getbuild, err3 := s.Builds().GetCommit(&model.Repo{ID: 1}, build2.Commit, build2.Branch)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(build2.ID).Equal(getbuild.ID)
|
||||
g.Assert(build2.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build2.Number).Equal(getbuild.Number)
|
||||
g.Assert(build2.Commit).Equal(getbuild.Commit)
|
||||
g.Assert(build2.Branch).Equal(getbuild.Branch)
|
||||
})
|
||||
|
||||
g.It("Should Get the last Build", func() {
|
||||
build1 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusFailure,
|
||||
Branch: "master",
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||
}
|
||||
build2 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusSuccess,
|
||||
Branch: "master",
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa",
|
||||
}
|
||||
err1 := s.Builds().Create(build1, []*model.Job{}...)
|
||||
err2 := s.Builds().Create(build2, []*model.Job{}...)
|
||||
getbuild, err3 := s.Builds().GetLast(&model.Repo{ID: 1}, build2.Branch)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(build2.ID).Equal(getbuild.ID)
|
||||
g.Assert(build2.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build2.Number).Equal(getbuild.Number)
|
||||
g.Assert(build2.Status).Equal(getbuild.Status)
|
||||
g.Assert(build2.Branch).Equal(getbuild.Branch)
|
||||
g.Assert(build2.Commit).Equal(getbuild.Commit)
|
||||
})
|
||||
|
||||
g.It("Should Get the last Build Before Build N", func() {
|
||||
build1 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusFailure,
|
||||
Branch: "master",
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac",
|
||||
}
|
||||
build2 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusSuccess,
|
||||
Branch: "master",
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa",
|
||||
}
|
||||
build3 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusRunning,
|
||||
Branch: "master",
|
||||
Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa",
|
||||
}
|
||||
err1 := s.Builds().Create(build1, []*model.Job{}...)
|
||||
err2 := s.Builds().Create(build2, []*model.Job{}...)
|
||||
err3 := s.Builds().Create(build3, []*model.Job{}...)
|
||||
getbuild, err4 := s.Builds().GetLastBefore(&model.Repo{ID: 1}, build3.Branch, build3.ID)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(err4 == nil).IsTrue()
|
||||
g.Assert(build2.ID).Equal(getbuild.ID)
|
||||
g.Assert(build2.RepoID).Equal(getbuild.RepoID)
|
||||
g.Assert(build2.Number).Equal(getbuild.Number)
|
||||
g.Assert(build2.Status).Equal(getbuild.Status)
|
||||
g.Assert(build2.Branch).Equal(getbuild.Branch)
|
||||
g.Assert(build2.Commit).Equal(getbuild.Commit)
|
||||
})
|
||||
|
||||
g.It("Should get recent Builds", func() {
|
||||
build1 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusFailure,
|
||||
}
|
||||
build2 := &model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusSuccess,
|
||||
}
|
||||
s.Builds().Create(build1, []*model.Job{}...)
|
||||
s.Builds().Create(build2, []*model.Job{}...)
|
||||
builds, err := s.Builds().GetList(&model.Repo{ID: 1})
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(builds)).Equal(2)
|
||||
g.Assert(builds[0].ID).Equal(build2.ID)
|
||||
g.Assert(builds[0].RepoID).Equal(build2.RepoID)
|
||||
g.Assert(builds[0].Status).Equal(build2.Status)
|
||||
})
|
||||
})
|
||||
}
|
55
store/datastore/jobs.go
Normal file
55
store/datastore/jobs.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
type jobstore struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func (db *jobstore) Get(id int64) (*model.Job, error) {
|
||||
var job = new(model.Job)
|
||||
var err = meddler.Load(db, jobTable, job, id)
|
||||
return job, err
|
||||
}
|
||||
|
||||
func (db *jobstore) GetNumber(build *model.Build, num int) (*model.Job, error) {
|
||||
var job = new(model.Job)
|
||||
var err = meddler.QueryRow(db, job, rebind(jobNumberQuery), build.ID, num)
|
||||
return job, err
|
||||
}
|
||||
|
||||
func (db *jobstore) GetList(build *model.Build) ([]*model.Job, error) {
|
||||
var jobs = []*model.Job{}
|
||||
var err = meddler.QueryAll(db, &jobs, rebind(jobListQuery), build.ID)
|
||||
return jobs, err
|
||||
}
|
||||
|
||||
func (db *jobstore) Create(job *model.Job) error {
|
||||
return meddler.Insert(db, jobTable, job)
|
||||
}
|
||||
|
||||
func (db *jobstore) Update(job *model.Job) error {
|
||||
return meddler.Update(db, jobTable, job)
|
||||
}
|
||||
|
||||
const jobTable = "jobs"
|
||||
|
||||
const jobListQuery = `
|
||||
SELECT *
|
||||
FROM jobs
|
||||
WHERE job_build_id = ?
|
||||
ORDER BY job_number ASC
|
||||
`
|
||||
|
||||
const jobNumberQuery = `
|
||||
SELECT *
|
||||
FROM jobs
|
||||
WHERE job_build_id = ?
|
||||
AND job_number = ?
|
||||
LIMIT 1
|
||||
`
|
118
store/datastore/jobs_test.go
Normal file
118
store/datastore/jobs_test.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_jobstore(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Job", func() {
|
||||
|
||||
// before each test we purge the package table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec("DELETE FROM jobs")
|
||||
db.Exec("DELETE FROM builds")
|
||||
})
|
||||
|
||||
g.It("Should Set a job", func() {
|
||||
job := &model.Job{
|
||||
BuildID: 1,
|
||||
Status: "pending",
|
||||
ExitCode: 0,
|
||||
Number: 1,
|
||||
}
|
||||
err1 := s.Jobs().Create(job)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(job.ID != 0).IsTrue()
|
||||
|
||||
job.Status = "started"
|
||||
err2 := s.Jobs().Update(job)
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
|
||||
getjob, err3 := s.Jobs().Get(job.ID)
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(getjob.Status).Equal(job.Status)
|
||||
})
|
||||
|
||||
g.It("Should Get a Job by ID", func() {
|
||||
job := &model.Job{
|
||||
BuildID: 1,
|
||||
Status: "pending",
|
||||
ExitCode: 1,
|
||||
Number: 1,
|
||||
Environment: map[string]string{"foo": "bar"},
|
||||
}
|
||||
err1 := s.Jobs().Create(job)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(job.ID != 0).IsTrue()
|
||||
|
||||
getjob, err2 := s.Jobs().Get(job.ID)
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(getjob.ID).Equal(job.ID)
|
||||
g.Assert(getjob.Status).Equal(job.Status)
|
||||
g.Assert(getjob.ExitCode).Equal(job.ExitCode)
|
||||
g.Assert(getjob.Environment).Equal(job.Environment)
|
||||
g.Assert(getjob.Environment["foo"]).Equal("bar")
|
||||
})
|
||||
|
||||
g.It("Should Get a Job by Number", func() {
|
||||
job := &model.Job{
|
||||
BuildID: 1,
|
||||
Status: "pending",
|
||||
ExitCode: 1,
|
||||
Number: 1,
|
||||
}
|
||||
err1 := s.Jobs().Create(job)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(job.ID != 0).IsTrue()
|
||||
|
||||
getjob, err2 := s.Jobs().GetNumber(&model.Build{ID: 1}, 1)
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(getjob.ID).Equal(job.ID)
|
||||
g.Assert(getjob.Status).Equal(job.Status)
|
||||
})
|
||||
|
||||
g.It("Should Get a List of Jobs by Commit", func() {
|
||||
|
||||
build := model.Build{
|
||||
RepoID: 1,
|
||||
Status: model.StatusSuccess,
|
||||
}
|
||||
jobs := []*model.Job{
|
||||
&model.Job{
|
||||
BuildID: 1,
|
||||
Status: "success",
|
||||
ExitCode: 0,
|
||||
Number: 1,
|
||||
},
|
||||
&model.Job{
|
||||
BuildID: 3,
|
||||
Status: "error",
|
||||
ExitCode: 1,
|
||||
Number: 2,
|
||||
},
|
||||
&model.Job{
|
||||
BuildID: 5,
|
||||
Status: "pending",
|
||||
ExitCode: 0,
|
||||
Number: 3,
|
||||
},
|
||||
}
|
||||
|
||||
err1 := s.Builds().Create(&build, jobs...)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
getjobs, err2 := s.Jobs().GetList(&build)
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(len(getjobs)).Equal(3)
|
||||
g.Assert(getjobs[0].Number).Equal(1)
|
||||
g.Assert(getjobs[0].Status).Equal(model.StatusSuccess)
|
||||
})
|
||||
})
|
||||
}
|
37
store/datastore/keys.go
Normal file
37
store/datastore/keys.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
type keystore struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func (db *keystore) Get(repo *model.Repo) (*model.Key, error) {
|
||||
var key = new(model.Key)
|
||||
var err = meddler.QueryRow(db, key, rebind(keyQuery), repo.ID)
|
||||
return key, err
|
||||
}
|
||||
|
||||
func (db *keystore) Create(key *model.Key) error {
|
||||
return meddler.Save(db, keyTable, key)
|
||||
}
|
||||
|
||||
func (db *keystore) Update(key *model.Key) error {
|
||||
return meddler.Save(db, keyTable, key)
|
||||
}
|
||||
|
||||
func (db *keystore) Delete(key *model.Key) error {
|
||||
var _, err = db.Exec(rebind(keyDeleteStmt), key.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const keyTable = "keys"
|
||||
|
||||
const keyQuery = "SELECT * FROM `keys` WHERE key_repo_id=? LIMIT 1"
|
||||
|
||||
const keyDeleteStmt = "DELETE FROM `keys` WHERE key_id=?"
|
114
store/datastore/keys_test.go
Normal file
114
store/datastore/keys_test.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_keystore(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Keys", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec(rebind("DELETE FROM `keys`"))
|
||||
})
|
||||
|
||||
g.It("Should create a key", func() {
|
||||
key := model.Key{
|
||||
RepoID: 1,
|
||||
Public: fakePublicKey,
|
||||
Private: fakePrivateKey,
|
||||
}
|
||||
err := s.Keys().Create(&key)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(key.ID != 0).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should update a key", func() {
|
||||
key := model.Key{
|
||||
RepoID: 1,
|
||||
Public: fakePublicKey,
|
||||
Private: fakePrivateKey,
|
||||
}
|
||||
err := s.Keys().Create(&key)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(key.ID != 0).IsTrue()
|
||||
|
||||
key.Private = ""
|
||||
key.Public = ""
|
||||
|
||||
err1 := s.Keys().Update(&key)
|
||||
getkey, err2 := s.Keys().Get(&model.Repo{ID: 1})
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(key.ID).Equal(getkey.ID)
|
||||
g.Assert(key.Public).Equal(getkey.Public)
|
||||
g.Assert(key.Private).Equal(getkey.Private)
|
||||
})
|
||||
|
||||
g.It("Should get a key", func() {
|
||||
key := model.Key{
|
||||
RepoID: 1,
|
||||
Public: fakePublicKey,
|
||||
Private: fakePrivateKey,
|
||||
}
|
||||
err := s.Keys().Create(&key)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(key.ID != 0).IsTrue()
|
||||
|
||||
getkey, err := s.Keys().Get(&model.Repo{ID: 1})
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(key.ID).Equal(getkey.ID)
|
||||
g.Assert(key.Public).Equal(getkey.Public)
|
||||
g.Assert(key.Private).Equal(getkey.Private)
|
||||
})
|
||||
|
||||
g.It("Should delete a key", func() {
|
||||
key := model.Key{
|
||||
RepoID: 1,
|
||||
Public: fakePublicKey,
|
||||
Private: fakePrivateKey,
|
||||
}
|
||||
err1 := s.Keys().Create(&key)
|
||||
err2 := s.Keys().Delete(&key)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
|
||||
_, err := s.Keys().Get(&model.Repo{ID: 1})
|
||||
g.Assert(err == nil).IsFalse()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
var fakePublicKey = `
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0
|
||||
FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/
|
||||
3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
`
|
||||
|
||||
var fakePrivateKey = `
|
||||
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
|
||||
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
|
||||
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
|
||||
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
|
||||
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
|
||||
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
|
||||
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
|
||||
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
|
||||
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
41
store/datastore/logs.go
Normal file
41
store/datastore/logs.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
type logstore struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func (db *logstore) Read(job *model.Job) (io.ReadCloser, error) {
|
||||
var log = new(model.Log)
|
||||
var err = meddler.QueryRow(db, log, rebind(logQuery), job.ID)
|
||||
var buf = bytes.NewBuffer(log.Data)
|
||||
return ioutil.NopCloser(buf), err
|
||||
}
|
||||
|
||||
func (db *logstore) Write(job *model.Job, r io.Reader) error {
|
||||
var log = new(model.Log)
|
||||
var err = meddler.QueryRow(db, log, rebind(logQuery), job.ID)
|
||||
if err != nil {
|
||||
log = &model.Log{JobID: job.ID}
|
||||
}
|
||||
log.Data, _ = ioutil.ReadAll(r)
|
||||
return meddler.Save(db, logTable, log)
|
||||
}
|
||||
|
||||
const logTable = "logs"
|
||||
|
||||
const logQuery = `
|
||||
SELECT *
|
||||
FROM logs
|
||||
WHERE log_job_id=?
|
||||
LIMIT 1
|
||||
`
|
60
store/datastore/logs_test.go
Normal file
60
store/datastore/logs_test.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_logstore(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Logs", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec("DELETE FROM logs")
|
||||
})
|
||||
|
||||
g.It("Should create a log", func() {
|
||||
job := model.Job{
|
||||
ID: 1,
|
||||
}
|
||||
buf := bytes.NewBufferString("echo hi")
|
||||
err := s.Logs().Write(&job, buf)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
|
||||
rc, err := s.Logs().Read(&job)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
defer rc.Close()
|
||||
out, _ := ioutil.ReadAll(rc)
|
||||
g.Assert(string(out)).Equal("echo hi")
|
||||
})
|
||||
|
||||
g.It("Should update a log", func() {
|
||||
job := model.Job{
|
||||
ID: 1,
|
||||
}
|
||||
buf1 := bytes.NewBufferString("echo hi")
|
||||
buf2 := bytes.NewBufferString("echo allo?")
|
||||
err1 := s.Logs().Write(&job, buf1)
|
||||
err2 := s.Logs().Write(&job, buf2)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
|
||||
rc, err := s.Logs().Read(&job)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
defer rc.Close()
|
||||
out, _ := ioutil.ReadAll(rc)
|
||||
g.Assert(string(out)).Equal("echo allo?")
|
||||
})
|
||||
|
||||
})
|
||||
}
|
60
store/datastore/nodes.go
Normal file
60
store/datastore/nodes.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
type nodestore struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func (db *nodestore) Get(id int64) (*model.Node, error) {
|
||||
var node = new(model.Node)
|
||||
var err = meddler.Load(db, nodeTable, node, id)
|
||||
return node, err
|
||||
}
|
||||
|
||||
func (db *nodestore) GetList() ([]*model.Node, error) {
|
||||
var nodes = []*model.Node{}
|
||||
var err = meddler.QueryAll(db, &nodes, rebind(nodeListQuery))
|
||||
return nodes, err
|
||||
}
|
||||
|
||||
func (db *nodestore) Count() (int, error) {
|
||||
var count int
|
||||
var err = db.QueryRow(rebind(nodeCountQuery)).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (db *nodestore) Create(node *model.Node) error {
|
||||
return meddler.Insert(db, nodeTable, node)
|
||||
}
|
||||
|
||||
func (db *nodestore) Update(node *model.Node) error {
|
||||
return meddler.Update(db, nodeTable, node)
|
||||
}
|
||||
|
||||
func (db *nodestore) Delete(node *model.Node) error {
|
||||
var _, err = db.Exec(rebind(nodeDeleteStmt), node.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const nodeTable = "nodes"
|
||||
|
||||
const nodeListQuery = `
|
||||
SELECT *
|
||||
FROM nodes
|
||||
ORDER BY node_addr
|
||||
`
|
||||
|
||||
const nodeCountQuery = `
|
||||
SELECT COUNT(*) FROM nodes
|
||||
`
|
||||
|
||||
const nodeDeleteStmt = `
|
||||
DELETE FROM nodes
|
||||
WHERE node_id=?
|
||||
`
|
101
store/datastore/nodes_test.go
Normal file
101
store/datastore/nodes_test.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_nodestore(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
s := From(db)
|
||||
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Nodes", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec("DELETE FROM nodes")
|
||||
})
|
||||
|
||||
g.It("Should create a node", func() {
|
||||
node := model.Node{
|
||||
Addr: "unix:///var/run/docker/docker.sock",
|
||||
Arch: "linux_amd64",
|
||||
}
|
||||
err := s.Nodes().Create(&node)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(node.ID != 0).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should update a node", func() {
|
||||
node := model.Node{
|
||||
Addr: "unix:///var/run/docker/docker.sock",
|
||||
Arch: "linux_amd64",
|
||||
}
|
||||
err := s.Nodes().Create(&node)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(node.ID != 0).IsTrue()
|
||||
|
||||
node.Addr = "unix:///var/run/docker.sock"
|
||||
|
||||
err1 := s.Nodes().Update(&node)
|
||||
getnode, err2 := s.Nodes().Get(node.ID)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(node.ID).Equal(getnode.ID)
|
||||
g.Assert(node.Addr).Equal(getnode.Addr)
|
||||
g.Assert(node.Arch).Equal(getnode.Arch)
|
||||
})
|
||||
|
||||
g.It("Should get a node", func() {
|
||||
node := model.Node{
|
||||
Addr: "unix:///var/run/docker/docker.sock",
|
||||
Arch: "linux_amd64",
|
||||
}
|
||||
err := s.Nodes().Create(&node)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(node.ID != 0).IsTrue()
|
||||
|
||||
getnode, err := s.Nodes().Get(node.ID)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(node.ID).Equal(getnode.ID)
|
||||
g.Assert(node.Addr).Equal(getnode.Addr)
|
||||
g.Assert(node.Arch).Equal(getnode.Arch)
|
||||
})
|
||||
|
||||
g.It("Should get a node list", func() {
|
||||
node1 := model.Node{
|
||||
Addr: "unix:///var/run/docker/docker.sock",
|
||||
Arch: "linux_amd64",
|
||||
}
|
||||
node2 := model.Node{
|
||||
Addr: "unix:///var/run/docker.sock",
|
||||
Arch: "linux_386",
|
||||
}
|
||||
s.Nodes().Create(&node1)
|
||||
s.Nodes().Create(&node2)
|
||||
|
||||
nodes, err := s.Nodes().GetList()
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(nodes)).Equal(2)
|
||||
})
|
||||
|
||||
g.It("Should delete a node", func() {
|
||||
node := model.Node{
|
||||
Addr: "unix:///var/run/docker/docker.sock",
|
||||
Arch: "linux_amd64",
|
||||
}
|
||||
err1 := s.Nodes().Create(&node)
|
||||
err2 := s.Nodes().Delete(&node)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
|
||||
_, err := s.Nodes().Get(node.ID)
|
||||
g.Assert(err == nil).IsFalse()
|
||||
})
|
||||
})
|
||||
}
|
91
store/datastore/repos.go
Normal file
91
store/datastore/repos.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
type repostore struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func (db *repostore) Get(id int64) (*model.Repo, error) {
|
||||
var repo = new(model.Repo)
|
||||
var err = meddler.Load(db, repoTable, repo, id)
|
||||
return repo, err
|
||||
}
|
||||
|
||||
func (db *repostore) GetName(name string) (*model.Repo, error) {
|
||||
var repo = new(model.Repo)
|
||||
var err = meddler.QueryRow(db, repo, rebind(repoNameQuery), name)
|
||||
return repo, err
|
||||
}
|
||||
|
||||
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 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...)
|
||||
return repos, err
|
||||
}
|
||||
|
||||
func (db *repostore) Count() (int, error) {
|
||||
var count int
|
||||
var err = db.QueryRow(rebind(repoCountQuery)).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (db *repostore) Create(repo *model.Repo) error {
|
||||
return meddler.Insert(db, repoTable, repo)
|
||||
}
|
||||
|
||||
func (db *repostore) Update(repo *model.Repo) error {
|
||||
return meddler.Update(db, repoTable, repo)
|
||||
}
|
||||
|
||||
func (db *repostore) Delete(repo *model.Repo) error {
|
||||
var _, err = db.Exec(rebind(repoDeleteStmt), repo.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const repoTable = "repos"
|
||||
|
||||
const repoNameQuery = `
|
||||
SELECT *
|
||||
FROM repos
|
||||
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 repoCountQuery = `
|
||||
SELECT COUNT(*) FROM repos
|
||||
`
|
||||
|
||||
const repoDeleteStmt = `
|
||||
DELETE FROM repos
|
||||
WHERE repo_id = ?
|
||||
`
|
150
store/datastore/repos_test.go
Normal file
150
store/datastore/repos_test.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_repostore(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
|
||||
s := From(db)
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Repo", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec("DELETE FROM builds")
|
||||
db.Exec("DELETE FROM repos")
|
||||
db.Exec("DELETE FROM users")
|
||||
})
|
||||
|
||||
g.It("Should Set a Repo", func() {
|
||||
repo := model.Repo{
|
||||
UserID: 1,
|
||||
FullName: "bradrydzewski/drone",
|
||||
Owner: "bradrydzewski",
|
||||
Name: "drone",
|
||||
}
|
||||
err1 := s.Repos().Create(&repo)
|
||||
err2 := s.Repos().Update(&repo)
|
||||
getrepo, err3 := s.Repos().Get(repo.ID)
|
||||
if err3 != nil {
|
||||
println("Get Repo Error")
|
||||
println(err3.Error())
|
||||
}
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(repo.ID).Equal(getrepo.ID)
|
||||
})
|
||||
|
||||
g.It("Should Add a Repo", func() {
|
||||
repo := model.Repo{
|
||||
UserID: 1,
|
||||
FullName: "bradrydzewski/drone",
|
||||
Owner: "bradrydzewski",
|
||||
Name: "drone",
|
||||
}
|
||||
err := s.Repos().Create(&repo)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.ID != 0).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should Get a Repo by ID", func() {
|
||||
repo := model.Repo{
|
||||
UserID: 1,
|
||||
FullName: "bradrydzewski/drone",
|
||||
Owner: "bradrydzewski",
|
||||
Name: "drone",
|
||||
}
|
||||
s.Repos().Create(&repo)
|
||||
getrepo, err := s.Repos().Get(repo.ID)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.ID).Equal(getrepo.ID)
|
||||
g.Assert(repo.UserID).Equal(getrepo.UserID)
|
||||
g.Assert(repo.Owner).Equal(getrepo.Owner)
|
||||
g.Assert(repo.Name).Equal(getrepo.Name)
|
||||
})
|
||||
|
||||
g.It("Should Get a Repo by Name", func() {
|
||||
repo := model.Repo{
|
||||
UserID: 1,
|
||||
FullName: "bradrydzewski/drone",
|
||||
Owner: "bradrydzewski",
|
||||
Name: "drone",
|
||||
}
|
||||
s.Repos().Create(&repo)
|
||||
getrepo, err := s.Repos().GetName(repo.FullName)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.ID).Equal(getrepo.ID)
|
||||
g.Assert(repo.UserID).Equal(getrepo.UserID)
|
||||
g.Assert(repo.Owner).Equal(getrepo.Owner)
|
||||
g.Assert(repo.Name).Equal(getrepo.Name)
|
||||
})
|
||||
|
||||
// g.It("Should Get a Repo List by User", func() {
|
||||
// repo1 := model.Repo{
|
||||
// UserID: 1,
|
||||
// FullName: "bradrydzewski/drone",
|
||||
// Owner: "bradrydzewski",
|
||||
// Name: "drone",
|
||||
// }
|
||||
// repo2 := model.Repo{
|
||||
// UserID: 1,
|
||||
// FullName: "bradrydzewski/drone-dart",
|
||||
// Owner: "bradrydzewski",
|
||||
// Name: "drone-dart",
|
||||
// }
|
||||
// s.Repos().Create(&repo1)
|
||||
// s.Repos().Create(&repo2)
|
||||
// CreateBuild(db, &Build{RepoID: repo1.ID, Author: "bradrydzewski"})
|
||||
// CreateBuild(db, &Build{RepoID: repo1.ID, Author: "johnsmith"})
|
||||
// repos, err := GetRepoList(db, &User{ID: 1, Login: "bradrydzewski"})
|
||||
// g.Assert(err == nil).IsTrue()
|
||||
// g.Assert(len(repos)).Equal(1)
|
||||
// g.Assert(repos[0].UserID).Equal(repo1.UserID)
|
||||
// g.Assert(repos[0].Owner).Equal(repo1.Owner)
|
||||
// g.Assert(repos[0].Name).Equal(repo1.Name)
|
||||
// })
|
||||
|
||||
g.It("Should Delete a Repo", func() {
|
||||
repo := model.Repo{
|
||||
UserID: 1,
|
||||
FullName: "bradrydzewski/drone",
|
||||
Owner: "bradrydzewski",
|
||||
Name: "drone",
|
||||
}
|
||||
s.Repos().Create(&repo)
|
||||
_, err1 := s.Repos().Get(repo.ID)
|
||||
err2 := s.Repos().Delete(&repo)
|
||||
_, err3 := s.Repos().Get(repo.ID)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsFalse()
|
||||
})
|
||||
|
||||
g.It("Should Enforce Unique Repo Name", func() {
|
||||
repo1 := model.Repo{
|
||||
UserID: 1,
|
||||
FullName: "bradrydzewski/drone",
|
||||
Owner: "bradrydzewski",
|
||||
Name: "drone",
|
||||
}
|
||||
repo2 := model.Repo{
|
||||
UserID: 2,
|
||||
FullName: "bradrydzewski/drone",
|
||||
Owner: "bradrydzewski",
|
||||
Name: "drone",
|
||||
}
|
||||
err1 := s.Repos().Create(&repo1)
|
||||
err2 := s.Repos().Create(&repo2)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsFalse()
|
||||
})
|
||||
})
|
||||
}
|
103
store/datastore/store.go
Normal file
103
store/datastore/store.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"os"
|
||||
|
||||
"github.com/drone/drone/shared/envconfig"
|
||||
"github.com/drone/drone/store"
|
||||
"github.com/drone/drone/store/migration"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/rubenv/sql-migrate"
|
||||
"github.com/russross/meddler"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// From creates a datastore from an existing database connection.
|
||||
func From(db *sql.DB) store.Store {
|
||||
return store.New(
|
||||
&nodestore{db},
|
||||
&userstore{db},
|
||||
&repostore{db},
|
||||
&keystore{db},
|
||||
&buildstore{db},
|
||||
&jobstore{db},
|
||||
&logstore{db},
|
||||
)
|
||||
}
|
||||
|
||||
// Load opens a new database connection with the specified driver
|
||||
// and connection string specified in the environment variables.
|
||||
func Load(env envconfig.Env) store.Store {
|
||||
var (
|
||||
driver = env.String("DATABASE_DRIVER", "sqlite3")
|
||||
config = env.String("DATABASE_CONFIG", "drone.sqlite")
|
||||
)
|
||||
|
||||
log.Infof("using database driver %s", driver)
|
||||
log.Infof("using database config %s", config)
|
||||
|
||||
return From(
|
||||
Open(driver, config),
|
||||
)
|
||||
}
|
||||
|
||||
// Open opens a new database connection with the specified
|
||||
// driver and connection string and returns a store.
|
||||
func Open(driver, config string) *sql.DB {
|
||||
db, err := sql.Open(driver, config)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
log.Fatalln("database connection failed")
|
||||
}
|
||||
setupMeddler(driver)
|
||||
|
||||
if err := setupDatabase(driver, db); err != nil {
|
||||
log.Errorln(err)
|
||||
log.Fatalln("migration failed")
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
||||
// OpenTest opens a new database connection for testing purposes.
|
||||
// The database driver and connection string are provided by
|
||||
// environment variables, with fallback to in-memory sqlite.
|
||||
func openTest() *sql.DB {
|
||||
var (
|
||||
driver = "sqlite3"
|
||||
config = ":memory:"
|
||||
)
|
||||
if os.Getenv("DATABASE_DRIVER") != "" {
|
||||
driver = os.Getenv("DATABASE_DRIVER")
|
||||
config = os.Getenv("DATABASE_CONFIG")
|
||||
}
|
||||
return Open(driver, config)
|
||||
}
|
||||
|
||||
// helper function to setup the databsae by performing
|
||||
// automated database migration steps.
|
||||
func setupDatabase(driver string, db *sql.DB) error {
|
||||
var migrations = &migrate.AssetMigrationSource{
|
||||
Asset: migration.Asset,
|
||||
AssetDir: migration.AssetDir,
|
||||
Dir: driver,
|
||||
}
|
||||
_, err := migrate.Exec(db, driver, migrations, migrate.Up)
|
||||
return err
|
||||
}
|
||||
|
||||
// helper function to setup the meddler default driver
|
||||
// based on the selected driver name.
|
||||
func setupMeddler(driver string) {
|
||||
switch driver {
|
||||
case "sqlite3":
|
||||
meddler.Default = meddler.SQLite
|
||||
case "mysql":
|
||||
meddler.Default = meddler.MySQL
|
||||
case "postgres":
|
||||
meddler.Default = meddler.PostgreSQL
|
||||
}
|
||||
}
|
111
store/datastore/users.go
Normal file
111
store/datastore/users.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
type userstore struct {
|
||||
*sql.DB
|
||||
}
|
||||
|
||||
func (db *userstore) Get(id int64) (*model.User, error) {
|
||||
var usr = new(model.User)
|
||||
var err = meddler.Load(db, userTable, usr, id)
|
||||
return usr, err
|
||||
}
|
||||
|
||||
func (db *userstore) GetLogin(login string) (*model.User, error) {
|
||||
var usr = new(model.User)
|
||||
var err = meddler.QueryRow(db, usr, rebind(userLoginQuery), login)
|
||||
return usr, err
|
||||
}
|
||||
|
||||
func (db *userstore) GetList() ([]*model.User, error) {
|
||||
var users = []*model.User{}
|
||||
var err = meddler.QueryAll(db, &users, rebind(userListQuery))
|
||||
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) Count() (int, error) {
|
||||
var count int
|
||||
var err = db.QueryRow(rebind(userCountQuery)).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (db *userstore) Create(user *model.User) error {
|
||||
return meddler.Insert(db, userTable, user)
|
||||
}
|
||||
|
||||
func (db *userstore) Update(user *model.User) error {
|
||||
return meddler.Update(db, userTable, user)
|
||||
}
|
||||
|
||||
func (db *userstore) Delete(user *model.User) error {
|
||||
var _, err = db.Exec(rebind(userDeleteStmt), user.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
const userTable = "users"
|
||||
|
||||
const userLoginQuery = `
|
||||
SELECT *
|
||||
FROM users
|
||||
WHERE user_login=?
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
const userListQuery = `
|
||||
SELECT *
|
||||
FROM users
|
||||
ORDER BY user_login ASC
|
||||
`
|
||||
|
||||
const userCountQuery = `
|
||||
SELECT count(1)
|
||||
FROM users
|
||||
`
|
||||
|
||||
const userDeleteStmt = `
|
||||
DELETE FROM users
|
||||
WHERE user_id=?
|
||||
`
|
||||
|
||||
const userFeedQuery = `
|
||||
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
|
||||
builds b
|
||||
,repos r
|
||||
WHERE b.build_repo_id = r.repo_id
|
||||
AND b.build_author = ?
|
||||
ORDER BY b.build_id DESC
|
||||
LIMIT ? OFFSET ?
|
||||
`
|
209
store/datastore/users_test.go
Normal file
209
store/datastore/users_test.go
Normal file
@@ -0,0 +1,209 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"github.com/franela/goblin"
|
||||
)
|
||||
|
||||
func Test_userstore(t *testing.T) {
|
||||
db := openTest()
|
||||
defer db.Close()
|
||||
s := From(db)
|
||||
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("User", func() {
|
||||
|
||||
// before each test be sure to purge the package
|
||||
// table data from the database.
|
||||
g.BeforeEach(func() {
|
||||
db.Exec("DELETE FROM users")
|
||||
db.Exec("DELETE FROM repos")
|
||||
db.Exec("DELETE FROM builds")
|
||||
db.Exec("DELETE FROM jobs")
|
||||
})
|
||||
|
||||
g.It("Should Update a User", func() {
|
||||
user := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "e42080dddf012c718e476da161d21ad5",
|
||||
}
|
||||
err1 := s.Users().Create(&user)
|
||||
err2 := s.Users().Update(&user)
|
||||
getuser, err3 := s.Users().Get(user.ID)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
g.Assert(err3 == nil).IsTrue()
|
||||
g.Assert(user.ID).Equal(getuser.ID)
|
||||
})
|
||||
|
||||
g.It("Should Add a new User", func() {
|
||||
user := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "e42080dddf012c718e476da161d21ad5",
|
||||
}
|
||||
err := s.Users().Create(&user)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(user.ID != 0).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should Get a User", func() {
|
||||
user := model.User{
|
||||
Login: "joe",
|
||||
Token: "f0b461ca586c27872b43a0685cbc2847",
|
||||
Secret: "976f22a5eef7caacb7e678d6c52f49b1",
|
||||
Email: "foo@bar.com",
|
||||
Avatar: "b9015b0857e16ac4d94a0ffd9a0b79c8",
|
||||
Active: true,
|
||||
Admin: true,
|
||||
}
|
||||
|
||||
s.Users().Create(&user)
|
||||
getuser, err := s.Users().Get(user.ID)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(user.ID).Equal(getuser.ID)
|
||||
g.Assert(user.Login).Equal(getuser.Login)
|
||||
g.Assert(user.Token).Equal(getuser.Token)
|
||||
g.Assert(user.Secret).Equal(getuser.Secret)
|
||||
g.Assert(user.Email).Equal(getuser.Email)
|
||||
g.Assert(user.Avatar).Equal(getuser.Avatar)
|
||||
g.Assert(user.Active).Equal(getuser.Active)
|
||||
g.Assert(user.Admin).Equal(getuser.Admin)
|
||||
})
|
||||
|
||||
g.It("Should Get a User By Login", func() {
|
||||
user := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "e42080dddf012c718e476da161d21ad5",
|
||||
}
|
||||
s.Users().Create(&user)
|
||||
getuser, err := s.Users().GetLogin(user.Login)
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(user.ID).Equal(getuser.ID)
|
||||
g.Assert(user.Login).Equal(getuser.Login)
|
||||
})
|
||||
|
||||
g.It("Should Enforce Unique User Login", func() {
|
||||
user1 := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "e42080dddf012c718e476da161d21ad5",
|
||||
}
|
||||
user2 := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "ab20g0ddaf012c744e136da16aa21ad9",
|
||||
}
|
||||
err1 := s.Users().Create(&user1)
|
||||
err2 := s.Users().Create(&user2)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsFalse()
|
||||
})
|
||||
|
||||
g.It("Should Get a User List", func() {
|
||||
user1 := model.User{
|
||||
Login: "jane",
|
||||
Email: "foo@bar.com",
|
||||
Token: "ab20g0ddaf012c744e136da16aa21ad9",
|
||||
}
|
||||
user2 := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "e42080dddf012c718e476da161d21ad5",
|
||||
}
|
||||
s.Users().Create(&user1)
|
||||
s.Users().Create(&user2)
|
||||
users, err := s.Users().GetList()
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(users)).Equal(2)
|
||||
g.Assert(users[0].Login).Equal(user1.Login)
|
||||
g.Assert(users[0].Email).Equal(user1.Email)
|
||||
g.Assert(users[0].Token).Equal(user1.Token)
|
||||
})
|
||||
|
||||
g.It("Should Get a User Count", func() {
|
||||
user1 := model.User{
|
||||
Login: "jane",
|
||||
Email: "foo@bar.com",
|
||||
Token: "ab20g0ddaf012c744e136da16aa21ad9",
|
||||
}
|
||||
user2 := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "e42080dddf012c718e476da161d21ad5",
|
||||
}
|
||||
s.Users().Create(&user1)
|
||||
s.Users().Create(&user2)
|
||||
count, err := s.Users().Count()
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(count).Equal(2)
|
||||
})
|
||||
|
||||
g.It("Should Get a User Count Zero", func() {
|
||||
count, err := s.Users().Count()
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(count).Equal(0)
|
||||
})
|
||||
|
||||
g.It("Should Del a User", func() {
|
||||
user := model.User{
|
||||
Login: "joe",
|
||||
Email: "foo@bar.com",
|
||||
Token: "e42080dddf012c718e476da161d21ad5",
|
||||
}
|
||||
s.Users().Create(&user)
|
||||
_, err1 := s.Users().Get(user.ID)
|
||||
err2 := s.Users().Delete(&user)
|
||||
_, err3 := s.Users().Get(user.ID)
|
||||
g.Assert(err1 == nil).IsTrue()
|
||||
g.Assert(err2 == nil).IsTrue()
|
||||
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)
|
||||
|
||||
// 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)
|
||||
|
||||
// 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")
|
||||
// })
|
||||
})
|
||||
}
|
35
store/datastore/utils.go
Normal file
35
store/datastore/utils.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package datastore
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/russross/meddler"
|
||||
)
|
||||
|
||||
// rebind is a helper function that changes the sql
|
||||
// bind type from ? to $ for postgres queries.
|
||||
func rebind(query string) string {
|
||||
if meddler.Default != meddler.PostgreSQL {
|
||||
return query
|
||||
}
|
||||
|
||||
qb := []byte(query)
|
||||
// Add space enough for 5 params before we have to allocate
|
||||
rqb := make([]byte, 0, len(qb)+5)
|
||||
j := 1
|
||||
for _, b := range qb {
|
||||
switch b {
|
||||
case '?':
|
||||
rqb = append(rqb, '$')
|
||||
for _, b := range strconv.Itoa(j) {
|
||||
rqb = append(rqb, byte(b))
|
||||
}
|
||||
j++
|
||||
case '`':
|
||||
rqb = append(rqb, ' ')
|
||||
default:
|
||||
rqb = append(rqb, b)
|
||||
}
|
||||
}
|
||||
return string(rqb)
|
||||
}
|
43
store/jobs.go
Normal file
43
store/jobs.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type JobStore interface {
|
||||
// Get gets a job by unique ID.
|
||||
Get(int64) (*model.Job, error)
|
||||
|
||||
// GetNumber gets a job by number.
|
||||
GetNumber(*model.Build, int) (*model.Job, error)
|
||||
|
||||
// GetList gets a list of all users in the system.
|
||||
GetList(*model.Build) ([]*model.Job, error)
|
||||
|
||||
// Create creates a job.
|
||||
Create(*model.Job) error
|
||||
|
||||
// Update updates a job.
|
||||
Update(*model.Job) error
|
||||
}
|
||||
|
||||
func GetJob(c context.Context, id int64) (*model.Job, error) {
|
||||
return FromContext(c).Jobs().Get(id)
|
||||
}
|
||||
|
||||
func GetJobNumber(c context.Context, build *model.Build, num int) (*model.Job, error) {
|
||||
return FromContext(c).Jobs().GetNumber(build, num)
|
||||
}
|
||||
|
||||
func GetJobList(c context.Context, build *model.Build) ([]*model.Job, error) {
|
||||
return FromContext(c).Jobs().GetList(build)
|
||||
}
|
||||
|
||||
func CreateJob(c context.Context, job *model.Job) error {
|
||||
return FromContext(c).Jobs().Create(job)
|
||||
}
|
||||
|
||||
func UpdateJob(c context.Context, job *model.Job) error {
|
||||
return FromContext(c).Jobs().Update(job)
|
||||
}
|
36
store/keys.go
Normal file
36
store/keys.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type KeyStore interface {
|
||||
// Get gets a key by unique repository ID.
|
||||
Get(*model.Repo) (*model.Key, error)
|
||||
|
||||
// Create creates a new key.
|
||||
Create(*model.Key) error
|
||||
|
||||
// Update updates a user key.
|
||||
Update(*model.Key) error
|
||||
|
||||
// Delete deletes a user key.
|
||||
Delete(*model.Key) error
|
||||
}
|
||||
|
||||
func GetKey(c context.Context, repo *model.Repo) (*model.Key, error) {
|
||||
return FromContext(c).Keys().Get(repo)
|
||||
}
|
||||
|
||||
func CreateKey(c context.Context, key *model.Key) error {
|
||||
return FromContext(c).Keys().Create(key)
|
||||
}
|
||||
|
||||
func UpdateKey(c context.Context, key *model.Key) error {
|
||||
return FromContext(c).Keys().Update(key)
|
||||
}
|
||||
|
||||
func DeleteKey(c context.Context, key *model.Key) error {
|
||||
return FromContext(c).Keys().Delete(key)
|
||||
}
|
24
store/logs.go
Normal file
24
store/logs.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type LogStore interface {
|
||||
// Read reads the Job logs from the datastore.
|
||||
Read(*model.Job) (io.ReadCloser, error)
|
||||
|
||||
// Write writes the job logs to the datastore.
|
||||
Write(*model.Job, io.Reader) error
|
||||
}
|
||||
|
||||
func ReadLog(c context.Context, job *model.Job) (io.ReadCloser, error) {
|
||||
return FromContext(c).Logs().Read(job)
|
||||
}
|
||||
|
||||
func WriteLog(c context.Context, job *model.Job, r io.Reader) error {
|
||||
return FromContext(c).Logs().Write(job, r)
|
||||
}
|
3
store/migration/migration.go
Normal file
3
store/migration/migration.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package migration
|
||||
|
||||
//go:generate go-bindata -pkg migration -o migration_gen.go sqlite3/ mysql/ postgres/
|
125
store/migration/mysql/1_init.sql
Normal file
125
store/migration/mysql/1_init.sql
Normal file
@@ -0,0 +1,125 @@
|
||||
-- +migrate Up
|
||||
|
||||
CREATE TABLE users (
|
||||
user_id INTEGER PRIMARY KEY AUTO_INCREMENT
|
||||
,user_login VARCHAR(500)
|
||||
,user_token VARCHAR(500)
|
||||
,user_secret VARCHAR(500)
|
||||
,user_expiry INTEGER
|
||||
,user_email VARCHAR(500)
|
||||
,user_avatar VARCHAR(500)
|
||||
,user_active BOOLEAN
|
||||
,user_admin BOOLEAN
|
||||
,user_hash VARCHAR(500)
|
||||
|
||||
,UNIQUE(user_login)
|
||||
);
|
||||
|
||||
CREATE TABLE repos (
|
||||
repo_id INTEGER PRIMARY KEY AUTO_INCREMENT
|
||||
,repo_user_id INTEGER
|
||||
,repo_owner VARCHAR(255)
|
||||
,repo_name VARCHAR(255)
|
||||
,repo_full_name VARCHAR(511)
|
||||
,repo_avatar VARCHAR(500)
|
||||
,repo_link VARCHAR(1000)
|
||||
,repo_clone VARCHAR(1000)
|
||||
,repo_branch VARCHAR(500)
|
||||
,repo_timeout INTEGER
|
||||
,repo_private BOOLEAN
|
||||
,repo_trusted BOOLEAN
|
||||
,repo_allow_pr BOOLEAN
|
||||
,repo_allow_push BOOLEAN
|
||||
,repo_allow_deploys BOOLEAN
|
||||
,repo_allow_tags BOOLEAN
|
||||
,repo_hash VARCHAR(500)
|
||||
|
||||
,UNIQUE(repo_full_name)
|
||||
);
|
||||
|
||||
CREATE TABLE `keys` (
|
||||
key_id INTEGER PRIMARY KEY AUTO_INCREMENT
|
||||
,key_repo_id INTEGER
|
||||
,key_public MEDIUMBLOB
|
||||
,key_private MEDIUMBLOB
|
||||
|
||||
,UNIQUE(key_repo_id)
|
||||
);
|
||||
|
||||
CREATE TABLE builds (
|
||||
build_id INTEGER PRIMARY KEY AUTO_INCREMENT
|
||||
,build_repo_id INTEGER
|
||||
,build_number INTEGER
|
||||
,build_event VARCHAR(500)
|
||||
,build_status VARCHAR(500)
|
||||
,build_enqueued INTEGER
|
||||
,build_created INTEGER
|
||||
,build_started INTEGER
|
||||
,build_finished INTEGER
|
||||
,build_commit VARCHAR(500)
|
||||
,build_branch VARCHAR(500)
|
||||
,build_ref VARCHAR(500)
|
||||
,build_refspec VARCHAR(1000)
|
||||
,build_remote VARCHAR(500)
|
||||
,build_title VARCHAR(1000)
|
||||
,build_message VARCHAR(2000)
|
||||
,build_timestamp INTEGER
|
||||
,build_author VARCHAR(500)
|
||||
,build_avatar VARCHAR(1000)
|
||||
,build_email VARCHAR(500)
|
||||
,build_link VARCHAR(1000)
|
||||
|
||||
,UNIQUE(build_number, build_repo_id)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_build_repo ON builds (build_repo_id);
|
||||
|
||||
CREATE TABLE jobs (
|
||||
job_id INTEGER PRIMARY KEY AUTO_INCREMENT
|
||||
,job_node_id INTEGER
|
||||
,job_build_id INTEGER
|
||||
,job_number INTEGER
|
||||
,job_status VARCHAR(500)
|
||||
,job_exit_code INTEGER
|
||||
,job_started INTEGER
|
||||
,job_enqueued INTEGER
|
||||
,job_finished INTEGER
|
||||
,job_environment VARCHAR(2000)
|
||||
|
||||
,UNIQUE(job_build_id, job_number)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_job_build ON jobs (job_build_id);
|
||||
CREATE INDEX ix_job_node ON jobs (job_node_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS logs (
|
||||
log_id INTEGER PRIMARY KEY AUTO_INCREMENT
|
||||
,log_job_id INTEGER
|
||||
,log_data MEDIUMBLOB
|
||||
|
||||
,UNIQUE(log_job_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS nodes (
|
||||
node_id INTEGER PRIMARY KEY AUTO_INCREMENT
|
||||
,node_addr VARCHAR(1024)
|
||||
,node_arch VARCHAR(50)
|
||||
,node_cert MEDIUMBLOB
|
||||
,node_key MEDIUMBLOB
|
||||
,node_ca MEDIUMBLOB
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO nodes VALUES(null, 'unix:///var/run/docker.sock', 'linux_amd64', '', '', '');
|
||||
INSERT INTO nodes VALUES(null, 'unix:///var/run/docker.sock', 'linux_amd64', '', '', '');
|
||||
|
||||
-- +migrate Down
|
||||
|
||||
DROP TABLE nodes;
|
||||
DROP TABLE logs;
|
||||
DROP TABLE jobs;
|
||||
DROP TABLE builds;
|
||||
DROP TABLE `keys`;
|
||||
DROP TABLE stars;
|
||||
DROP TABLE repos;
|
||||
DROP TABLE users;
|
126
store/migration/postgres/1_init.sql
Normal file
126
store/migration/postgres/1_init.sql
Normal file
@@ -0,0 +1,126 @@
|
||||
-- +migrate Up
|
||||
|
||||
CREATE TABLE users (
|
||||
user_id SERIAL PRIMARY KEY
|
||||
,user_login VARCHAR(40)
|
||||
,user_token VARCHAR(128)
|
||||
,user_secret VARCHAR(128)
|
||||
,user_expiry INTEGER
|
||||
,user_email VARCHAR(256)
|
||||
,user_avatar VARCHAR(256)
|
||||
,user_active BOOLEAN
|
||||
,user_admin BOOLEAN
|
||||
,user_hash VARCHAR(128)
|
||||
|
||||
,UNIQUE(user_login)
|
||||
);
|
||||
|
||||
CREATE TABLE repos (
|
||||
repo_id SERIAL PRIMARY KEY
|
||||
,repo_user_id INTEGER
|
||||
,repo_owner VARCHAR(255)
|
||||
,repo_name VARCHAR(255)
|
||||
,repo_full_name VARCHAR(511)
|
||||
,repo_avatar VARCHAR(500)
|
||||
,repo_link VARCHAR(1000)
|
||||
,repo_clone VARCHAR(1000)
|
||||
,repo_branch VARCHAR(500)
|
||||
,repo_timeout INTEGER
|
||||
,repo_private BOOLEAN
|
||||
,repo_trusted BOOLEAN
|
||||
,repo_allow_pr BOOLEAN
|
||||
,repo_allow_push BOOLEAN
|
||||
,repo_allow_deploys BOOLEAN
|
||||
,repo_allow_tags BOOLEAN
|
||||
,repo_hash VARCHAR(500)
|
||||
|
||||
,UNIQUE(repo_full_name)
|
||||
);
|
||||
|
||||
CREATE TABLE keys (
|
||||
key_id SERIAL PRIMARY KEY
|
||||
,key_repo_id INTEGER
|
||||
,key_public BYTEA
|
||||
,key_private BYTEA
|
||||
|
||||
,UNIQUE(key_repo_id)
|
||||
);
|
||||
|
||||
CREATE TABLE builds (
|
||||
build_id SERIAL PRIMARY KEY
|
||||
,build_repo_id INTEGER
|
||||
,build_number INTEGER
|
||||
,build_event VARCHAR(25)
|
||||
,build_status VARCHAR(25)
|
||||
,build_enqueued INTEGER
|
||||
,build_created INTEGER
|
||||
,build_started INTEGER
|
||||
,build_finished INTEGER
|
||||
,build_commit VARCHAR(40)
|
||||
,build_branch VARCHAR(256)
|
||||
,build_ref VARCHAR(512)
|
||||
,build_refspec VARCHAR(512)
|
||||
,build_remote VARCHAR(512)
|
||||
,build_title VARCHAR(1000)
|
||||
,build_message VARCHAR(2000)
|
||||
,build_timestamp INTEGER
|
||||
,build_author VARCHAR(40)
|
||||
,build_avatar VARCHAR(1000)
|
||||
,build_email VARCHAR(500)
|
||||
,build_link VARCHAR(1000)
|
||||
|
||||
,UNIQUE(build_number, build_repo_id)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_build_repo ON builds (build_repo_id);
|
||||
|
||||
CREATE TABLE jobs (
|
||||
job_id SERIAL PRIMARY KEY
|
||||
,job_node_id INTEGER
|
||||
,job_build_id INTEGER
|
||||
,job_number INTEGER
|
||||
,job_status VARCHAR(25)
|
||||
,job_exit_code INTEGER
|
||||
,job_started INTEGER
|
||||
,job_enqueued INTEGER
|
||||
,job_finished INTEGER
|
||||
,job_environment VARCHAR(2000)
|
||||
|
||||
,UNIQUE(job_build_id, job_number)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_job_build ON jobs (job_build_id);
|
||||
CREATE INDEX ix_job_node ON jobs (job_node_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS logs (
|
||||
log_id SERIAL PRIMARY KEY
|
||||
,log_job_id INTEGER
|
||||
,log_data BYTEA
|
||||
|
||||
,UNIQUE(log_job_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS nodes (
|
||||
node_id SERIAL PRIMARY KEY
|
||||
,node_addr VARCHAR(1024)
|
||||
,node_arch VARCHAR(50)
|
||||
,node_cert BYTEA
|
||||
,node_key BYTEA
|
||||
,node_ca BYTEA
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO nodes (node_addr, node_arch, node_cert, node_key, node_ca) VALUES
|
||||
('unix:///var/run/docker.sock', 'linux_amd64', '', '', ''),
|
||||
('unix:///var/run/docker.sock', 'linux_amd64', '', '', '');
|
||||
|
||||
-- +migrate Down
|
||||
|
||||
DROP TABLE nodes;
|
||||
DROP TABLE logs;
|
||||
DROP TABLE jobs;
|
||||
DROP TABLE builds;
|
||||
DROP TABLE keys;
|
||||
DROP TABLE stars;
|
||||
DROP TABLE repos;
|
||||
DROP TABLE users;
|
135
store/migration/sqlite3/1_init.sql
Normal file
135
store/migration/sqlite3/1_init.sql
Normal file
@@ -0,0 +1,135 @@
|
||||
-- +migrate Up
|
||||
|
||||
CREATE TABLE users (
|
||||
user_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,user_login TEXT
|
||||
,user_token TEXT
|
||||
,user_secret TEXT
|
||||
,user_expiry INTEGER
|
||||
,user_email TEXT
|
||||
,user_avatar TEXT
|
||||
,user_active BOOLEAN
|
||||
,user_admin BOOLEAN
|
||||
,user_hash TEXT
|
||||
|
||||
,UNIQUE(user_login)
|
||||
);
|
||||
|
||||
CREATE TABLE repos (
|
||||
repo_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,repo_user_id INTEGER
|
||||
,repo_owner TEXT
|
||||
,repo_name TEXT
|
||||
,repo_full_name TEXT
|
||||
,repo_avatar TEXT
|
||||
,repo_link TEXT
|
||||
,repo_clone TEXT
|
||||
,repo_branch TEXT
|
||||
,repo_timeout INTEGER
|
||||
,repo_private BOOLEAN
|
||||
,repo_trusted BOOLEAN
|
||||
,repo_allow_pr BOOLEAN
|
||||
,repo_allow_push BOOLEAN
|
||||
,repo_allow_deploys BOOLEAN
|
||||
,repo_allow_tags BOOLEAN
|
||||
,repo_hash TEXT
|
||||
|
||||
,UNIQUE(repo_full_name)
|
||||
);
|
||||
|
||||
CREATE TABLE stars (
|
||||
star_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,star_repo_id INTEGER
|
||||
,star_user_id INTEGER
|
||||
|
||||
,UNIQUE(star_repo_id, star_user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_star_user ON stars (star_user_id);
|
||||
|
||||
CREATE TABLE keys (
|
||||
key_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,key_repo_id INTEGER
|
||||
,key_public BLOB
|
||||
,key_private BLOB
|
||||
|
||||
,UNIQUE(key_repo_id)
|
||||
);
|
||||
|
||||
CREATE TABLE builds (
|
||||
build_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,build_repo_id INTEGER
|
||||
,build_number INTEGER
|
||||
,build_event TEXT
|
||||
,build_status TEXT
|
||||
,build_enqueued INTEGER
|
||||
,build_created INTEGER
|
||||
,build_started INTEGER
|
||||
,build_finished INTEGER
|
||||
,build_commit TEXT
|
||||
,build_branch TEXT
|
||||
,build_ref TEXT
|
||||
,build_refspec TEXT
|
||||
,build_remote TEXT
|
||||
,build_title TEXT
|
||||
,build_message TEXT
|
||||
,build_timestamp INTEGER
|
||||
,build_author TEXT
|
||||
,build_avatar TEXT
|
||||
,build_email TEXT
|
||||
,build_link TEXT
|
||||
|
||||
,UNIQUE(build_number, build_repo_id)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_build_repo ON builds (build_repo_id);
|
||||
CREATE INDEX ix_build_author ON builds (build_author);
|
||||
|
||||
CREATE TABLE jobs (
|
||||
job_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,job_node_id INTEGER
|
||||
,job_build_id INTEGER
|
||||
,job_number INTEGER
|
||||
,job_status TEXT
|
||||
,job_exit_code INTEGER
|
||||
,job_enqueued INTEGER
|
||||
,job_started INTEGER
|
||||
,job_finished INTEGER
|
||||
,job_environment TEXT
|
||||
|
||||
,UNIQUE(job_build_id, job_number)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_job_build ON jobs (job_build_id);
|
||||
CREATE INDEX ix_job_node ON jobs (job_node_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS logs (
|
||||
log_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,log_job_id INTEGER
|
||||
,log_data BLOB
|
||||
|
||||
,UNIQUE(log_job_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS nodes (
|
||||
node_id INTEGER PRIMARY KEY AUTOINCREMENT
|
||||
,node_addr TEXT
|
||||
,node_arch TEXT
|
||||
,node_cert BLOB
|
||||
,node_key BLOB
|
||||
,node_ca BLOB
|
||||
);
|
||||
|
||||
INSERT INTO nodes VALUES(null, 'unix:///var/run/docker.sock', 'linux_amd64', '', '', '');
|
||||
INSERT INTO nodes VALUES(null, 'unix:///var/run/docker.sock', 'linux_amd64', '', '', '');
|
||||
|
||||
-- +migrate Down
|
||||
|
||||
DROP TABLE nodes;
|
||||
DROP TABLE logs;
|
||||
DROP TABLE jobs;
|
||||
DROP TABLE builds;
|
||||
DROP TABLE keys;
|
||||
DROP TABLE stars;
|
||||
DROP TABLE repos;
|
||||
DROP TABLE users;
|
50
store/nodes.go
Normal file
50
store/nodes.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type NodeStore interface {
|
||||
// Get gets a user by unique ID.
|
||||
Get(int64) (*model.Node, error)
|
||||
|
||||
// GetList gets a list of all nodes in the system.
|
||||
GetList() ([]*model.Node, error)
|
||||
|
||||
// Count gets a count of all nodes in the system.
|
||||
Count() (int, error)
|
||||
|
||||
// Create creates a node.
|
||||
Create(*model.Node) error
|
||||
|
||||
// Update updates a node.
|
||||
Update(*model.Node) error
|
||||
|
||||
// Delete deletes a node.
|
||||
Delete(*model.Node) error
|
||||
}
|
||||
|
||||
func GetNode(c context.Context, id int64) (*model.Node, error) {
|
||||
return FromContext(c).Nodes().Get(id)
|
||||
}
|
||||
|
||||
func GetNodeList(c context.Context) ([]*model.Node, error) {
|
||||
return FromContext(c).Nodes().GetList()
|
||||
}
|
||||
|
||||
func CountNodes(c context.Context) (int, error) {
|
||||
return FromContext(c).Nodes().Count()
|
||||
}
|
||||
|
||||
func CreateNode(c context.Context, node *model.Node) error {
|
||||
return FromContext(c).Nodes().Create(node)
|
||||
}
|
||||
|
||||
func UpdateNode(c context.Context, node *model.Node) error {
|
||||
return FromContext(c).Nodes().Update(node)
|
||||
}
|
||||
|
||||
func DeleteNode(c context.Context, node *model.Node) error {
|
||||
return FromContext(c).Nodes().Delete(node)
|
||||
}
|
61
store/repos.go
Normal file
61
store/repos.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type RepoStore interface {
|
||||
// Get gets a repo by unique ID.
|
||||
Get(int64) (*model.Repo, error)
|
||||
|
||||
// GetLogin gets a repo by its full name.
|
||||
GetName(string) (*model.Repo, error)
|
||||
|
||||
// GetListOf gets the list of enumerated repos in the system.
|
||||
GetListOf([]*model.RepoLite) ([]*model.Repo, error)
|
||||
|
||||
// Count gets a count of all repos in the system.
|
||||
Count() (int, error)
|
||||
|
||||
// Create creates a new repository.
|
||||
Create(*model.Repo) error
|
||||
|
||||
// Update updates a user repository.
|
||||
Update(*model.Repo) error
|
||||
|
||||
// Delete deletes a user repository.
|
||||
Delete(*model.Repo) error
|
||||
}
|
||||
|
||||
func GetRepo(c context.Context, id int64) (*model.Repo, error) {
|
||||
return FromContext(c).Repos().Get(id)
|
||||
}
|
||||
|
||||
func GetRepoName(c context.Context, name string) (*model.Repo, error) {
|
||||
return FromContext(c).Repos().GetName(name)
|
||||
}
|
||||
|
||||
func GetRepoOwnerName(c context.Context, owner, name string) (*model.Repo, error) {
|
||||
return FromContext(c).Repos().GetName(owner + "/" + name)
|
||||
}
|
||||
|
||||
func GetRepoListOf(c context.Context, listof []*model.RepoLite) ([]*model.Repo, error) {
|
||||
return FromContext(c).Repos().GetListOf(listof)
|
||||
}
|
||||
|
||||
func CountRepos(c context.Context) (int, error) {
|
||||
return FromContext(c).Repos().Count()
|
||||
}
|
||||
|
||||
func CreateRepo(c context.Context, repo *model.Repo) error {
|
||||
return FromContext(c).Repos().Create(repo)
|
||||
}
|
||||
|
||||
func UpdateRepo(c context.Context, repo *model.Repo) error {
|
||||
return FromContext(c).Repos().Update(repo)
|
||||
}
|
||||
|
||||
func DeleteRepo(c context.Context, repo *model.Repo) error {
|
||||
return FromContext(c).Repos().Update(repo)
|
||||
}
|
49
store/store.go
Normal file
49
store/store.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package store
|
||||
|
||||
type Store interface {
|
||||
Nodes() NodeStore
|
||||
Users() UserStore
|
||||
Repos() RepoStore
|
||||
Keys() KeyStore
|
||||
Builds() BuildStore
|
||||
Jobs() JobStore
|
||||
Logs() LogStore
|
||||
}
|
||||
|
||||
type store struct {
|
||||
nodes NodeStore
|
||||
users UserStore
|
||||
repos RepoStore
|
||||
keys KeyStore
|
||||
builds BuildStore
|
||||
jobs JobStore
|
||||
logs LogStore
|
||||
}
|
||||
|
||||
func (s *store) Nodes() NodeStore { return s.nodes }
|
||||
func (s *store) Users() UserStore { return s.users }
|
||||
func (s *store) Repos() RepoStore { return s.repos }
|
||||
func (s *store) Keys() KeyStore { return s.keys }
|
||||
func (s *store) Builds() BuildStore { return s.builds }
|
||||
func (s *store) Jobs() JobStore { return s.jobs }
|
||||
func (s *store) Logs() LogStore { return s.logs }
|
||||
|
||||
func New(
|
||||
nodes NodeStore,
|
||||
users UserStore,
|
||||
repos RepoStore,
|
||||
keys KeyStore,
|
||||
builds BuildStore,
|
||||
jobs JobStore,
|
||||
logs LogStore,
|
||||
) Store {
|
||||
return &store{
|
||||
nodes,
|
||||
users,
|
||||
repos,
|
||||
keys,
|
||||
builds,
|
||||
jobs,
|
||||
logs,
|
||||
}
|
||||
}
|
64
store/users.go
Normal file
64
store/users.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"github.com/drone/drone/model"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
type UserStore interface {
|
||||
// Get gets a user by unique ID.
|
||||
Get(int64) (*model.User, error)
|
||||
|
||||
// GetLogin gets a user by unique Login name.
|
||||
GetLogin(string) (*model.User, error)
|
||||
|
||||
// GetList gets a list of all users in the system.
|
||||
GetList() ([]*model.User, error)
|
||||
|
||||
// GetFeed gets a user activity feed.
|
||||
GetFeed(*model.User, int, int) ([]*model.Feed, error)
|
||||
|
||||
// Count gets a count of all users in the system.
|
||||
Count() (int, error)
|
||||
|
||||
// Create creates a new user account.
|
||||
Create(*model.User) error
|
||||
|
||||
// Update updates a user account.
|
||||
Update(*model.User) error
|
||||
|
||||
// Delete deletes a user account.
|
||||
Delete(*model.User) error
|
||||
}
|
||||
|
||||
func GetUser(c context.Context, id int64) (*model.User, error) {
|
||||
return FromContext(c).Users().Get(id)
|
||||
}
|
||||
|
||||
func GetUserLogin(c context.Context, login string) (*model.User, error) {
|
||||
return FromContext(c).Users().GetLogin(login)
|
||||
}
|
||||
|
||||
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 CountUsers(c context.Context) (int, error) {
|
||||
return FromContext(c).Users().Count()
|
||||
}
|
||||
|
||||
func CreateUser(c context.Context, user *model.User) error {
|
||||
return FromContext(c).Users().Create(user)
|
||||
}
|
||||
|
||||
func UpdateUser(c context.Context, user *model.User) error {
|
||||
return FromContext(c).Users().Update(user)
|
||||
}
|
||||
|
||||
func DeleteUser(c context.Context, user *model.User) error {
|
||||
return FromContext(c).Users().Delete(user)
|
||||
}
|
Reference in New Issue
Block a user