Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Commit

Permalink
create ./bin/db to manage database (at least for testing)
Browse files Browse the repository at this point in the history
  • Loading branch information
alovak committed Sep 21, 2020
1 parent fb3c1fe commit 1d26964
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 75 deletions.
150 changes: 150 additions & 0 deletions cmd/db/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package main

import (
"database/sql"
"flag"
"fmt"
"os"
"strings"

"github.com/go-kit/kit/log"
"github.com/kelseyhightower/envconfig"
"github.com/moov-io/customers/internal/database"
)

var flagLogFormat = flag.String("log.format", "", "Format for log lines (Options: json, plain")

type Config struct {
RootPassword string `split_words:"true" default:"secret"`
User string `default:"moov"`
Password string `default:"secret"`
Address string `default:"tcp(localhost:3306)"`
Database string `default:"paygate_test"`
}

func main() {
var config Config
err := envconfig.Process("mysql", &config)
if err != nil {
panic(err)
}

err = runCmd(os.Args[1], &config)
if err != nil {
panic(err)
}
}

func runCmd(cmd string, config *Config) error {
switch cmd {
case "setup":
err := dropDB(config)
if err != nil {
return err
}

err = createDB(config)
if err != nil {
return err
}

err = migrateDB(config)
if err != nil {
return err
}
case "create":
err := createDB(config)
if err != nil {
return err
}
case "drop":
err := dropDB(config)
if err != nil {
return err
}
case "migrate":
err := migrateDB(config)
if err != nil {
return err
}
}

return nil
}

func dropDB(config *Config) error {
dsn := fmt.Sprintf("root:%s@%s/", config.RootPassword, config.Address)
db, err := sql.Open("mysql", dsn)
if err != nil {
return err
}
defer db.Close()

_, err = db.Exec("DROP DATABASE IF EXISTS " + config.Database)
if err != nil {
return err
}

fmt.Printf("Database %s was deleted\n", config.Database)
return nil
}

func createDB(config *Config) error {
dsn := fmt.Sprintf("root:%s@%s/", config.RootPassword, config.Address)
db, err := sql.Open("mysql", dsn)
if err != nil {
return err
}
defer db.Close()

_, err = db.Exec("CREATE DATABASE " + config.Database)
if err != nil {
return err
}

_, err = db.Exec(fmt.Sprintf("CREATE USER IF NOT EXISTS '%s'@'%%' IDENTIFIED BY '%s'", config.User, config.Password))
if err != nil {
return err
}

_, err = db.Exec(fmt.Sprintf("GRANT ALL PRIVILEGES ON %s . * TO '%s'@'%%';", config.Database, config.User))
if err != nil {
return err
}

fmt.Printf("Database %s was created\n", config.Database)
return nil
}

// TODO: having migration inside database.New (inside Connect method) makes it
// ambiguous we should extract migtation method into separate public method
// that we can call from here.
func migrateDB(config *Config) error {
var logger log.Logger

// migrate database
if strings.ToLower(*flagLogFormat) == "json" {
logger = log.NewJSONLogger(os.Stderr)
} else {
logger = log.NewLogfmtLogger(os.Stderr)
}
logger = log.With(logger, "ts", log.DefaultTimestampUTC)
logger = log.With(logger, "caller", log.DefaultCaller)

dbConf := &database.MySQLConfig{
User: config.User,
Password: config.Password,
Address: config.Address,
Database: config.Database,
}

db, err := database.NewMySQL(logger, dbConf)
if err != nil {
return err
}
db.Close()

fmt.Printf("Database %s was migrated\n", config.Database)

return nil
}
70 changes: 0 additions & 70 deletions cmd/migrate/main.go

This file was deleted.

2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v0.5.4
github.com/hashicorp/vault/api v1.0.4
github.com/kelseyhightower/envconfig v1.4.0
github.com/lopezator/migrator v0.3.0
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/mitchellh/mapstructure v1.3.3
Expand All @@ -37,6 +38,7 @@ require (
github.com/plaid/plaid-go v0.0.0-20200805000941-b566963d2892
github.com/prometheus/client_golang v1.7.1
github.com/prometheus/common v0.13.0 // indirect
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.6.1
gocloud.dev v0.20.0
gocloud.dev/secrets/hashivault v0.20.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,8 @@ github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
Expand Down
21 changes: 17 additions & 4 deletions internal/database/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"os"
"strings"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -177,6 +178,17 @@ func (my *mysql) Connect() (*sql.DB, error) {
return db, nil
}

type MySQLConfig struct {
User string
Password string
Address string
Database string
}

func NewMySQL(logger log.Logger, config *MySQLConfig) (*sql.DB, error) {
return mysqlConnection(logger, config.User, config.Password, config.Address, config.Database).Connect()
}

func mysqlConnection(logger log.Logger, user, pass string, address string, database string) *mysql {
timeout := "30s"
if v := os.Getenv("MYSQL_TIMEOUT"); v != "" {
Expand Down Expand Up @@ -219,7 +231,6 @@ func CreateTestMySQLDB(t *testing.T) *TestMySQLDB {
if os.Getenv("MYSQL_TEST") != "" {
params := "timeout=30s&charset=utf8mb4&parseTime=true&sql_mode=ALLOW_INVALID_DATES"
dsn := fmt.Sprintf("%s:%s@%s/%s?%s", "moov", "secret", "tcp(localhost:3306)", "paygate_test", params)

db, err := TestConnect(dsn)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -286,11 +297,13 @@ func MySQLUniqueViolation(err error) bool {
return match
}

func init() {
txdb.Register("txdb", "mysql", "moov:secret@tcp(localhost:3306)/paygate_test?timeout=30s&charset=utf8mb4&parseTime=true&sql_mode=ALLOW_INVALID_DATES")
}
var initTestDbOnce sync.Once

func TestConnect(dsn string) (*sql.DB, error) {
initTestDbOnce.Do(func() {
txdb.Register("txdb", "mysql", dsn)
})

db, err := sql.Open("txdb", "identifier")
if err != nil {
return nil, err
Expand Down
3 changes: 2 additions & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@ AUTHORS:

.PHONY: setup_test_db
setup_test_db:
DATABASE_TYPE=mysql MYSQL_ROOT_PASSWORD=secret MYSQL_USER=moov MYSQL_PASSWORD=secret MYSQL_ADDRESS="tcp(localhost:3306)" MYSQL_DATABASE=paygate_test go run cmd/migrate/main.go
CGO_ENABLED=1 go build -o ./bin/db github.com/moov-io/customers/cmd/db
MYSQL_ROOT_PASSWORD=secret MYSQL_USER=moov MYSQL_PASSWORD=secret MYSQL_ADDRESS="tcp(localhost:3306)" MYSQL_DATABASE=paygate_test ./bin/db setup

0 comments on commit 1d26964

Please sign in to comment.