diff --git a/pkg/store/builtin/build.go b/pkg/store/builtin/build.go index d8abfe7ad..0a1d8211c 100644 --- a/pkg/store/builtin/build.go +++ b/pkg/store/builtin/build.go @@ -1,62 +1,47 @@ package builtin import ( + "database/sql" "time" - "github.com/drone/drone/Godeps/_workspace/src/github.com/russross/meddler" - common "github.com/drone/drone/pkg/types" + "github.com/drone/drone/pkg/types" ) type Buildstore struct { - meddler.DB + *sql.DB } -func NewBuildstore(db meddler.DB) *Buildstore { +func NewBuildstore(db *sql.DB) *Buildstore { return &Buildstore{db} } // Build returns a build by ID. -func (db *Buildstore) Build(id int64) (*common.Build, error) { - var build = new(common.Build) - var err = meddler.Load(db, buildTable, build, id) - return build, err +func (db *Buildstore) Build(id int64) (*types.Build, error) { + return getBuild(db, rebind(stmtBuildSelect), id) } // BuildSeq returns a build by sequence number. -func (db *Buildstore) BuildSeq(commit *common.Commit, seq int) (*common.Build, error) { - var build = new(common.Build) - var err = meddler.QueryRow(db, build, rebind(buildNumberQuery), commit.ID, seq) - return build, err +func (db *Buildstore) BuildSeq(commit *types.Commit, seq int) (*types.Build, error) { + return getBuild(db, rebind(stmtBuildSelectBuildSeq), commit.ID, seq) } // BuildList returns a list of all commit builds -func (db *Buildstore) BuildList(commit *common.Commit) ([]*common.Build, error) { - var builds []*common.Build - var err = meddler.QueryAll(db, &builds, rebind(buildListQuery), commit.ID) - return builds, err +func (db *Buildstore) BuildList(commit *types.Commit) ([]*types.Build, error) { + return getBuilds(db, rebind(stmtBuildSelectBuildCommitId), commit.ID) } // SetBuild updates an existing build. -func (db *Buildstore) SetBuild(build *common.Build) error { +func (db *Buildstore) SetBuild(build *types.Build) error { build.Updated = time.Now().UTC().Unix() - return meddler.Update(db, buildTable, build) + return updateBuild(db, rebind(stmtBuildUpdate), build) +} + +// AddBuild inserts a build. +func (db *Buildstore) AddBuild(build *types.Build) error { + build.Created = time.Now().UTC().Unix() + build.Updated = time.Now().UTC().Unix() + return createBuild(db, rebind(stmtBuildInsert), build) } // Build table name in database. const buildTable = "builds" - -// SQL query to retrieve a token by label. -const buildListQuery = ` -SELECT * -FROM builds -WHERE commit_id = ? -ORDER BY build_seq ASC -` - -const buildNumberQuery = ` -SELECT * -FROM builds -WHERE commit_id = ? - AND build_seq = ? -LIMIT 1; -` diff --git a/pkg/store/builtin/build_sql.go b/pkg/store/builtin/build_sql.go new file mode 100644 index 000000000..1d5d02af6 --- /dev/null +++ b/pkg/store/builtin/build_sql.go @@ -0,0 +1,355 @@ +package builtin + +// DO NOT EDIT +// code generated by go:generate + +import ( + "database/sql" + "encoding/json" + + . "github.com/drone/drone/pkg/types" +) + +var _ = json.Marshal + +// generic database interface, matching both *sql.Db and *sql.Tx +type buildDB interface { + Exec(query string, args ...interface{}) (sql.Result, error) + Query(query string, args ...interface{}) (*sql.Rows, error) + QueryRow(query string, args ...interface{}) *sql.Row +} + +func getBuild(db buildDB, query string, args ...interface{}) (*Build, error) { + row := db.QueryRow(query, args...) + return scanBuild(row) +} + +func getBuilds(db buildDB, query string, args ...interface{}) ([]*Build, error) { + rows, err := db.Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + return scanBuilds(rows) +} + +func createBuild(db buildDB, query string, v *Build) error { + var v0 int64 + var v1 string + var v2 int + var v3 int + var v4 int64 + var v5 int64 + var v6 int64 + var v7 int64 + var v8 int64 + var v9 []byte + v0 = v.CommitID + v1 = v.State + v2 = v.ExitCode + v3 = v.Sequence + v4 = v.Duration + v5 = v.Started + v6 = v.Finished + v7 = v.Created + v8 = v.Updated + v9, _ = json.Marshal(v.Environment) + + res, err := db.Exec(query, + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + ) + if err != nil { + return err + } + + v.ID, err = res.LastInsertId() + return err +} + +func updateBuild(db buildDB, query string, v *Build) error { + var v0 int64 + var v1 int64 + var v2 string + var v3 int + var v4 int + var v5 int64 + var v6 int64 + var v7 int64 + var v8 int64 + var v9 int64 + var v10 []byte + v0 = v.ID + v1 = v.CommitID + v2 = v.State + v3 = v.ExitCode + v4 = v.Sequence + v5 = v.Duration + v6 = v.Started + v7 = v.Finished + v8 = v.Created + v9 = v.Updated + v10, _ = json.Marshal(v.Environment) + + _, err := db.Exec(query, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + &v0, + ) + return err +} + +func scanBuild(row *sql.Row) (*Build, error) { + var v0 int64 + var v1 int64 + var v2 string + var v3 int + var v4 int + var v5 int64 + var v6 int64 + var v7 int64 + var v8 int64 + var v9 int64 + var v10 []byte + + err := row.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + ) + if err != nil { + return nil, err + } + + v := &Build{} + v.ID = v0 + v.CommitID = v1 + v.State = v2 + v.ExitCode = v3 + v.Sequence = v4 + v.Duration = v5 + v.Started = v6 + v.Finished = v7 + v.Created = v8 + v.Updated = v9 + json.Unmarshal(v10, &v.Environment) + + return v, nil +} + +func scanBuilds(rows *sql.Rows) ([]*Build, error) { + var err error + var vv []*Build + for rows.Next() { + var v0 int64 + var v1 int64 + var v2 string + var v3 int + var v4 int + var v5 int64 + var v6 int64 + var v7 int64 + var v8 int64 + var v9 int64 + var v10 []byte + err = rows.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + ) + if err != nil { + return vv, err + } + + v := &Build{} + v.ID = v0 + v.CommitID = v1 + v.State = v2 + v.ExitCode = v3 + v.Sequence = v4 + v.Duration = v5 + v.Started = v6 + v.Finished = v7 + v.Created = v8 + v.Updated = v9 + json.Unmarshal(v10, &v.Environment) + vv = append(vv, v) + } + return vv, rows.Err() +} + +const stmtBuildSelectList = ` +SELECT + build_id +,build_commit_id +,build_state +,build_exit_code +,build_sequence +,build_duration +,build_started +,build_finished +,build_created +,build_updated +,build_environment +FROM builds +` + +const stmtBuildSelectRange = ` +SELECT + build_id +,build_commit_id +,build_state +,build_exit_code +,build_sequence +,build_duration +,build_started +,build_finished +,build_created +,build_updated +,build_environment +FROM builds +LIMIT ? OFFSET ? +` + +const stmtBuildSelect = ` +SELECT + build_id +,build_commit_id +,build_state +,build_exit_code +,build_sequence +,build_duration +,build_started +,build_finished +,build_created +,build_updated +,build_environment +FROM builds +WHERE build_id = ? +` + +const stmtBuildSelectBuildCommitId = ` +SELECT + build_id +,build_commit_id +,build_state +,build_exit_code +,build_sequence +,build_duration +,build_started +,build_finished +,build_created +,build_updated +,build_environment +FROM builds +WHERE build_commit_id = ? +` + +const stmtBuildSelectBuildSeq = ` +SELECT + build_id +,build_commit_id +,build_state +,build_exit_code +,build_sequence +,build_duration +,build_started +,build_finished +,build_created +,build_updated +,build_environment +FROM builds +WHERE build_commit_id = ? +AND build_sequence = ? +` + +const stmtBuildInsert = ` +INSERT INTO builds ( + build_commit_id +,build_state +,build_exit_code +,build_sequence +,build_duration +,build_started +,build_finished +,build_created +,build_updated +,build_environment +) VALUES (?,?,?,?,?,?,?,?,?,?); +` + +const stmtBuildUpdate = ` +UPDATE builds SET + build_commit_id = ? +,build_state = ? +,build_exit_code = ? +,build_sequence = ? +,build_duration = ? +,build_started = ? +,build_finished = ? +,build_created = ? +,build_updated = ? +,build_environment = ? +WHERE build_id = ? +` + +const stmtBuildDelete = ` +DELETE FROM builds +WHERE build_id = ? +` + +const stmtBuildTable = ` +CREATE TABLE IF NOT EXISTS builds ( + build_id INTEGER PRIMARY KEY AUTOINCREMENT +,build_commit_id INTEGER +,build_state VARCHAR +,build_exit_code INTEGER +,build_sequence INTEGER +,build_duration INTEGER +,build_started INTEGER +,build_finished INTEGER +,build_created INTEGER +,build_updated INTEGER +,build_environment VARCHAR(2048) +); +` + +const stmtBuildBuildCommitIdIndex = ` +CREATE INDEX IF NOT EXISTS ix_build_commit_id ON builds (build_commit_id); +` + +const stmtBuildBuildSeqIndex = ` +CREATE UNIQUE INDEX IF NOT EXISTS ux_build_seq ON builds (build_commit_id,build_sequence); +` diff --git a/pkg/store/builtin/build_test.go b/pkg/store/builtin/build_test.go index 139ba0dcb..6cd6d8651 100644 --- a/pkg/store/builtin/build_test.go +++ b/pkg/store/builtin/build_test.go @@ -1,9 +1,11 @@ package builtin import ( - "github.com/drone/drone/Godeps/_workspace/src/github.com/franela/goblin" - common "github.com/drone/drone/pkg/types" "testing" + + "github.com/bradrydzewski/drone/common" + "github.com/drone/drone/Godeps/_workspace/src/github.com/franela/goblin" + "github.com/drone/drone/pkg/types" ) func TestBuildstore(t *testing.T) { @@ -21,139 +23,80 @@ func TestBuildstore(t *testing.T) { db.Exec("DELETE FROM commits") }) - g.It("Should update an existing build in the datastore", func() { - buildList := []*common.Build{ - &common.Build{ - CommitID: 1, - State: "success", - ExitCode: 0, - Sequence: 1, - }, - &common.Build{ - CommitID: 3, - State: "error", - ExitCode: 1, - Sequence: 2, - }, + g.It("Should Set a build", func() { + build := &types.Build{ + CommitID: 1, + State: "pending", + ExitCode: 0, + Sequence: 1, } - //In order for buid to be populated, - //The AddCommit command will insert builds - //if the Commit.Builds array is populated - //Add Commit. - commit1 := common.Commit{ - RepoID: 1, - State: common.StateSuccess, - Ref: "refs/heads/master", - Sha: "14710626f22791619d3b7e9ccf58b10374e5b76d", - Builds: buildList, - } - //Add commit, build, retrieve 2nd, update it and recheck it. - err1 := cs.AddCommit(&commit1) + err1 := bs.AddBuild(build) g.Assert(err1 == nil).IsTrue() - g.Assert(commit1.ID != 0).IsTrue() - g.Assert(commit1.Sequence).Equal(1) - // - build, err2 := bs.Build(commit1.Builds[1].ID) + g.Assert(build.ID != 0).IsTrue() + + build.State = "started" + err2 := bs.SetBuild(build) g.Assert(err2 == nil).IsTrue() - g.Assert(build.ID).Equal(commit1.Builds[1].ID) - build.State = common.StatePending - err1 = bs.SetBuild(build) - g.Assert(err1 == nil).IsTrue() - build, err2 = bs.Build(commit1.Builds[1].ID) - g.Assert(build.ID).Equal(commit1.Builds[1].ID) - g.Assert(build.State).Equal(common.StatePending) + + getbuild, err3 := bs.Build(build.ID) + g.Assert(err3 == nil).IsTrue() + g.Assert(getbuild.State).Equal(build.State) }) - g.It("Should return a build by ID", func() { - buildList := []*common.Build{ - &common.Build{ - CommitID: 1, - State: "success", - ExitCode: 0, - Sequence: 1, - }, - &common.Build{ - CommitID: 3, - State: "error", - ExitCode: 1, - Sequence: 2, - }, + g.It("Should Get a Build by ID", func() { + build := &types.Build{ + CommitID: 1, + State: "pending", + ExitCode: 1, + Sequence: 1, + Environment: map[string]string{"foo": "bar"}, } - //In order for buid to be populated, - //The AddCommit command will insert builds - //if the Commit.Builds array is populated - //Add Commit. - commit1 := common.Commit{ - RepoID: 1, - State: common.StateSuccess, - Ref: "refs/heads/master", - Sha: "14710626f22791619d3b7e9ccf58b10374e5b76d", - Builds: buildList, - } - //Add commit, build, retrieve 2nd build ID. - err1 := cs.AddCommit(&commit1) + err1 := bs.AddBuild(build) g.Assert(err1 == nil).IsTrue() - g.Assert(commit1.ID != 0).IsTrue() - g.Assert(commit1.Sequence).Equal(1) - // - build, err2 := bs.Build(commit1.Builds[1].ID) + g.Assert(build.ID != 0).IsTrue() + + getbuild, err2 := bs.Build(build.ID) g.Assert(err2 == nil).IsTrue() - g.Assert(build.ID).Equal(commit1.Builds[1].ID) + g.Assert(getbuild.ID).Equal(build.ID) + g.Assert(getbuild.State).Equal(build.State) + g.Assert(getbuild.ExitCode).Equal(build.ExitCode) + g.Assert(getbuild.Environment).Equal(build.Environment) + g.Assert(getbuild.Environment["foo"]).Equal("bar") }) - g.It("Should return a build by Sequence", func() { - buildList := []*common.Build{ - &common.Build{ - CommitID: 1, - State: "success", - ExitCode: 0, - Sequence: 1, - }, - &common.Build{ - CommitID: 3, - State: "error", - ExitCode: 1, - Sequence: 2, - }, + g.It("Should Get a Build by Sequence", func() { + build := &types.Build{ + CommitID: 1, + State: "pending", + ExitCode: 1, + Sequence: 1, } - //In order for buid to be populated, - //The AddCommit command will insert builds - //if the Commit.Builds array is populated - //Add Commit. - commit1 := common.Commit{ - RepoID: 1, - State: common.StateSuccess, - Ref: "refs/heads/master", - Sha: "14710626f22791619d3b7e9ccf58b10374e5b76d", - Builds: buildList, - } - //Add commit, build, retrieve 2nd build ID. - err1 := cs.AddCommit(&commit1) + err1 := bs.AddBuild(build) g.Assert(err1 == nil).IsTrue() - g.Assert(commit1.ID != 0).IsTrue() - g.Assert(commit1.Sequence).Equal(1) - // - build, err2 := bs.BuildSeq(&commit1, commit1.Builds[1].Sequence) + g.Assert(build.ID != 0).IsTrue() + + getbuild, err2 := bs.BuildSeq(&types.Commit{ID: 1}, 1) g.Assert(err2 == nil).IsTrue() - g.Assert(build.Sequence).Equal(commit1.Builds[1].Sequence) + g.Assert(getbuild.ID).Equal(build.ID) + g.Assert(getbuild.State).Equal(build.State) }) - g.It("Should return a list of all commit builds", func() { + g.It("Should Get a List of Builds by Commit", func() { //Add repo - buildList := []*common.Build{ - &common.Build{ + buildList := []*types.Build{ + &types.Build{ CommitID: 1, State: "success", ExitCode: 0, Sequence: 1, }, - &common.Build{ + &types.Build{ CommitID: 3, State: "error", ExitCode: 1, Sequence: 2, }, - &common.Build{ + &types.Build{ CommitID: 5, State: "pending", ExitCode: 0, @@ -164,7 +107,7 @@ func TestBuildstore(t *testing.T) { //The AddCommit command will insert builds //if the Commit.Builds array is populated //Add Commit. - commit1 := common.Commit{ + commit1 := types.Commit{ RepoID: 1, State: common.StateSuccess, Ref: "refs/heads/master", diff --git a/pkg/store/builtin/migrate/migrate.go b/pkg/store/builtin/migrate/migrate.go index 95dfe521d..7ab7b6bb1 100644 --- a/pkg/store/builtin/migrate/migrate.go +++ b/pkg/store/builtin/migrate/migrate.go @@ -11,10 +11,6 @@ func Setup(tx migration.LimitedTx) error { userTable, starTable, repoTable, - repoKeyTable, - repoKeyIndex, - repoParamTable, - repoParamsIndex, repoUserIndex, commitTable, commitRepoIndex, @@ -55,20 +51,20 @@ CREATE TABLE IF NOT EXISTS users ( var repoTable = ` CREATE TABLE IF NOT EXISTS repos ( repo_id INTEGER PRIMARY KEY AUTOINCREMENT - ,user_id INTEGER + ,repo_user_id INTEGER ,repo_owner VARCHAR(255) ,repo_name VARCHAR(255) - ,repo_slug VARCHAR(1024) + ,repo_full_name VARCHAR(1024) ,repo_token VARCHAR(255) - ,repo_lang VARCHAR(255) + ,repo_language VARCHAR(255) ,repo_branch VARCHAR(255) ,repo_private BOOLEAN ,repo_trusted BOOLEAN ,repo_self VARCHAR(1024) ,repo_link VARCHAR(1024) ,repo_clone VARCHAR(1024) - ,repo_push BOOLEAN - ,repo_pull BOOLEAN + ,repo_post_commit BOOLEAN + ,repo_pull_request BOOLEAN ,repo_public_key BLOB ,repo_private_key BLOB ,repo_params BLOB @@ -76,40 +72,40 @@ CREATE TABLE IF NOT EXISTS repos ( ,repo_created INTEGER ,repo_updated INTEGER ,UNIQUE(repo_owner, repo_name) - ,UNIQUE(repo_slug) + ,UNIQUE(repo_full_name) ); ` var repoUserIndex = ` -CREATE INDEX repos_user_idx ON repos (user_id); +CREATE INDEX repos_user_idx ON repos (repo_user_id); ` -var repoKeyTable = ` -CREATE TABLE IF NOT EXISTS repo_keys ( - keys_id INTEGER PRIMARY KEY AUTOINCREMENT - ,repo_id INTEGER - ,keys_public BLOB - ,keys_private BLOB - ,UNIQUE(repo_id) -); -` +// var repoKeyTable = ` +// CREATE TABLE IF NOT EXISTS repo_keys ( +// keys_id INTEGER PRIMARY KEY AUTOINCREMENT +// ,repo_id INTEGER +// ,keys_public BLOB +// ,keys_private BLOB +// ,UNIQUE(repo_id) +// ); +// ` +// +// var repoKeyIndex = ` +// CREATE INDEX keys_repo_idx ON repo_keys (repo_id); +// ` -var repoKeyIndex = ` -CREATE INDEX keys_repo_idx ON repo_keys (repo_id); -` - -var repoParamTable = ` -CREATE TABLE IF NOT EXISTS repo_params ( - param_id INTEGER PRIMARY KEY AUTOINCREMENT - ,repo_id INTEGER - ,param_map BLOB - ,UNIQUE(repo_id) -); -` - -var repoParamsIndex = ` -CREATE INDEX params_repo_idx ON repo_params (repo_id); -` +// var repoParamTable = ` +// CREATE TABLE IF NOT EXISTS repo_params ( +// param_id INTEGER PRIMARY KEY AUTOINCREMENT +// ,repo_id INTEGER +// ,param_map BLOB +// ,UNIQUE(repo_id) +// ); +// ` +// +// var repoParamsIndex = ` +// CREATE INDEX params_repo_idx ON repo_params (repo_id); +// ` var starTable = ` CREATE TABLE IF NOT EXISTS stars ( @@ -152,38 +148,38 @@ CREATE INDEX commits_repo_idx ON commits (repo_id); var tokenTable = ` CREATE TABLE IF NOT EXISTS tokens ( token_id INTEGER PRIMARY KEY AUTOINCREMENT - ,user_id INTEGER + ,token_user_id INTEGER ,token_kind VARCHAR(255) ,token_label VARCHAR(255) ,token_expiry INTEGER ,token_issued INTEGER - ,UNIQUE(user_id, token_label) + ,UNIQUE(token_user_id, token_label) ); ` var tokenUserIndex = ` -CREATE INDEX tokens_user_idx ON tokens (user_id); +CREATE INDEX tokens_user_idx ON tokens (token_user_id); ` var buildTable = ` CREATE TABLE IF NOT EXISTS builds ( build_id INTEGER PRIMARY KEY AUTOINCREMENT - ,commit_id INTEGER - ,build_seq INTEGER + ,build_commit_id INTEGER + ,build_sequence INTEGER ,build_state VARCHAR(255) - ,build_exit INTEGER + ,build_exit_code INTEGER ,build_duration INTEGER ,build_started INTEGER ,build_finished INTEGER ,build_created INTEGER ,build_updated INTEGER - ,build_env BLOB - ,UNIQUE(commit_id, build_seq) + ,build_environment VARCHAR(2000) + ,UNIQUE(build_commit_id, build_sequence) ); ` var buildCommitIndex = ` -CREATE INDEX builds_commit_idx ON builds (commit_id); +CREATE INDEX builds_commit_idx ON builds (build_commit_id); ` var statusTable = ` diff --git a/pkg/store/builtin/repo.go b/pkg/store/builtin/repo.go index eb68c3c5d..e8b3e006f 100644 --- a/pkg/store/builtin/repo.go +++ b/pkg/store/builtin/repo.go @@ -4,8 +4,7 @@ import ( "database/sql" "time" - "github.com/drone/drone/Godeps/_workspace/src/github.com/russross/meddler" - common "github.com/drone/drone/pkg/types" + "github.com/drone/drone/pkg/types" ) type Repostore struct { @@ -18,95 +17,69 @@ func NewRepostore(db *sql.DB) *Repostore { // Repo retrieves a specific repo from the // datastore for the given ID. -func (db *Repostore) Repo(id int64) (*common.Repo, error) { - var repo = new(common.Repo) - var err = meddler.Load(db, repoTable, repo, id) - return repo, err +func (db *Repostore) Repo(id int64) (*types.Repo, error) { + return getRepo(db, rebind(stmtRepoSelect), id) } // RepoName retrieves a repo from the datastore // for the specified name. -func (db *Repostore) RepoName(owner, name string) (*common.Repo, error) { - var repo = new(common.Repo) - var err = meddler.QueryRow(db, repo, rebind(repoNameQuery), owner, name) - return repo, err +func (db *Repostore) RepoName(owner, name string) (*types.Repo, error) { + return getRepo(db, rebind(stmtRepoSelectRepoOwnerName), owner, name) } // RepoList retrieves a list of all repos from // the datastore accessible by the given user ID. -func (db *Repostore) RepoList(user *common.User) ([]*common.Repo, error) { - var repos []*common.Repo - var err = meddler.QueryAll(db, &repos, rebind(repoListQuery), user.ID) - return repos, err +func (db *Repostore) RepoList(user *types.User) ([]*types.Repo, error) { + return getRepos(db, rebind(repoListQuery), user.ID) } // AddRepo inserts a repo in the datastore. -func (db *Repostore) AddRepo(repo *common.Repo) error { +func (db *Repostore) AddRepo(repo *types.Repo) error { repo.Created = time.Now().UTC().Unix() repo.Updated = time.Now().UTC().Unix() - return meddler.Insert(db, repoTable, repo) + return createRepo(db, rebind(stmtRepoInsert), repo) } // SetRepo updates a repo in the datastore. -func (db *Repostore) SetRepo(repo *common.Repo) error { +func (db *Repostore) SetRepo(repo *types.Repo) error { repo.Updated = time.Now().UTC().Unix() - return meddler.Update(db, repoTable, repo) + return updateRepo(db, rebind(stmtRepoUpdate), repo) } // DelRepo removes the repo from the datastore. -func (db *Repostore) DelRepo(repo *common.Repo) error { - var _, err = db.Exec(rebind(repoDeleteStmt), repo.ID) +func (db *Repostore) DelRepo(repo *types.Repo) error { + var _, err = db.Exec(rebind(stmtRepoDelete), repo.ID) return err } -// Repo table names in database. -const ( - repoTable = "repos" - repoKeyTable = "repo_keys" - repoParamTable = "repo_params" -) - -// SQL statement to retrieve a Repo by name. -const repoNameQuery = ` -SELECT * -FROM repos -WHERE repo_owner = ? - AND repo_name = ? -LIMIT 1; -` - // SQL statement to retrieve a list of Repos // with permissions for the given User ID. const repoListQuery = ` -SELECT r.* +SELECT + r.repo_id +,r.repo_user_id +,r.repo_owner +,r.repo_name +,r.repo_full_name +,r.repo_token +,r.repo_language +,r.repo_private +,r.repo_self +,r.repo_link +,r.repo_clone +,r.repo_branch +,r.repo_timeout +,r.repo_trusted +,r.repo_post_commit +,r.repo_pull_request +,r.repo_public_key +,r.repo_private_key +,r.repo_created +,r.repo_updated +,r.repo_params FROM repos r ,stars s WHERE r.repo_id = s.repo_id AND s.user_id = ? ` - -// SQL statement to retrieve a keypair for -// a Repository. -const repoKeysQuery = ` -SELECT * -FROM repo_keys -WHERE repo_id = ? -LIMIT 1; -` - -// SQL statement to retrieve a keypair for -// a Repository. -const repoParamsQuery = ` -SELECT * -FROM repo_params -WHERE repo_id = ? -LIMIT 1; -` - -// SQL statement to delete a User by ID. -const ( - repoDeleteStmt = `DELETE FROM repos WHERE repo_id = ?` - repoKeypairDeleteStmt = `DELETE FROM repo_params WHERE repo_id = ?` - repoParamsDeleteStmt = `DELETE FROM repo_keys WHERE repo_id = ?` -) diff --git a/pkg/store/builtin/repo_sql.go b/pkg/store/builtin/repo_sql.go new file mode 100644 index 000000000..0e0d25f2e --- /dev/null +++ b/pkg/store/builtin/repo_sql.go @@ -0,0 +1,555 @@ +package builtin + +// DO NOT EDIT +// code generated by go:generate + +import ( + "database/sql" + "encoding/json" + + . "github.com/drone/drone/pkg/types" +) + +var _ = json.Marshal + +// generic database interface, matching both *sql.Db and *sql.Tx +type repoDB interface { + Exec(query string, args ...interface{}) (sql.Result, error) + Query(query string, args ...interface{}) (*sql.Rows, error) + QueryRow(query string, args ...interface{}) *sql.Row +} + +func getRepo(db repoDB, query string, args ...interface{}) (*Repo, error) { + row := db.QueryRow(query, args...) + return scanRepo(row) +} + +func getRepos(db repoDB, query string, args ...interface{}) ([]*Repo, error) { + rows, err := db.Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + return scanRepos(rows) +} + +func createRepo(db repoDB, query string, v *Repo) error { + var v0 int64 + var v1 string + var v2 string + var v3 string + var v4 string + var v5 string + var v6 bool + var v7 string + var v8 string + var v9 string + var v10 string + var v11 int64 + var v12 bool + var v13 bool + var v14 bool + var v15 string + var v16 string + var v17 int64 + var v18 int64 + var v19 []byte + v0 = v.UserID + v1 = v.Owner + v2 = v.Name + v3 = v.FullName + v4 = v.Token + v5 = v.Language + v6 = v.Private + v7 = v.Self + v8 = v.Link + v9 = v.Clone + v10 = v.Branch + v11 = v.Timeout + v12 = v.Trusted + v13 = v.PostCommit + v14 = v.PullRequest + v15 = v.PublicKey + v16 = v.PrivateKey + v17 = v.Created + v18 = v.Updated + v19, _ = json.Marshal(v.Params) + + res, err := db.Exec(query, + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + &v11, + &v12, + &v13, + &v14, + &v15, + &v16, + &v17, + &v18, + &v19, + ) + if err != nil { + return err + } + + v.ID, err = res.LastInsertId() + return err +} + +func updateRepo(db repoDB, query string, v *Repo) error { + var v0 int64 + var v1 int64 + var v2 string + var v3 string + var v4 string + var v5 string + var v6 string + var v7 bool + var v8 string + var v9 string + var v10 string + var v11 string + var v12 int64 + var v13 bool + var v14 bool + var v15 bool + var v16 string + var v17 string + var v18 int64 + var v19 int64 + var v20 []byte + v0 = v.ID + v1 = v.UserID + v2 = v.Owner + v3 = v.Name + v4 = v.FullName + v5 = v.Token + v6 = v.Language + v7 = v.Private + v8 = v.Self + v9 = v.Link + v10 = v.Clone + v11 = v.Branch + v12 = v.Timeout + v13 = v.Trusted + v14 = v.PostCommit + v15 = v.PullRequest + v16 = v.PublicKey + v17 = v.PrivateKey + v18 = v.Created + v19 = v.Updated + v20, _ = json.Marshal(v.Params) + + _, err := db.Exec(query, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + &v11, + &v12, + &v13, + &v14, + &v15, + &v16, + &v17, + &v18, + &v19, + &v20, + &v0, + ) + return err +} + +func scanRepo(row *sql.Row) (*Repo, error) { + var v0 int64 + var v1 int64 + var v2 string + var v3 string + var v4 string + var v5 string + var v6 string + var v7 bool + var v8 string + var v9 string + var v10 string + var v11 string + var v12 int64 + var v13 bool + var v14 bool + var v15 bool + var v16 string + var v17 string + var v18 int64 + var v19 int64 + var v20 []byte + + err := row.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + &v11, + &v12, + &v13, + &v14, + &v15, + &v16, + &v17, + &v18, + &v19, + &v20, + ) + if err != nil { + return nil, err + } + + v := &Repo{} + v.ID = v0 + v.UserID = v1 + v.Owner = v2 + v.Name = v3 + v.FullName = v4 + v.Token = v5 + v.Language = v6 + v.Private = v7 + v.Self = v8 + v.Link = v9 + v.Clone = v10 + v.Branch = v11 + v.Timeout = v12 + v.Trusted = v13 + v.PostCommit = v14 + v.PullRequest = v15 + v.PublicKey = v16 + v.PrivateKey = v17 + v.Created = v18 + v.Updated = v19 + json.Unmarshal(v20, &v.Params) + + return v, nil +} + +func scanRepos(rows *sql.Rows) ([]*Repo, error) { + var err error + var vv []*Repo + for rows.Next() { + var v0 int64 + var v1 int64 + var v2 string + var v3 string + var v4 string + var v5 string + var v6 string + var v7 bool + var v8 string + var v9 string + var v10 string + var v11 string + var v12 int64 + var v13 bool + var v14 bool + var v15 bool + var v16 string + var v17 string + var v18 int64 + var v19 int64 + var v20 []byte + err = rows.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + &v11, + &v12, + &v13, + &v14, + &v15, + &v16, + &v17, + &v18, + &v19, + &v20, + ) + if err != nil { + return vv, err + } + + v := &Repo{} + v.ID = v0 + v.UserID = v1 + v.Owner = v2 + v.Name = v3 + v.FullName = v4 + v.Token = v5 + v.Language = v6 + v.Private = v7 + v.Self = v8 + v.Link = v9 + v.Clone = v10 + v.Branch = v11 + v.Timeout = v12 + v.Trusted = v13 + v.PostCommit = v14 + v.PullRequest = v15 + v.PublicKey = v16 + v.PrivateKey = v17 + v.Created = v18 + v.Updated = v19 + json.Unmarshal(v20, &v.Params) + vv = append(vv, v) + } + return vv, rows.Err() +} + +const stmtRepoSelectList = ` +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_token +,repo_language +,repo_private +,repo_self +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_trusted +,repo_post_commit +,repo_pull_request +,repo_public_key +,repo_private_key +,repo_created +,repo_updated +,repo_params +FROM repos +` + +const stmtRepoSelectRange = ` +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_token +,repo_language +,repo_private +,repo_self +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_trusted +,repo_post_commit +,repo_pull_request +,repo_public_key +,repo_private_key +,repo_created +,repo_updated +,repo_params +FROM repos +LIMIT ? OFFSET ? +` + +const stmtRepoSelect = ` +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_token +,repo_language +,repo_private +,repo_self +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_trusted +,repo_post_commit +,repo_pull_request +,repo_public_key +,repo_private_key +,repo_created +,repo_updated +,repo_params +FROM repos +WHERE repo_id = ? +` + +const stmtRepoSelectRepoOwnerName = ` +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_token +,repo_language +,repo_private +,repo_self +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_trusted +,repo_post_commit +,repo_pull_request +,repo_public_key +,repo_private_key +,repo_created +,repo_updated +,repo_params +FROM repos +WHERE repo_owner = ? +AND repo_name = ? +` + +const stmtRepoSelectRepoFullName = ` +SELECT + repo_id +,repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_token +,repo_language +,repo_private +,repo_self +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_trusted +,repo_post_commit +,repo_pull_request +,repo_public_key +,repo_private_key +,repo_created +,repo_updated +,repo_params +FROM repos +WHERE repo_full_name = ? +` + +const stmtRepoInsert = ` +INSERT INTO repos ( + repo_user_id +,repo_owner +,repo_name +,repo_full_name +,repo_token +,repo_language +,repo_private +,repo_self +,repo_link +,repo_clone +,repo_branch +,repo_timeout +,repo_trusted +,repo_post_commit +,repo_pull_request +,repo_public_key +,repo_private_key +,repo_created +,repo_updated +,repo_params +) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?); +` + +const stmtRepoUpdate = ` +UPDATE repos SET + repo_user_id = ? +,repo_owner = ? +,repo_name = ? +,repo_full_name = ? +,repo_token = ? +,repo_language = ? +,repo_private = ? +,repo_self = ? +,repo_link = ? +,repo_clone = ? +,repo_branch = ? +,repo_timeout = ? +,repo_trusted = ? +,repo_post_commit = ? +,repo_pull_request = ? +,repo_public_key = ? +,repo_private_key = ? +,repo_created = ? +,repo_updated = ? +,repo_params = ? +WHERE repo_id = ? +` + +const stmtRepoDelete = ` +DELETE FROM repos +WHERE repo_id = ? +` + +const stmtRepoTable = ` +CREATE TABLE IF NOT EXISTS repos ( + repo_id INTEGER PRIMARY KEY AUTOINCREMENT +,repo_user_id INTEGER +,repo_owner VARCHAR +,repo_name VARCHAR +,repo_full_name VARCHAR +,repo_token VARCHAR +,repo_language VARCHAR +,repo_private BOOLEAN +,repo_self VARCHAR +,repo_link VARCHAR +,repo_clone VARCHAR +,repo_branch VARCHAR +,repo_timeout INTEGER +,repo_trusted BOOLEAN +,repo_post_commit BOOLEAN +,repo_pull_request BOOLEAN +,repo_public_key VARCHAR +,repo_private_key VARCHAR +,repo_created INTEGER +,repo_updated INTEGER +,repo_params BLOB +); +` + +const stmtRepoRepoOwnerNameIndex = ` +CREATE UNIQUE INDEX IF NOT EXISTS ux_repo_owner_name ON repos (repo_owner,repo_name); +` + +const stmtRepoRepoFullNameIndex = ` +CREATE UNIQUE INDEX IF NOT EXISTS ux_repo_full_name ON repos (repo_full_name); +` diff --git a/pkg/store/builtin/repo_test.go b/pkg/store/builtin/repo_test.go index 583e1334b..540d21af5 100644 --- a/pkg/store/builtin/repo_test.go +++ b/pkg/store/builtin/repo_test.go @@ -50,38 +50,6 @@ func TestRepostore(t *testing.T) { g.Assert(repo.ID != 0).IsTrue() }) - // g.It("Should Add a Repos Keypair", func() { - // keypair := common.Keypair{ - // RepoID: 1, - // Public: []byte("-----BEGIN RSA PRIVATE KEY----- ..."), - // Private: []byte("ssh-rsa AAAAE1BzbF1xc2EABAvVA6Z ..."), - // } - // err := rs.SetRepoKeypair(&keypair) - // g.Assert(err == nil).IsTrue() - // g.Assert(keypair.ID != 0).IsTrue() - // getkeypair, err := rs.RepoKeypair(&common.Repo{ID: 1}) - // g.Assert(err == nil).IsTrue() - // g.Assert(keypair.ID).Equal(getkeypair.ID) - // g.Assert(keypair.RepoID).Equal(getkeypair.RepoID) - // g.Assert(keypair.Public).Equal(getkeypair.Public) - // g.Assert(keypair.Private).Equal(getkeypair.Private) - // }) - - // g.It("Should Add a Repos Private Params", func() { - // params := common.Params{ - // RepoID: 1, - // Map: map[string]string{"foo": "bar"}, - // } - // err := rs.SetRepoParams(¶ms) - // g.Assert(err == nil).IsTrue() - // g.Assert(params.ID != 0).IsTrue() - // getparams, err := rs.RepoParams(&common.Repo{ID: 1}) - // g.Assert(err == nil).IsTrue() - // g.Assert(params.ID).Equal(getparams.ID) - // g.Assert(params.RepoID).Equal(getparams.RepoID) - // g.Assert(params.Map).Equal(getparams.Map) - // }) - g.It("Should Get a Repo by ID", func() { repo := common.Repo{ UserID: 1, diff --git a/pkg/store/builtin/token.go b/pkg/store/builtin/token.go index ecbbd789f..c6939359f 100644 --- a/pkg/store/builtin/token.go +++ b/pkg/store/builtin/token.go @@ -1,74 +1,43 @@ package builtin import ( - "github.com/drone/drone/Godeps/_workspace/src/github.com/russross/meddler" - common "github.com/drone/drone/pkg/types" + "database/sql" + + "github.com/drone/drone/pkg/types" ) type Tokenstore struct { - meddler.DB + *sql.DB } -func NewTokenstore(db meddler.DB) *Tokenstore { +func NewTokenstore(db *sql.DB) *Tokenstore { return &Tokenstore{db} } // Token returns a token by ID. -func (db *Tokenstore) Token(id int64) (*common.Token, error) { - var token = new(common.Token) - var err = meddler.Load(db, tokenTable, token, id) - return token, err +func (db *Tokenstore) Token(id int64) (*types.Token, error) { + return getToken(db, rebind(stmtTokenSelect), id) } // TokenLabel returns a token by label -func (db *Tokenstore) TokenLabel(user *common.User, label string) (*common.Token, error) { - var token = new(common.Token) - var err = meddler.QueryRow(db, token, rebind(tokenLabelQuery), user.ID, label) - return token, err +func (db *Tokenstore) TokenLabel(user *types.User, label string) (*types.Token, error) { + return getToken(db, rebind(stmtTokenSelectTokenUserLabel), user.ID, label) } // TokenList returns a list of all user tokens. -func (db *Tokenstore) TokenList(user *common.User) ([]*common.Token, error) { - var tokens []*common.Token - var err = meddler.QueryAll(db, &tokens, rebind(tokenListQuery), user.ID) - return tokens, err +func (db *Tokenstore) TokenList(user *types.User) ([]*types.Token, error) { + return getTokens(db, rebind(stmtTokenSelectTokenUserId), user.ID) } // AddToken inserts a new token into the datastore. // If the token label already exists for the user // an error is returned. -func (db *Tokenstore) AddToken(token *common.Token) error { - return meddler.Insert(db, tokenTable, token) +func (db *Tokenstore) AddToken(token *types.Token) error { + return createToken(db, rebind(stmtTokenInsert), token) } // DelToken removes the DelToken from the datastore. -func (db *Tokenstore) DelToken(token *common.Token) error { - var _, err = db.Exec(rebind(tokenDeleteStmt), token.ID) +func (db *Tokenstore) DelToken(token *types.Token) error { + var _, err = db.Exec(rebind(stmtTokenDelete), token.ID) return err } - -// Token table name in database. -const tokenTable = "tokens" - -// SQL query to retrieve a token by label. -const tokenLabelQuery = ` -SELECT * -FROM tokens -WHERE user_id = ? - AND token_label = ? -LIMIT 1 -` - -// SQL query to retrieve a list of user tokens. -const tokenListQuery = ` -SELECT * -FROM tokens -WHERE user_id = ? -ORDER BY token_label ASC -` - -// SQL statement to delete a Token by ID. -const tokenDeleteStmt = ` -DELETE FROM tokens -WHERE token_id=? -` diff --git a/pkg/store/builtin/token_sql.go b/pkg/store/builtin/token_sql.go new file mode 100644 index 000000000..2554bede2 --- /dev/null +++ b/pkg/store/builtin/token_sql.go @@ -0,0 +1,255 @@ +package builtin + +// DO NOT EDIT +// code generated by go:generate + +import ( + "database/sql" + "encoding/json" + + . "github.com/drone/drone/pkg/types" +) + +var _ = json.Marshal + +// generic database interface, matching both *sql.Db and *sql.Tx +type tokenDB interface { + Exec(query string, args ...interface{}) (sql.Result, error) + Query(query string, args ...interface{}) (*sql.Rows, error) + QueryRow(query string, args ...interface{}) *sql.Row +} + +func getToken(db tokenDB, query string, args ...interface{}) (*Token, error) { + row := db.QueryRow(query, args...) + return scanToken(row) +} + +func getTokens(db tokenDB, query string, args ...interface{}) ([]*Token, error) { + rows, err := db.Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + return scanTokens(rows) +} + +func createToken(db tokenDB, query string, v *Token) error { + var v0 int64 + var v1 string + var v2 string + var v3 int64 + var v4 int64 + v0 = v.UserID + v1 = v.Kind + v2 = v.Label + v3 = v.Expiry + v4 = v.Issued + + res, err := db.Exec(query, + &v0, + &v1, + &v2, + &v3, + &v4, + ) + if err != nil { + return err + } + + v.ID, err = res.LastInsertId() + return err +} + +func updateToken(db tokenDB, query string, v *Token) error { + var v0 int64 + var v1 int64 + var v2 string + var v3 string + var v4 int64 + var v5 int64 + v0 = v.ID + v1 = v.UserID + v2 = v.Kind + v3 = v.Label + v4 = v.Expiry + v5 = v.Issued + + _, err := db.Exec(query, + &v1, + &v2, + &v3, + &v4, + &v5, + &v0, + ) + return err +} + +func scanToken(row *sql.Row) (*Token, error) { + var v0 int64 + var v1 int64 + var v2 string + var v3 string + var v4 int64 + var v5 int64 + + err := row.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + ) + if err != nil { + return nil, err + } + + v := &Token{} + v.ID = v0 + v.UserID = v1 + v.Kind = v2 + v.Label = v3 + v.Expiry = v4 + v.Issued = v5 + + return v, nil +} + +func scanTokens(rows *sql.Rows) ([]*Token, error) { + var err error + var vv []*Token + for rows.Next() { + var v0 int64 + var v1 int64 + var v2 string + var v3 string + var v4 int64 + var v5 int64 + err = rows.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + ) + if err != nil { + return vv, err + } + + v := &Token{} + v.ID = v0 + v.UserID = v1 + v.Kind = v2 + v.Label = v3 + v.Expiry = v4 + v.Issued = v5 + vv = append(vv, v) + } + return vv, rows.Err() +} + +const stmtTokenSelectList = ` +SELECT + token_id +,token_user_id +,token_kind +,token_label +,token_expiry +,token_issued +FROM tokens +` + +const stmtTokenSelectRange = ` +SELECT + token_id +,token_user_id +,token_kind +,token_label +,token_expiry +,token_issued +FROM tokens +LIMIT ? OFFSET ? +` + +const stmtTokenSelect = ` +SELECT + token_id +,token_user_id +,token_kind +,token_label +,token_expiry +,token_issued +FROM tokens +WHERE token_id = ? +` + +const stmtTokenSelectTokenUserId = ` +SELECT + token_id +,token_user_id +,token_kind +,token_label +,token_expiry +,token_issued +FROM tokens +WHERE token_user_id = ? +` + +const stmtTokenSelectTokenUserLabel = ` +SELECT + token_id +,token_user_id +,token_kind +,token_label +,token_expiry +,token_issued +FROM tokens +WHERE token_user_id = ? +AND token_label = ? +` + +const stmtTokenInsert = ` +INSERT INTO tokens ( + token_user_id +,token_kind +,token_label +,token_expiry +,token_issued +) VALUES (?,?,?,?,?); +` + +const stmtTokenUpdate = ` +UPDATE tokens SET + token_user_id = ? +,token_kind = ? +,token_label = ? +,token_expiry = ? +,token_issued = ? +WHERE token_id = ? +` + +const stmtTokenDelete = ` +DELETE FROM tokens +WHERE token_id = ? +` + +const stmtTokenTable = ` +CREATE TABLE IF NOT EXISTS tokens ( + token_id INTEGER PRIMARY KEY AUTOINCREMENT +,token_user_id INTEGER +,token_kind VARCHAR +,token_label VARCHAR +,token_expiry INTEGER +,token_issued INTEGER +); +` + +const stmtTokenTokenUserIdIndex = ` +CREATE INDEX IF NOT EXISTS ix_token_user_id ON tokens (token_user_id); +` + +const stmtTokenTokenUserLabelIndex = ` +CREATE UNIQUE INDEX IF NOT EXISTS ux_token_user_label ON tokens (token_user_id,token_label); +` diff --git a/pkg/store/builtin/user.go b/pkg/store/builtin/user.go index ddd5126c6..5027e6ac1 100644 --- a/pkg/store/builtin/user.go +++ b/pkg/store/builtin/user.go @@ -1,106 +1,71 @@ package builtin import ( + "database/sql" "time" "github.com/drone/drone/Godeps/_workspace/src/github.com/russross/meddler" - common "github.com/drone/drone/pkg/types" + "github.com/drone/drone/pkg/types" ) type Userstore struct { - meddler.DB + *sql.DB } -func NewUserstore(db meddler.DB) *Userstore { +func NewUserstore(db *sql.DB) *Userstore { return &Userstore{db} } // User returns a user by user ID. -func (db *Userstore) User(id int64) (*common.User, error) { - var usr = new(common.User) - var err = meddler.Load(db, userTable, usr, id) - return usr, err +func (db *Userstore) User(id int64) (*types.User, error) { + return getUser(db, rebind(stmtUserSelect), id) } // UserLogin returns a user by user login. -func (db *Userstore) UserLogin(login string) (*common.User, error) { - var usr = new(common.User) - var err = meddler.QueryRow(db, usr, rebind(userLoginQuery), login) - return usr, err +func (db *Userstore) UserLogin(login string) (*types.User, error) { + return getUser(db, rebind(stmtUserSelectUserLogin), login) } // UserList returns a list of all registered users. -func (db *Userstore) UserList() ([]*common.User, error) { - var users []*common.User - var err = meddler.QueryAll(db, &users, rebind(userListQuery)) - return users, err +func (db *Userstore) UserList() ([]*types.User, error) { + return getUsers(db, rebind(stmtUserSelectList)) } // UserFeed retrieves a digest of recent builds // from the datastore accessible to the specified user. -func (db *Userstore) UserFeed(user *common.User, limit, offset int) ([]*common.RepoCommit, error) { - var builds []*common.RepoCommit +func (db *Userstore) UserFeed(user *types.User, limit, offset int) ([]*types.RepoCommit, error) { + var builds []*types.RepoCommit var err = meddler.QueryAll(db, &builds, rebind(userFeedQuery), user.ID, limit, offset) return builds, err } // UserCount returns a count of all registered users. func (db *Userstore) UserCount() (int, error) { - var count = struct{ Count int }{} - var err = meddler.QueryRow(db, &count, rebind(userCountQuery)) - return count.Count, err + var count int + err := db.QueryRow(stmtUserSelectCount).Scan(&count) + return count, err } // AddUser inserts a new user into the datastore. // If the user login already exists an error is returned. -func (db *Userstore) AddUser(user *common.User) error { +func (db *Userstore) AddUser(user *types.User) error { user.Created = time.Now().UTC().Unix() user.Updated = time.Now().UTC().Unix() - return meddler.Insert(db, userTable, user) + return createUser(db, rebind(stmtUserInsert), user) } // SetUser updates an existing user. -func (db *Userstore) SetUser(user *common.User) error { +func (db *Userstore) SetUser(user *types.User) error { user.Updated = time.Now().UTC().Unix() - return meddler.Update(db, userTable, user) + return updateUser(db, rebind(stmtUserUpdate), user) } // DelUser removes the user from the datastore. -func (db *Userstore) DelUser(user *common.User) error { - var _, err = db.Exec(rebind(userDeleteStmt), user.ID) +func (db *Userstore) DelUser(user *types.User) error { + var _, err = db.Exec(rebind(stmtUserDelete), user.ID) return err } -// User table name in database. -const userTable = "users" - -// SQL query to retrieve a User by remote login. -const userLoginQuery = ` -SELECT * -FROM users -WHERE user_login=? -LIMIT 1 -` - -// SQL query to retrieve a list of all users. -const userListQuery = ` -SELECT * -FROM users -ORDER BY user_name ASC -` - -// SQL query to retrieve a list of all users. -const userCountQuery = ` -SELECT count(1) as "Count" -FROM users -` - -// SQL statement to delete a User by ID. -const userDeleteStmt = ` -DELETE FROM users -WHERE user_id=? -` - // SQL query to retrieve a build feed for the given // user account. const userFeedQuery = ` @@ -108,7 +73,7 @@ SELECT r.repo_id ,r.repo_owner ,r.repo_name -,r.repo_slug +,r.repo_full_name ,c.commit_seq ,c.commit_state ,c.commit_started diff --git a/pkg/store/builtin/user_sql.go b/pkg/store/builtin/user_sql.go new file mode 100644 index 000000000..3c0151238 --- /dev/null +++ b/pkg/store/builtin/user_sql.go @@ -0,0 +1,338 @@ +package builtin + +// DO NOT EDIT +// code generated by go:generate + +import ( + "database/sql" + "encoding/json" + + . "github.com/drone/drone/pkg/types" +) + +var _ = json.Marshal + +// generic database interface, matching both *sql.Db and *sql.Tx +type userDB interface { + Exec(query string, args ...interface{}) (sql.Result, error) + Query(query string, args ...interface{}) (*sql.Rows, error) + QueryRow(query string, args ...interface{}) *sql.Row +} + +func getUser(db userDB, query string, args ...interface{}) (*User, error) { + row := db.QueryRow(query, args...) + return scanUser(row) +} + +func getUsers(db userDB, query string, args ...interface{}) ([]*User, error) { + rows, err := db.Query(query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + return scanUsers(rows) +} + +func createUser(db userDB, query string, v *User) error { + var v0 string + var v1 string + var v2 string + var v3 string + var v4 string + var v5 string + var v6 bool + var v7 bool + var v8 int64 + var v9 int64 + v0 = v.Login + v1 = v.Token + v2 = v.Secret + v3 = v.Name + v4 = v.Email + v5 = v.Gravatar + v6 = v.Admin + v7 = v.Active + v8 = v.Created + v9 = v.Updated + + res, err := db.Exec(query, + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + ) + if err != nil { + return err + } + + v.ID, err = res.LastInsertId() + return err +} + +func updateUser(db userDB, query string, v *User) error { + var v0 int64 + var v1 string + var v2 string + var v3 string + var v4 string + var v5 string + var v6 string + var v7 bool + var v8 bool + var v9 int64 + var v10 int64 + v0 = v.ID + v1 = v.Login + v2 = v.Token + v3 = v.Secret + v4 = v.Name + v5 = v.Email + v6 = v.Gravatar + v7 = v.Admin + v8 = v.Active + v9 = v.Created + v10 = v.Updated + + _, err := db.Exec(query, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + &v0, + ) + return err +} + +func scanUser(row *sql.Row) (*User, error) { + var v0 int64 + var v1 string + var v2 string + var v3 string + var v4 string + var v5 string + var v6 string + var v7 bool + var v8 bool + var v9 int64 + var v10 int64 + + err := row.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + ) + if err != nil { + return nil, err + } + + v := &User{} + v.ID = v0 + v.Login = v1 + v.Token = v2 + v.Secret = v3 + v.Name = v4 + v.Email = v5 + v.Gravatar = v6 + v.Admin = v7 + v.Active = v8 + v.Created = v9 + v.Updated = v10 + + return v, nil +} + +func scanUsers(rows *sql.Rows) ([]*User, error) { + var err error + var vv []*User + for rows.Next() { + var v0 int64 + var v1 string + var v2 string + var v3 string + var v4 string + var v5 string + var v6 string + var v7 bool + var v8 bool + var v9 int64 + var v10 int64 + err = rows.Scan( + &v0, + &v1, + &v2, + &v3, + &v4, + &v5, + &v6, + &v7, + &v8, + &v9, + &v10, + ) + if err != nil { + return vv, err + } + + v := &User{} + v.ID = v0 + v.Login = v1 + v.Token = v2 + v.Secret = v3 + v.Name = v4 + v.Email = v5 + v.Gravatar = v6 + v.Admin = v7 + v.Active = v8 + v.Created = v9 + v.Updated = v10 + vv = append(vv, v) + } + return vv, rows.Err() +} + +const stmtUserSelectList = ` +SELECT + user_id +,user_login +,user_token +,user_secret +,user_name +,user_email +,user_gravatar +,user_admin +,user_active +,user_created +,user_updated +FROM users +` + +const stmtUserSelectRange = ` +SELECT + user_id +,user_login +,user_token +,user_secret +,user_name +,user_email +,user_gravatar +,user_admin +,user_active +,user_created +,user_updated +FROM users +LIMIT ? OFFSET ? +` + +const stmtUserSelect = ` +SELECT + user_id +,user_login +,user_token +,user_secret +,user_name +,user_email +,user_gravatar +,user_admin +,user_active +,user_created +,user_updated +FROM users +WHERE user_id = ? +` + +const stmtUserSelectUserLogin = ` +SELECT + user_id +,user_login +,user_token +,user_secret +,user_name +,user_email +,user_gravatar +,user_admin +,user_active +,user_created +,user_updated +FROM users +WHERE user_login = ? +` + +const stmtUserSelectCount = ` +SELECT count(1) +FROM users +` + +const stmtUserInsert = ` +INSERT INTO users ( + user_login +,user_token +,user_secret +,user_name +,user_email +,user_gravatar +,user_admin +,user_active +,user_created +,user_updated +) VALUES (?,?,?,?,?,?,?,?,?,?); +` + +const stmtUserUpdate = ` +UPDATE users SET + user_login = ? +,user_token = ? +,user_secret = ? +,user_name = ? +,user_email = ? +,user_gravatar = ? +,user_admin = ? +,user_active = ? +,user_created = ? +,user_updated = ? +WHERE user_id = ? +` + +const stmtUserDelete = ` +DELETE FROM users +WHERE user_id = ? +` + +const stmtUserTable = ` +CREATE TABLE IF NOT EXISTS users ( + user_id INTEGER PRIMARY KEY AUTOINCREMENT +,user_login VARCHAR +,user_token VARCHAR +,user_secret VARCHAR +,user_name VARCHAR +,user_email VARCHAR +,user_gravatar VARCHAR +,user_admin BOOLEAN +,user_active BOOLEAN +,user_created INTEGER +,user_updated INTEGER +); +` + +const stmtUserUserLoginIndex = ` +CREATE UNIQUE INDEX IF NOT EXISTS ux_user_login ON users (user_login); +` diff --git a/pkg/store/builtin/users_test.go b/pkg/store/builtin/users_test.go index 171917ee1..07c4507ad 100644 --- a/pkg/store/builtin/users_test.go +++ b/pkg/store/builtin/users_test.go @@ -162,6 +162,12 @@ func TestUserstore(t *testing.T) { g.Assert(count).Equal(2) }) + g.It("Should Get a User Count Zero", func() { + count, err := us.UserCount() + g.Assert(err == nil).IsTrue() + g.Assert(count).Equal(0) + }) + g.It("Should Del a User", func() { user := common.User{ Login: "joe", diff --git a/pkg/types/build.go b/pkg/types/build.go index ed0b10f74..27a8fd83a 100644 --- a/pkg/types/build.go +++ b/pkg/types/build.go @@ -1,18 +1,18 @@ package types type Build struct { - ID int64 `meddler:"build_id,pk" json:"id"` - CommitID int64 `meddler:"commit_id" json:"-"` - State string `meddler:"build_state" json:"state"` - ExitCode int `meddler:"build_exit" json:"exit_code"` - Sequence int `meddler:"build_seq" json:"sequence"` - Duration int64 `meddler:"build_duration" json:"duration"` - Started int64 `meddler:"build_started" json:"started_at"` - Finished int64 `meddler:"build_finished" json:"finished_at"` - Created int64 `meddler:"build_created" json:"created_at"` - Updated int64 `meddler:"build_updated" json:"updated_at"` + ID int64 `meddler:"build_id,pk" json:"id"` + CommitID int64 `meddler:"build_commit_id" json:"-" sql:"unique:ux_build_seq,index:ix_build_commit_id"` + State string `meddler:"build_state" json:"state"` + ExitCode int `meddler:"build_exit_code" json:"exit_code"` + Sequence int `meddler:"build_sequence" json:"sequence" sql:"unique:ux_build_seq"` + Duration int64 `meddler:"build_duration" json:"duration"` + Started int64 `meddler:"build_started" json:"started_at"` + Finished int64 `meddler:"build_finished" json:"finished_at"` + Created int64 `meddler:"build_created" json:"created_at"` + Updated int64 `meddler:"build_updated" json:"updated_at"` - Environment map[string]string `meddler:"build_env,json" json:"environment"` + Environment map[string]string `meddler:"build_environment,json" json:"environment" sql:"type:varchar,size:2048"` } // QUESTION: should we track if it was oom killed? diff --git a/pkg/types/repo.go b/pkg/types/repo.go index a8d9b683f..5126e3896 100644 --- a/pkg/types/repo.go +++ b/pkg/types/repo.go @@ -1,26 +1,26 @@ package types type Repo struct { - ID int64 `meddler:"repo_id,pk" json:"id"` - UserID int64 `meddler:"user_id" json:"-"` - Owner string `meddler:"repo_owner" json:"owner"` - Name string `meddler:"repo_name" json:"name"` - FullName string `meddler:"repo_slug" json:"full_name"` - Token string `meddler:"repo_token" json:"-"` - Language string `meddler:"repo_lang" json:"language"` - Private bool `meddler:"repo_private" json:"private"` - Self string `meddler:"repo_self" json:"self_url"` - Link string `meddler:"repo_link" json:"link_url"` - Clone string `meddler:"repo_clone" json:"clone_url"` - Branch string `meddler:"repo_branch" json:"default_branch"` - Timeout int64 `meddler:"repo_timeout" json:"timeout"` - Trusted bool `meddler:"repo_trusted" json:"trusted"` - PostCommit bool `meddler:"repo_push" json:"post_commits"` - PullRequest bool `meddler:"repo_pull" json:"pull_requests"` - PublicKey string `meddler:"repo_public_key" json:"-"` - PrivateKey string `meddler:"repo_private_key" json:"-"` - Created int64 `meddler:"repo_created" json:"created_at"` - Updated int64 `meddler:"repo_updated" json:"updated_at"` + ID int64 `meddler:"repo_id,pk" json:"id"` + UserID int64 `meddler:"repo_user_id" json:"-" sql:"index:ix_repo_user_id"` + Owner string `meddler:"repo_owner" json:"owner" sql:"unique:ux_repo_owner_name"` + Name string `meddler:"repo_name" json:"name" sql:"unique:ux_repo_owner_name"` + FullName string `meddler:"repo_full_name" json:"full_name" sql:"unique:ux_repo_full_name"` + Token string `meddler:"repo_token" json:"-"` + Language string `meddler:"repo_language" json:"language"` + Private bool `meddler:"repo_private" json:"private"` + Self string `meddler:"repo_self" json:"self_url"` + Link string `meddler:"repo_link" json:"link_url"` + Clone string `meddler:"repo_clone" json:"clone_url"` + Branch string `meddler:"repo_branch" json:"default_branch"` + Timeout int64 `meddler:"repo_timeout" json:"timeout"` + Trusted bool `meddler:"repo_trusted" json:"trusted"` + PostCommit bool `meddler:"repo_post_commit" json:"post_commits"` + PullRequest bool `meddler:"repo_pull_request" json:"pull_requests"` + PublicKey string `meddler:"repo_public_key" json:"-"` + PrivateKey string `meddler:"repo_private_key" json:"-"` + Created int64 `meddler:"repo_created" json:"created_at"` + Updated int64 `meddler:"repo_updated" json:"updated_at"` Params map[string]string `meddler:"repo_params,json" json:"-"` } @@ -41,7 +41,7 @@ type RepoCommit struct { ID int64 `meddler:"repo_id,pk" json:"id"` Owner string `meddler:"repo_owner" json:"owner"` Name string `meddler:"repo_name" json:"name"` - FullName string `meddler:"repo_slug" json:"full_name"` + FullName string `meddler:"repo_full_name" json:"full_name"` Number int `meddler:"commit_seq" json:"number"` State string `meddler:"commit_state" json:"state"` Started int64 `meddler:"commit_started" json:"started_at"` diff --git a/pkg/types/token.go b/pkg/types/token.go index e83463efa..c0d5e93d6 100644 --- a/pkg/types/token.go +++ b/pkg/types/token.go @@ -2,10 +2,10 @@ package types type Token struct { ID int64 `meddler:"token_id,pk" json:"-"` - UserID int64 `meddler:"user_id" json:"-"` - Login string `meddler:"-" json:"-"` + UserID int64 `meddler:"token_user_id" json:"-" sql:"index:ix_token_user_id,unique:ux_token_user_label"` + Login string `meddler:"-" json:"-" sql:"-"` Kind string `meddler:"token_kind" json:"kind,omitempty"` - Label string `meddler:"token_label" json:"label,omitempty"` + Label string `meddler:"token_label" json:"label,omitempty" sql:"unique:ux_token_user_label"` Expiry int64 `meddler:"token_expiry" json:"expiry,omitempty"` Issued int64 `meddler:"token_issued" json:"issued_at,omitempty"` } diff --git a/pkg/types/user.go b/pkg/types/user.go index a7f846a68..813df01d5 100644 --- a/pkg/types/user.go +++ b/pkg/types/user.go @@ -2,7 +2,7 @@ package types type User struct { ID int64 `meddler:"user_id,pk" json:"id"` - Login string `meddler:"user_login" json:"login,omitempty"` + Login string `meddler:"user_login" json:"login,omitempty" sql:"unique:ux_user_login"` Token string `meddler:"user_token" json:"-"` Secret string `meddler:"user_secret" json:"-"` Name string `meddler:"user_name" json:"name,omitempty"`