Skip to content

Commit

Permalink
Reset & refresh commands
Browse files Browse the repository at this point in the history
Reset rolls back all migrations
Refresh rolls back all migrations and applies all available migrations again
it's useful for development to put db in latest state without full
recreation of db.
  • Loading branch information
smacker committed Jul 2, 2017
1 parent a0e07f5 commit 0bf6bef
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cmd/goose/main.go
Expand Up @@ -116,6 +116,8 @@ Commands:
down Roll back the version by 1
down-to VERSION Roll back to a specific VERSION
redo Re-run the latest migration
reset Roll back all migrations
refresh Roll back all migrations and apply all available migrations again
status Dump the migration status for the current DB
version Print the current version of the database
create NAME [sql|go] Creates new migration file with next version
Expand Down
11 changes: 11 additions & 0 deletions goose.go
Expand Up @@ -68,6 +68,17 @@ func Run(command string, db *sql.DB, dir string, args ...string) error {
if err := Redo(db, dir); err != nil {
return err
}
case "reset":
if err := Reset(db, dir); err != nil {
return err
}
case "refresh":
if err := Reset(db, dir); err != nil {
return err
}
if err := Up(db, dir); err != nil {
return err
}
case "status":
if err := Status(db, dir); err != nil {
return err
Expand Down
59 changes: 59 additions & 0 deletions reset.go
@@ -0,0 +1,59 @@
package goose

import (
"database/sql"
"log"
"sort"
)

// Reset rolls back all migrations
func Reset(db *sql.DB, dir string) error {
migrations, err := CollectMigrations(dir, minVersion, maxVersion)
if err != nil {
return err
}
statuses, err := dbMigrationsStatus(db)
if err != nil {
return err
}
sort.Sort(sort.Reverse(migrations))

for _, migration := range migrations {
if !statuses[migration.Version] {
continue
}
if err = migration.Down(db); err != nil {
return err
}
}

return nil
}

func dbMigrationsStatus(db *sql.DB) (map[int64]bool, error) {
rows, err := GetDialect().dbVersionQuery(db)
if err != nil {
return map[int64]bool{}, createVersionTable(db)
}
defer rows.Close()

// The most recent record for each migration specifies
// whether it has been applied or rolled back.

result := make(map[int64]bool)

for rows.Next() {
var row MigrationRecord
if err = rows.Scan(&row.VersionID, &row.IsApplied); err != nil {
log.Fatal("error scanning rows:", err)
}

if _, ok := result[row.VersionID]; ok {
continue
}

result[row.VersionID] = row.IsApplied
}

return result, nil
}

0 comments on commit 0bf6bef

Please sign in to comment.