From dc0e714992576a85ed8b00e0c7b45dacc4954d17 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Sun, 14 Jun 2015 23:26:49 -0700 Subject: [PATCH] loading database via driver --- cmd/drone-server/drone.go | 12 +++-- pkg/store/builtin/store.go | 23 ++++++++ pkg/store/store.go | 105 +++++++++++++++++++++++++------------ 3 files changed, 102 insertions(+), 38 deletions(-) diff --git a/cmd/drone-server/drone.go b/cmd/drone-server/drone.go index 151812d8..a90575db 100644 --- a/cmd/drone-server/drone.go +++ b/cmd/drone-server/drone.go @@ -4,6 +4,7 @@ import ( "flag" "html/template" "net/http" + "os" "github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin" @@ -17,7 +18,9 @@ import ( eventbus "github.com/drone/drone/pkg/bus/builtin" queue "github.com/drone/drone/pkg/queue/builtin" runner "github.com/drone/drone/pkg/runner/builtin" - store "github.com/drone/drone/pkg/store/builtin" + "github.com/drone/drone/pkg/store" + + _ "github.com/drone/drone/pkg/store/builtin" _ "net/http/pprof" ) @@ -42,9 +45,10 @@ func main() { panic(err) } - db := store.MustConnect(settings.Database.Driver, settings.Database.Datasource) - store := store.New(db) - defer db.Close() + store, err := store.New(os.Getenv("DATABASE")) + if err != nil { + panic(err) + } remote := github.New(settings) session := session.New(settings) diff --git a/pkg/store/builtin/store.go b/pkg/store/builtin/store.go index 8b715407..47a4fff1 100644 --- a/pkg/store/builtin/store.go +++ b/pkg/store/builtin/store.go @@ -2,6 +2,7 @@ package builtin import ( "database/sql" + "net/url" "os" "github.com/drone/drone/pkg/store" @@ -19,6 +20,28 @@ const ( driverMysql = "mysql" ) +func init() { + store.Register("sqlite3", NewDriver) + store.Register("postgres", NewDriver) +} + +func NewDriver(dsn string) (store.Store, error) { + uri, err := url.Parse(dsn) + if err != nil { + return nil, err + } + driver := uri.Scheme + if uri.Scheme == "sqlite3" { + uri.Scheme = "" + } + datasource := uri.String() + conn, err := Connect(driver, datasource) + if err != nil { + return nil, err + } + return New(conn), nil +} + // Connect is a helper function that establishes a new // database connection and auto-generates the database // schema. If the database already exists, it will perform diff --git a/pkg/store/store.go b/pkg/store/store.go index bbf44b8c..af5c2332 100644 --- a/pkg/store/store.go +++ b/pkg/store/store.go @@ -1,115 +1,152 @@ package store import ( + "fmt" "io" + "net/url" - common "github.com/drone/drone/pkg/types" + "github.com/drone/drone/pkg/types" ) +var drivers = make(map[string]DriverFunc) + +// Register makes a datastore driver available by the provided name. +// If Register is called twice with the same name or if driver is nil, +// it panics. +func Register(name string, driver DriverFunc) { + if driver == nil { + panic("datastore: Register driver is nil") + } + if _, dup := drivers[name]; dup { + panic("datastore: Register called twice for driver " + name) + } + drivers[name] = driver +} + +// DriverFunc returns a new connection to the datastore. +// The name is a string in a driver-specific format. +type DriverFunc func(name string) (Store, error) + +// New creates a new database connection specified by its database driver +// name and a driver-specific data source name, usually consisting of at +// least a database name and connection information. +func New(dsn string) (Store, error) { + uri, err := url.Parse(dsn) + if err != nil { + return nil, err + } + driver := uri.Scheme + fn, ok := drivers[driver] + if !ok { + return nil, fmt.Errorf("datastore: unknown driver %q", driver) + } + return fn(dsn) +} + type Store interface { // User returns a user by user ID. - User(id int64) (*common.User, error) + User(id int64) (*types.User, error) // UserLogin returns a user by user login. - UserLogin(string) (*common.User, error) + UserLogin(string) (*types.User, error) // UserList returns a list of all registered users. - UserList() ([]*common.User, error) + UserList() ([]*types.User, error) // UserFeed retrieves a digest of recent builds // from the datastore accessible to the specified user. - UserFeed(*common.User, int, int) ([]*common.RepoCommit, error) + UserFeed(*types.User, int, int) ([]*types.RepoCommit, error) // UserCount returns a count of all registered users. UserCount() (int, error) // AddUser inserts a new user into the datastore. // If the user login already exists an error is returned. - AddUser(*common.User) error + AddUser(*types.User) error // SetUser updates an existing user. - SetUser(*common.User) error + SetUser(*types.User) error // DelUser removes the user from the datastore. - DelUser(*common.User) error + DelUser(*types.User) error // // Token returns a token by ID. - Token(int64) (*common.Token, error) + Token(int64) (*types.Token, error) // TokenLabel returns a token by label - TokenLabel(*common.User, string) (*common.Token, error) + TokenLabel(*types.User, string) (*types.Token, error) // TokenList returns a list of all user tokens. - TokenList(*common.User) ([]*common.Token, error) + TokenList(*types.User) ([]*types.Token, error) // AddToken inserts a new token into the datastore. // If the token label already exists for the user // an error is returned. - AddToken(*common.Token) error + AddToken(*types.Token) error // DelToken removes the DelToken from the datastore. - DelToken(*common.Token) error + DelToken(*types.Token) error // // Starred returns true if the user starred // the given repository. - Starred(*common.User, *common.Repo) (bool, error) + Starred(*types.User, *types.Repo) (bool, error) // AddStar stars a repository. - AddStar(*common.User, *common.Repo) error + AddStar(*types.User, *types.Repo) error // DelStar unstars a repository. - DelStar(*common.User, *common.Repo) error + DelStar(*types.User, *types.Repo) error // // Repo retrieves a specific repo from the // datastore for the given ID. - Repo(id int64) (*common.Repo, error) + Repo(id int64) (*types.Repo, error) // RepoName retrieves a repo from the datastore // for the specified name. - RepoName(owner, name string) (*common.Repo, error) + RepoName(owner, name string) (*types.Repo, error) // RepoList retrieves a list of all repos from // the datastore accessible by the given user ID. - RepoList(*common.User) ([]*common.Repo, error) + RepoList(*types.User) ([]*types.Repo, error) // AddRepo inserts a repo in the datastore. - AddRepo(*common.Repo) error + AddRepo(*types.Repo) error // SetRepo updates a repo in the datastore. - SetRepo(*common.Repo) error + SetRepo(*types.Repo) error // DelRepo removes the repo from the datastore. - DelRepo(*common.Repo) error + DelRepo(*types.Repo) error // // Commit gets a commit by ID - Commit(int64) (*common.Commit, error) + Commit(int64) (*types.Commit, error) // CommitSeq gets the specified commit sequence for the // named repository and commit number - CommitSeq(*common.Repo, int) (*common.Commit, error) + CommitSeq(*types.Repo, int) (*types.Commit, error) // CommitLast gets the last executed commit for the // named repository and branch - CommitLast(*common.Repo, string) (*common.Commit, error) + CommitLast(*types.Repo, string) (*types.Commit, error) // CommitList gets a list of recent commits for the // named repository. - CommitList(*common.Repo, int, int) ([]*common.Commit, error) + CommitList(*types.Repo, int, int) ([]*types.Commit, error) // AddCommit inserts a new commit in the datastore. - AddCommit(*common.Commit) error + AddCommit(*types.Commit) error // SetCommit updates an existing commit and commit tasks. - SetCommit(*common.Commit) error + SetCommit(*types.Commit) error // KillCommits updates all pending or started commits // in the datastore settings the status to killed. @@ -118,16 +155,16 @@ type Store interface { // // Build returns a build by ID. - Build(int64) (*common.Build, error) + Build(int64) (*types.Build, error) // BuildSeq returns a build by sequence number. - BuildSeq(*common.Commit, int) (*common.Build, error) + BuildSeq(*types.Commit, int) (*types.Build, error) // BuildList returns a list of all commit builds - BuildList(*common.Commit) ([]*common.Build, error) + BuildList(*types.Commit) ([]*types.Build, error) // SetBuild updates an existing build. - SetBuild(*common.Build) error + SetBuild(*types.Build) error // @@ -152,8 +189,8 @@ type Store interface { // // Agent returns an agent by ID. - Agent(*common.Commit) (string, error) + Agent(*types.Commit) (string, error) // SetAgent updates an agent in the datastore. - SetAgent(*common.Commit, string) error + SetAgent(*types.Commit, string) error }