diff --git a/cmd/goose/cmd_down.go b/cmd/goose/cmd_down.go index 91c55a6..87099a5 100644 --- a/cmd/goose/cmd_down.go +++ b/cmd/goose/cmd_down.go @@ -2,7 +2,6 @@ package main import ( "bitbucket.org/liamstask/goose/lib/goose" - "fmt" "log" ) @@ -25,17 +24,9 @@ func downRun(cmd *Command, args ...string) { log.Fatal(err) } - if current == 0 { - fmt.Println("db is empty, can't go down.") - return - } - - previous, earliest := goose.GetPreviousDBVersion(conf.MigrationsDir, current) - - // if we're at the earliest version, indicate that the - // only available step is to roll back to an empty database - if current == earliest { - previous = 0 + previous, err := goose.GetPreviousDBVersion(conf.MigrationsDir, current) + if err != nil { + log.Fatal(err) } goose.RunMigrations(conf, conf.MigrationsDir, previous) diff --git a/cmd/goose/cmd_redo.go b/cmd/goose/cmd_redo.go index 93a4836..ecac847 100644 --- a/cmd/goose/cmd_redo.go +++ b/cmd/goose/cmd_redo.go @@ -18,19 +18,18 @@ func redoRun(cmd *Command, args ...string) { log.Fatal(err) } - target, err := goose.GetDBVersion(conf) + current, err := goose.GetDBVersion(conf) if err != nil { log.Fatal(err) } - _, earliest := goose.GetPreviousDBVersion(conf.MigrationsDir, target) - - downRun(cmd, args...) - if target == 0 { - log.Printf("Updating from %s to %s\n", target, earliest) - target = earliest + previous, err := goose.GetPreviousDBVersion(conf.MigrationsDir, current) + if err != nil { + log.Fatal(err) } - goose.RunMigrations(conf, conf.MigrationsDir, target) + + goose.RunMigrations(conf, conf.MigrationsDir, previous) + goose.RunMigrations(conf, conf.MigrationsDir, current) } func init() { diff --git a/lib/goose/migrate.go b/lib/goose/migrate.go index 08add2c..925acfb 100644 --- a/lib/goose/migrate.go +++ b/lib/goose/migrate.go @@ -15,7 +15,10 @@ import ( "time" ) -var ErrTableDoesNotExist = errors.New("table does not exist") +var ( + ErrTableDoesNotExist = errors.New("table does not exist") + ErrNoPreviousVersion = errors.New("no previous version found") +) type MigrationRecord struct { VersionId int64 @@ -282,20 +285,20 @@ func GetDBVersion(conf *DBConf) (version int64, err error) { return version, nil } -func GetPreviousDBVersion(dirpath string, version int64) (previous, earliest int64) { +func GetPreviousDBVersion(dirpath string, version int64) (previous int64, err error) { previous = -1 - earliest = (1 << 63) - 1 + sawGivenVersion := false - filepath.Walk(dirpath, func(name string, info os.FileInfo, err error) error { + filepath.Walk(dirpath, func(name string, info os.FileInfo, walkerr error) error { if !info.IsDir() { if v, e := NumericComponent(name); e == nil { if v > previous && v < version { previous = v } - if v < earliest { - earliest = v + if v == version { + sawGivenVersion = true } } } @@ -303,7 +306,18 @@ func GetPreviousDBVersion(dirpath string, version int64) (previous, earliest int return nil }) - return previous, earliest + if previous == -1 { + if sawGivenVersion { + // the given version is (likely) valid but we didn't find + // anything before it. + // 'previous' must reflect that no migrations have been applied. + previous = 0 + } else { + err = ErrNoPreviousVersion + } + } + + return } // helper to identify the most recent possible version