diff --git a/cmd/goose/main.go b/cmd/goose/main.go index a247476..607ef70 100644 --- a/cmd/goose/main.go +++ b/cmd/goose/main.go @@ -10,8 +10,9 @@ import ( ) var ( - flags = flag.NewFlagSet("goose", flag.ExitOnError) - dir = flags.String("dir", ".", "directory with migration files") + flags = flag.NewFlagSet("goose", flag.ExitOnError) + dir = flags.String("dir", ".", "directory with migration files") + verbose = flags.Bool("v", false, "enable verbose mode") ) func main() { @@ -24,6 +25,10 @@ func main() { return } + if *verbose { + goose.SetVerbosity(goose.VerboseOn) + } + switch args[0] { case "create": if err := goose.Run("create", nil, *dir, args[1:]...); err != nil { diff --git a/goose.go b/goose.go index ff4b5e8..710ba80 100644 --- a/goose.go +++ b/goose.go @@ -3,17 +3,35 @@ package goose import ( "database/sql" "fmt" + "regexp" "strconv" "sync" ) +// VerboseLevel verbose level of the goose library +type VerboseLevel int + +const ( + // VerboseOff disable the log of the executed SQL statements + VerboseOff VerboseLevel = iota + 1 + // VerboseOn log the executed SQL statements + VerboseOn +) + var ( duplicateCheckOnce sync.Once minVersion = int64(0) maxVersion = int64((1 << 63) - 1) timestampFormat = "20060102150405" + verbose = VerboseOff + reMatchSQLComments = regexp.MustCompile(`(--.*)|(((\/\*)+?[\w\W]+?(\*\/)+))`) ) +// SetVerbosity defines the goose verbose level +func SetVerbosity(vl VerboseLevel) { + verbose = vl +} + // Run runs a goose command. func Run(command string, db *sql.DB, dir string, args ...string) error { switch command { diff --git a/migration_sql.go b/migration_sql.go index 0f4f48e..3702b0e 100644 --- a/migration_sql.go +++ b/migration_sql.go @@ -153,13 +153,17 @@ func runSQLMigration(db *sql.DB, scriptFile string, v int64, direction bool) err if useTx { // TRANSACTION. + printInfo("Begin transaction\n") + tx, err := db.Begin() if err != nil { log.Fatal(err) } for _, query := range statements { + printInfo("Executing statement : %s\n", cleanStatement(query)) if _, err = tx.Exec(query); err != nil { + printInfo("Rollback transaction\n") tx.Rollback() return err } @@ -167,21 +171,25 @@ func runSQLMigration(db *sql.DB, scriptFile string, v int64, direction bool) err if direction { if _, err := tx.Exec(GetDialect().insertVersionSQL(), v, direction); err != nil { + printInfo("Rollback transaction\n") tx.Rollback() return err } } else { if _, err := tx.Exec(GetDialect().deleteVersionSQL(), v); err != nil { + printInfo("Rollback transaction\n") tx.Rollback() return err } } + printInfo("Commit transaction\n") return tx.Commit() } // NO TRANSACTION. for _, query := range statements { + printInfo("Executing statement : %s\n", cleanStatement(query)) if _, err := db.Exec(query); err != nil { return err } @@ -192,3 +200,13 @@ func runSQLMigration(db *sql.DB, scriptFile string, v int64, direction bool) err return nil } + +func printInfo(s string, args ...interface{}) { + if verbose == VerboseOn { + log.Printf(s, args...) + } +} + +func cleanStatement(s string) string { + return reMatchSQLComments.ReplaceAllString(s, ``) +}