gorm-goose/lib/goose/dbconf.go
2016-09-09 15:12:30 +03:00

117 lines
2.5 KiB
Go

package goose
import (
"fmt"
"os"
"path/filepath"
"github.com/jinzhu/gorm"
"github.com/kylelemons/go-gypsy/yaml"
)
// DBDriver encapsulates the info needed to work with
// a specific database driver
type DBDriver struct {
Name string
OpenStr string
Import string
}
type DBConf struct {
MigrationsDir string
Env string
Driver DBDriver
PgSchema string
}
// NewDBConf extract configuration details from the given file
func NewDBConf(p, env string, pgschema string) (*DBConf, error) {
cfgFile := filepath.Join(p, "dbconf.yml")
f, err := yaml.ReadFile(cfgFile)
if err != nil {
return nil, err
}
drv, err := f.Get(fmt.Sprintf("%s.driver", env))
if err != nil {
return nil, err
}
drv = os.ExpandEnv(drv)
open, err := f.Get(fmt.Sprintf("%s.open", env))
if err != nil {
return nil, err
}
open = os.ExpandEnv(open)
d := newDBDriver(drv, open)
// allow the configuration to override the Import for this driver
if imprt, err := f.Get(fmt.Sprintf("%s.import", env)); err == nil {
d.Import = imprt
}
if !d.IsValid() {
return nil, fmt.Errorf("Invalid DBConf: %v", d)
}
return &DBConf{
MigrationsDir: filepath.Join(p, "migrations"),
Env: env,
Driver: d,
PgSchema: pgschema,
}, nil
}
// Create a new DBDriver and populate driver specific
// fields for drivers that we know about.
// Further customization may be done in NewDBConf
func newDBDriver(name, open string) DBDriver {
d := DBDriver{
Name: name,
OpenStr: open,
}
switch name {
case "postgres":
d.Import = "github.com/jinzhu/gorm/dialects/postgres"
case "mysql":
d.Import = "github.com/jinzhu/gorm/dialects/mysql"
d.OpenStr = d.OpenStr + "?charset=utf8&parseTime=True&loc=Local"
case "sqlite3":
d.Import = "github.com/jinzhu/gorm/dialects/sqlite"
}
return d
}
// IsValid ensure we have enough info about this driver
func (drv *DBDriver) IsValid() bool {
return len(drv.Import) > 0
}
// OpenDBFromDBConf wraps database/sql.DB.Open() and configures
// the newly opened DB based on the given DBConf.
//
// Callers must Close() the returned DB.
func OpenDBFromDBConf(conf *DBConf) (*gorm.DB, error) {
db, err := gorm.Open(conf.Driver.Name, conf.Driver.OpenStr)
if err != nil {
return nil, err
}
// if a postgres schema has been specified, apply it
if conf.Driver.Name == "postgres" && conf.PgSchema != "" {
if err := db.Exec("SET search_path TO " + conf.PgSchema).Error; err != nil {
return nil, err
}
}
return db, nil
}