2014-09-26 10:10:48 +03:00
|
|
|
package database
|
2014-09-25 11:07:40 +03:00
|
|
|
|
|
|
|
import (
|
2014-10-14 11:49:10 +03:00
|
|
|
"time"
|
|
|
|
|
2014-09-25 11:07:40 +03:00
|
|
|
"github.com/drone/drone/shared/model"
|
|
|
|
"github.com/russross/meddler"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Commitstore struct {
|
|
|
|
meddler.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewCommitstore(db meddler.DB) *Commitstore {
|
|
|
|
return &Commitstore{db}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCommit retrieves a commit from the
|
|
|
|
// datastore for the given ID.
|
|
|
|
func (db *Commitstore) GetCommit(id int64) (*model.Commit, error) {
|
|
|
|
var commit = new(model.Commit)
|
|
|
|
var err = meddler.Load(db, commitTable, commit, id)
|
|
|
|
return commit, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCommitSha retrieves a commit from the
|
|
|
|
// datastore for the specified repo and sha
|
|
|
|
func (db *Commitstore) GetCommitSha(repo *model.Repo, branch, sha string) (*model.Commit, error) {
|
|
|
|
var commit = new(model.Commit)
|
2014-09-26 10:10:48 +03:00
|
|
|
var err = meddler.QueryRow(db, commit, rebind(commitShaQuery), repo.ID, branch, sha)
|
2014-09-25 11:07:40 +03:00
|
|
|
return commit, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCommitLast retrieves the latest commit
|
|
|
|
// from the datastore for the specified repository
|
|
|
|
// and branch.
|
|
|
|
func (db *Commitstore) GetCommitLast(repo *model.Repo, branch string) (*model.Commit, error) {
|
|
|
|
var commit = new(model.Commit)
|
2014-09-26 10:10:48 +03:00
|
|
|
var err = meddler.QueryRow(db, commit, rebind(commitLastQuery), repo.ID, branch)
|
2014-09-25 11:07:40 +03:00
|
|
|
return commit, err
|
|
|
|
}
|
|
|
|
|
2014-12-30 18:37:57 +02:00
|
|
|
// GetCommitPrior retrieves the latest commit
|
|
|
|
// from the datastore for the specified repository
|
|
|
|
// and branch.
|
|
|
|
func (db *Commitstore) GetCommitPrior(oldCommit *model.Commit) (*model.Commit, error) {
|
|
|
|
var commit = new(model.Commit)
|
|
|
|
var err = meddler.QueryRow(db, commit, rebind(commitPriorQuery), oldCommit.RepoID, oldCommit.Branch, oldCommit.Created)
|
|
|
|
return commit, err
|
|
|
|
}
|
|
|
|
|
2014-09-25 11:07:40 +03:00
|
|
|
// GetCommitList retrieves a list of latest commits
|
|
|
|
// from the datastore for the specified repository.
|
|
|
|
func (db *Commitstore) GetCommitList(repo *model.Repo) ([]*model.Commit, error) {
|
|
|
|
var commits []*model.Commit
|
2014-09-27 23:09:55 +03:00
|
|
|
var err = meddler.QueryAll(db, &commits, rebind(commitListQuery), repo.ID)
|
2014-09-25 11:07:40 +03:00
|
|
|
return commits, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCommitListUser retrieves a list of latest commits
|
|
|
|
// from the datastore accessible to the specified user.
|
2014-10-01 21:29:23 +03:00
|
|
|
func (db *Commitstore) GetCommitListUser(user *model.User) ([]*model.CommitRepo, error) {
|
|
|
|
var commits []*model.CommitRepo
|
|
|
|
var err = meddler.QueryAll(db, &commits, rebind(commitListUserQuery), user.ID)
|
|
|
|
return commits, err
|
2014-09-25 11:07:40 +03:00
|
|
|
}
|
|
|
|
|
2014-11-07 18:04:08 +02:00
|
|
|
// GetCommitListActivity retrieves an ungrouped list of latest commits
|
|
|
|
// from the datastore accessible to the specified user.
|
|
|
|
func (db *Commitstore) GetCommitListActivity(user *model.User) ([]*model.CommitRepo, error) {
|
|
|
|
var commits []*model.CommitRepo
|
|
|
|
var err = meddler.QueryAll(db, &commits, rebind(commitListActivityQuery), user.ID)
|
|
|
|
return commits, err
|
|
|
|
}
|
|
|
|
|
2014-09-25 11:07:40 +03:00
|
|
|
// PostCommit saves a commit in the datastore.
|
|
|
|
func (db *Commitstore) PostCommit(commit *model.Commit) error {
|
2014-10-14 11:49:10 +03:00
|
|
|
if commit.Created == 0 {
|
|
|
|
commit.Created = time.Now().UTC().Unix()
|
|
|
|
}
|
|
|
|
commit.Updated = time.Now().UTC().Unix()
|
2014-12-30 18:37:57 +02:00
|
|
|
|
|
|
|
priorCommit, err := db.GetCommitPrior(commit)
|
|
|
|
if err == nil {
|
|
|
|
commit.PriorStatus = priorCommit.Status
|
|
|
|
}
|
|
|
|
|
2014-09-25 11:07:40 +03:00
|
|
|
return meddler.Save(db, commitTable, commit)
|
|
|
|
}
|
|
|
|
|
|
|
|
// PutCommit saves a commit in the datastore.
|
|
|
|
func (db *Commitstore) PutCommit(commit *model.Commit) error {
|
2014-12-30 18:37:57 +02:00
|
|
|
return db.PostCommit(commit)
|
2014-09-25 11:07:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// DelCommit removes the commit from the datastore.
|
|
|
|
func (db *Commitstore) DelCommit(commit *model.Commit) error {
|
2014-09-26 10:10:48 +03:00
|
|
|
var _, err = db.Exec(rebind(commitDeleteStmt), commit.ID)
|
2014-09-25 11:07:40 +03:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// KillCommits updates all pending or started commits
|
|
|
|
// in the datastore settings the status to killed.
|
|
|
|
func (db *Commitstore) KillCommits() error {
|
2014-09-26 10:10:48 +03:00
|
|
|
var _, err = db.Exec(rebind(commitKillStmt))
|
2014-09-25 11:07:40 +03:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Commit table name in database.
|
|
|
|
const commitTable = "commits"
|
|
|
|
|
|
|
|
// SQL statement to delete a Commit by ID.
|
|
|
|
const commitDeleteStmt = `
|
|
|
|
DELETE FROM commits
|
|
|
|
WHERE commit_id = ?
|
|
|
|
`
|
|
|
|
|
2014-10-01 21:29:23 +03:00
|
|
|
// SQL query to retrieve the latest Commits accessible
|
2014-11-07 18:04:08 +02:00
|
|
|
// to a specific user account
|
2014-10-01 21:29:23 +03:00
|
|
|
const commitListUserQuery = `
|
|
|
|
SELECT r.repo_remote, r.repo_host, r.repo_owner, r.repo_name, c.*
|
|
|
|
FROM
|
|
|
|
commits c
|
|
|
|
,repos r
|
|
|
|
WHERE c.repo_id = r.repo_id
|
|
|
|
AND c.commit_id IN (
|
|
|
|
SELECT max(c.commit_id)
|
|
|
|
FROM
|
|
|
|
commits c
|
|
|
|
,repos r
|
|
|
|
,perms p
|
|
|
|
WHERE c.repo_id = r.repo_id
|
|
|
|
AND r.repo_id = p.repo_id
|
|
|
|
AND p.user_id = ?
|
|
|
|
GROUP BY r.repo_id
|
2014-11-16 15:34:54 +02:00
|
|
|
) ORDER BY c.commit_created DESC;
|
2014-10-01 21:29:23 +03:00
|
|
|
`
|
|
|
|
|
2014-11-07 18:04:08 +02:00
|
|
|
// SQL query to retrieve the ungrouped, latest Commits
|
|
|
|
// accessible to a specific user account
|
|
|
|
const commitListActivityQuery = `
|
|
|
|
SELECT r.repo_remote, r.repo_host, r.repo_owner, r.repo_name, c.*
|
|
|
|
FROM
|
|
|
|
commits c
|
|
|
|
,repos r
|
|
|
|
,perms p
|
|
|
|
WHERE c.repo_id = r.repo_id
|
|
|
|
AND r.repo_id = p.repo_id
|
|
|
|
AND p.user_id = ?
|
|
|
|
ORDER BY c.commit_created DESC
|
|
|
|
LIMIT 20
|
|
|
|
`
|
|
|
|
|
2014-09-25 11:07:40 +03:00
|
|
|
// SQL query to retrieve the latest Commits across all branches.
|
|
|
|
const commitListQuery = `
|
|
|
|
SELECT *
|
|
|
|
FROM commits
|
2014-11-16 15:34:54 +02:00
|
|
|
WHERE repo_id = ?
|
2014-09-25 11:07:40 +03:00
|
|
|
ORDER BY commit_id DESC
|
|
|
|
LIMIT 20
|
|
|
|
`
|
|
|
|
|
|
|
|
// SQL query to retrieve a Commit by branch and sha.
|
|
|
|
const commitShaQuery = `
|
|
|
|
SELECT *
|
|
|
|
FROM commits
|
|
|
|
WHERE repo_id = ?
|
|
|
|
AND commit_branch = ?
|
|
|
|
AND commit_sha = ?
|
|
|
|
LIMIT 1
|
|
|
|
`
|
|
|
|
|
|
|
|
// SQL query to retrieve the most recent Commit for a branch.
|
|
|
|
const commitLastQuery = `
|
|
|
|
SELECT *
|
|
|
|
FROM commits
|
|
|
|
WHERE repo_id = ?
|
|
|
|
AND commit_branch = ?
|
2014-10-10 05:03:11 +03:00
|
|
|
AND commit_pr = ''
|
2014-09-25 11:07:40 +03:00
|
|
|
ORDER BY commit_id DESC
|
|
|
|
LIMIT 1
|
|
|
|
`
|
|
|
|
|
2014-12-30 18:37:57 +02:00
|
|
|
// SQL query to retrieve the prior Commit (by commit_created) in the same branch and repo as the specified Commit.
|
|
|
|
const commitPriorQuery = `
|
|
|
|
SELECT *
|
|
|
|
FROM commits
|
|
|
|
WHERE repo_id = ?
|
|
|
|
AND commit_branch = ?
|
|
|
|
AND commit_created < ?
|
|
|
|
AND commit_status IN ('Success', 'Failure')
|
|
|
|
ORDER BY commit_created DESC
|
|
|
|
LIMIT 1
|
|
|
|
`
|
|
|
|
|
2014-09-25 11:07:40 +03:00
|
|
|
// SQL statement to cancel all running Commits.
|
|
|
|
const commitKillStmt = `
|
2014-09-27 23:09:55 +03:00
|
|
|
UPDATE commits SET commit_status = 'Killed'
|
2014-09-25 11:07:40 +03:00
|
|
|
WHERE commit_status IN ('Started', 'Pending');
|
|
|
|
`
|