Support for migrating up/down to a specific version

pull/20/head
Piotr Kozłowski 2017-03-17 14:44:22 +01:00
parent e591daea14
commit da36030846
4 changed files with 80 additions and 2 deletions

39
down.go
View File

@ -23,3 +23,42 @@ func Down(db *sql.DB, dir string) error {
return current.Down(db)
}
func DownTo(db *sql.DB, dir string, version int64) error {
migrations, err := collectMigrations(dir, minVersion, maxVersion)
if err != nil {
return err
}
for {
currentVersion, err := GetDBVersion(db)
if err != nil {
return err
}
prev, err := migrations.Previous(currentVersion)
if err != nil {
if err == ErrNoNextVersion {
fmt.Printf("goose: no migrations to run. current version: %d\n", currentVersion)
return nil
}
return err
}
if prev.Version < version {
fmt.Printf("goose: no migrations to run. current version: %d\n", currentVersion)
return nil
}
current, err := migrations.Current(currentVersion)
if err != nil {
return fmt.Errorf("no migration %v", currentVersion)
}
if err = current.Down(db); err != nil {
return err
}
}
return nil
}

View File

@ -4,6 +4,7 @@ import (
"database/sql"
"fmt"
"sync"
"strconv"
)
var (
@ -22,6 +23,18 @@ func Run(command string, db *sql.DB, dir string, args ...string) error {
if err := UpByOne(db, dir); err != nil {
return err
}
case "up-to":
if len(args) == 0 {
return fmt.Errorf("up-to must be of form: goose [OPTIONS] DRIVER DBSTRING up-to VERSION")
}
version, err := strconv.ParseInt(args[0], 10, 64)
if err != nil {
return fmt.Errorf("version must be a number (got '%s')", args[0])
}
if err := UpTo(db, dir, version); err != nil {
return err
}
case "create":
if len(args) == 0 {
return fmt.Errorf("create must be of form: goose [OPTIONS] DRIVER DBSTRING create NAME [go|sql]")
@ -38,6 +51,18 @@ func Run(command string, db *sql.DB, dir string, args ...string) error {
if err := Down(db, dir); err != nil {
return err
}
case "down-to":
if len(args) == 0 {
return fmt.Errorf("down-to must be of form: goose [OPTIONS] DRIVER DBSTRING down-to VERSION")
}
version, err := strconv.ParseInt(args[0], 10, 64)
if err != nil {
return fmt.Errorf("version must be a number (got '%s')", args[0])
}
if err := DownTo(db, dir, version); err != nil {
return err
}
case "redo":
if err := Redo(db, dir); err != nil {
return err

View File

@ -51,6 +51,16 @@ func (ms Migrations) Next(current int64) (*Migration, error) {
return nil, ErrNoNextVersion
}
func (ms Migrations) Previous(current int64) (*Migration, error) {
for i := len(ms)-1; i >= 0; i-- {
if ms[i].Version < current {
return ms[i], nil
}
}
return nil, ErrNoNextVersion
}
func (ms Migrations) Last() (*Migration, error) {
if len(ms) == 0 {
return nil, ErrNoNextVersion

8
up.go
View File

@ -5,8 +5,8 @@ import (
"fmt"
)
func Up(db *sql.DB, dir string) error {
migrations, err := collectMigrations(dir, minVersion, maxVersion)
func UpTo(db *sql.DB, dir string, version int64) error {
migrations, err := collectMigrations(dir, minVersion, version)
if err != nil {
return err
}
@ -34,6 +34,10 @@ func Up(db *sql.DB, dir string) error {
return nil
}
func Up(db *sql.DB, dir string) error {
return UpTo(db, dir, maxVersion)
}
func UpByOne(db *sql.DB, dir string) error {
migrations, err := collectMigrations(dir, minVersion, maxVersion)
if err != nil {