mirror of
https://github.com/TECHNOFAB11/dbmate.git
synced 2025-12-11 23:50:04 +01:00
Write log lines to DB.Log output (#195)
This makes it possible to redirect the logs somewhere else, useful if you embed dbmate into your application.
This commit is contained in:
parent
454f93a000
commit
2bac2c7590
6 changed files with 44 additions and 26 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
|
|
@ -41,6 +42,7 @@ type DB struct {
|
|||
WaitBefore bool
|
||||
WaitInterval time.Duration
|
||||
WaitTimeout time.Duration
|
||||
Log io.Writer
|
||||
}
|
||||
|
||||
// migrationFileRegexp pattern for valid migration files
|
||||
|
|
@ -63,6 +65,7 @@ func New(databaseURL *url.URL) *DB {
|
|||
WaitBefore: false,
|
||||
WaitInterval: DefaultWaitInterval,
|
||||
WaitTimeout: DefaultWaitTimeout,
|
||||
Log: os.Stdout,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,6 +83,7 @@ func (db *DB) GetDriver() (Driver, error) {
|
|||
config := DriverConfig{
|
||||
DatabaseURL: db.DatabaseURL,
|
||||
MigrationsTableName: db.MigrationsTableName,
|
||||
Log: db.Log,
|
||||
}
|
||||
|
||||
return driverFunc(config), nil
|
||||
|
|
@ -104,22 +108,22 @@ func (db *DB) wait(drv Driver) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
fmt.Print("Waiting for database")
|
||||
fmt.Fprint(db.Log, "Waiting for database")
|
||||
for i := 0 * time.Second; i < db.WaitTimeout; i += db.WaitInterval {
|
||||
fmt.Print(".")
|
||||
fmt.Fprint(db.Log, ".")
|
||||
time.Sleep(db.WaitInterval)
|
||||
|
||||
// attempt connection to database server
|
||||
err = drv.Ping()
|
||||
if err == nil {
|
||||
// connection successful
|
||||
fmt.Print("\n")
|
||||
fmt.Fprint(db.Log, "\n")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// if we find outselves here, we could not connect within the timeout
|
||||
fmt.Print("\n")
|
||||
fmt.Fprint(db.Log, "\n")
|
||||
return fmt.Errorf("unable to connect to database: %s", err)
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +218,7 @@ func (db *DB) dumpSchema(drv Driver) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Writing: %s\n", db.SchemaFile)
|
||||
fmt.Fprintf(db.Log, "Writing: %s\n", db.SchemaFile)
|
||||
|
||||
// ensure schema directory exists
|
||||
if err = ensureDir(filepath.Dir(db.SchemaFile)); err != nil {
|
||||
|
|
@ -252,7 +256,7 @@ func (db *DB) NewMigration(name string) error {
|
|||
|
||||
// check file does not already exist
|
||||
path := filepath.Join(db.MigrationsDir, name)
|
||||
fmt.Printf("Creating migration: %s\n", path)
|
||||
fmt.Fprintf(db.Log, "Creating migration: %s\n", path)
|
||||
|
||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||
return fmt.Errorf("file already exists")
|
||||
|
|
@ -345,7 +349,7 @@ func (db *DB) migrate(drv Driver) error {
|
|||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("Applying: %s\n", filename)
|
||||
fmt.Fprintf(db.Log, "Applying: %s\n", filename)
|
||||
|
||||
up, _, err := parseMigration(filepath.Join(db.MigrationsDir, filename))
|
||||
if err != nil {
|
||||
|
|
@ -358,7 +362,7 @@ func (db *DB) migrate(drv Driver) error {
|
|||
if err != nil {
|
||||
return err
|
||||
} else if db.Verbose {
|
||||
printVerbose(result)
|
||||
db.printVerbose(result)
|
||||
}
|
||||
|
||||
// record migration
|
||||
|
|
@ -386,14 +390,14 @@ func (db *DB) migrate(drv Driver) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func printVerbose(result sql.Result) {
|
||||
func (db *DB) printVerbose(result sql.Result) {
|
||||
lastInsertID, err := result.LastInsertId()
|
||||
if err == nil {
|
||||
fmt.Printf("Last insert ID: %d\n", lastInsertID)
|
||||
fmt.Fprintf(db.Log, "Last insert ID: %d\n", lastInsertID)
|
||||
}
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err == nil {
|
||||
fmt.Printf("Rows affected: %d\n", rowsAffected)
|
||||
fmt.Fprintf(db.Log, "Rows affected: %d\n", rowsAffected)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -485,7 +489,7 @@ func (db *DB) Rollback() error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Rolling back: %s\n", filename)
|
||||
fmt.Fprintf(db.Log, "Rolling back: %s\n", filename)
|
||||
|
||||
_, down, err := parseMigration(filepath.Join(db.MigrationsDir, filename))
|
||||
if err != nil {
|
||||
|
|
@ -498,7 +502,7 @@ func (db *DB) Rollback() error {
|
|||
if err != nil {
|
||||
return err
|
||||
} else if db.Verbose {
|
||||
printVerbose(result)
|
||||
db.printVerbose(result)
|
||||
}
|
||||
|
||||
// remove migration record
|
||||
|
|
@ -548,15 +552,15 @@ func (db *DB) Status(quiet bool) (int, error) {
|
|||
line = fmt.Sprintf("[ ] %s", res.Filename)
|
||||
}
|
||||
if !quiet {
|
||||
fmt.Println(line)
|
||||
fmt.Fprintln(db.Log, line)
|
||||
}
|
||||
}
|
||||
|
||||
totalPending := len(results) - totalApplied
|
||||
if !quiet {
|
||||
fmt.Println()
|
||||
fmt.Printf("Applied: %d\n", totalApplied)
|
||||
fmt.Printf("Pending: %d\n", totalPending)
|
||||
fmt.Fprintln(db.Log)
|
||||
fmt.Fprintf(db.Log, "Applied: %d\n", totalApplied)
|
||||
fmt.Fprintf(db.Log, "Pending: %d\n", totalPending)
|
||||
}
|
||||
|
||||
return totalPending, nil
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package dbmate
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
"github.com/amacneil/dbmate/pkg/dbutil"
|
||||
|
|
@ -25,6 +26,7 @@ type Driver interface {
|
|||
type DriverConfig struct {
|
||||
DatabaseURL *url.URL
|
||||
MigrationsTableName string
|
||||
Log io.Writer
|
||||
}
|
||||
|
||||
// DriverFunc represents a driver constructor
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"sort"
|
||||
|
|
@ -23,6 +24,7 @@ func init() {
|
|||
type Driver struct {
|
||||
migrationsTableName string
|
||||
databaseURL *url.URL
|
||||
log io.Writer
|
||||
}
|
||||
|
||||
// NewDriver initializes the driver
|
||||
|
|
@ -30,6 +32,7 @@ func NewDriver(config dbmate.DriverConfig) dbmate.Driver {
|
|||
return &Driver{
|
||||
migrationsTableName: config.MigrationsTableName,
|
||||
databaseURL: config.DatabaseURL,
|
||||
log: config.Log,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +111,7 @@ func (drv *Driver) quoteIdentifier(str string) string {
|
|||
// CreateDatabase creates the specified database
|
||||
func (drv *Driver) CreateDatabase() error {
|
||||
name := drv.databaseName()
|
||||
fmt.Printf("Creating: %s\n", name)
|
||||
fmt.Fprintf(drv.log, "Creating: %s\n", name)
|
||||
|
||||
db, err := drv.openClickHouseDB()
|
||||
if err != nil {
|
||||
|
|
@ -124,7 +127,7 @@ func (drv *Driver) CreateDatabase() error {
|
|||
// DropDatabase drops the specified database (if it exists)
|
||||
func (drv *Driver) DropDatabase() error {
|
||||
name := drv.databaseName()
|
||||
fmt.Printf("Dropping: %s\n", name)
|
||||
fmt.Fprintf(drv.log, "Dropping: %s\n", name)
|
||||
|
||||
db, err := drv.openClickHouseDB()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
|
|
@ -21,6 +22,7 @@ func init() {
|
|||
type Driver struct {
|
||||
migrationsTableName string
|
||||
databaseURL *url.URL
|
||||
log io.Writer
|
||||
}
|
||||
|
||||
// NewDriver initializes the driver
|
||||
|
|
@ -28,6 +30,7 @@ func NewDriver(config dbmate.DriverConfig) dbmate.Driver {
|
|||
return &Driver{
|
||||
migrationsTableName: config.MigrationsTableName,
|
||||
databaseURL: config.DatabaseURL,
|
||||
log: config.Log,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,7 +95,7 @@ func (drv *Driver) quoteIdentifier(str string) string {
|
|||
// CreateDatabase creates the specified database
|
||||
func (drv *Driver) CreateDatabase() error {
|
||||
name := dbutil.DatabaseName(drv.databaseURL)
|
||||
fmt.Printf("Creating: %s\n", name)
|
||||
fmt.Fprintf(drv.log, "Creating: %s\n", name)
|
||||
|
||||
db, err := drv.openRootDB()
|
||||
if err != nil {
|
||||
|
|
@ -109,7 +112,7 @@ func (drv *Driver) CreateDatabase() error {
|
|||
// DropDatabase drops the specified database (if it exists)
|
||||
func (drv *Driver) DropDatabase() error {
|
||||
name := dbutil.DatabaseName(drv.databaseURL)
|
||||
fmt.Printf("Dropping: %s\n", name)
|
||||
fmt.Fprintf(drv.log, "Dropping: %s\n", name)
|
||||
|
||||
db, err := drv.openRootDB()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
|
|
@ -22,6 +23,7 @@ func init() {
|
|||
type Driver struct {
|
||||
migrationsTableName string
|
||||
databaseURL *url.URL
|
||||
log io.Writer
|
||||
}
|
||||
|
||||
// NewDriver initializes the driver
|
||||
|
|
@ -29,6 +31,7 @@ func NewDriver(config dbmate.DriverConfig) dbmate.Driver {
|
|||
return &Driver{
|
||||
migrationsTableName: config.MigrationsTableName,
|
||||
databaseURL: config.DatabaseURL,
|
||||
log: config.Log,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +115,7 @@ func (drv *Driver) openPostgresDB() (*sql.DB, error) {
|
|||
// CreateDatabase creates the specified database
|
||||
func (drv *Driver) CreateDatabase() error {
|
||||
name := dbutil.DatabaseName(drv.databaseURL)
|
||||
fmt.Printf("Creating: %s\n", name)
|
||||
fmt.Fprintf(drv.log, "Creating: %s\n", name)
|
||||
|
||||
db, err := drv.openPostgresDB()
|
||||
if err != nil {
|
||||
|
|
@ -129,7 +132,7 @@ func (drv *Driver) CreateDatabase() error {
|
|||
// DropDatabase drops the specified database (if it exists)
|
||||
func (drv *Driver) DropDatabase() error {
|
||||
name := dbutil.DatabaseName(drv.databaseURL)
|
||||
fmt.Printf("Dropping: %s\n", name)
|
||||
fmt.Fprintf(drv.log, "Dropping: %s\n", name)
|
||||
|
||||
db, err := drv.openPostgresDB()
|
||||
if err != nil {
|
||||
|
|
@ -233,7 +236,7 @@ func (drv *Driver) CreateMigrationsTable(db *sql.DB) error {
|
|||
|
||||
// in theory we could attempt to create the schema every time, but we avoid that
|
||||
// in case the user doesn't have permissions to create schemas
|
||||
fmt.Printf("Creating schema: %s\n", schema)
|
||||
fmt.Fprintf(drv.log, "Creating schema: %s\n", schema)
|
||||
_, err = db.Exec(fmt.Sprintf("create schema if not exists %s", schema))
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
|
|
@ -27,6 +28,7 @@ func init() {
|
|||
type Driver struct {
|
||||
migrationsTableName string
|
||||
databaseURL *url.URL
|
||||
log io.Writer
|
||||
}
|
||||
|
||||
// NewDriver initializes the driver
|
||||
|
|
@ -34,6 +36,7 @@ func NewDriver(config dbmate.DriverConfig) dbmate.Driver {
|
|||
return &Driver{
|
||||
migrationsTableName: config.MigrationsTableName,
|
||||
databaseURL: config.DatabaseURL,
|
||||
log: config.Log,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +59,7 @@ func (drv *Driver) Open() (*sql.DB, error) {
|
|||
|
||||
// CreateDatabase creates the specified database
|
||||
func (drv *Driver) CreateDatabase() error {
|
||||
fmt.Printf("Creating: %s\n", ConnectionString(drv.databaseURL))
|
||||
fmt.Fprintf(drv.log, "Creating: %s\n", ConnectionString(drv.databaseURL))
|
||||
|
||||
db, err := drv.Open()
|
||||
if err != nil {
|
||||
|
|
@ -70,7 +73,7 @@ func (drv *Driver) CreateDatabase() error {
|
|||
// DropDatabase drops the specified database (if it exists)
|
||||
func (drv *Driver) DropDatabase() error {
|
||||
path := ConnectionString(drv.databaseURL)
|
||||
fmt.Printf("Dropping: %s\n", path)
|
||||
fmt.Fprintf(drv.log, "Dropping: %s\n", path)
|
||||
|
||||
exists, err := drv.DatabaseExists()
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue