redo.go

 1package goose
 2
 3import (
 4	"context"
 5	"database/sql"
 6)
 7
 8// Redo rolls back the most recently applied migration, then runs it again.
 9func Redo(db *sql.DB, dir string, opts ...OptionsFunc) error {
10	ctx := context.Background()
11	return RedoContext(ctx, db, dir, opts...)
12}
13
14// RedoContext rolls back the most recently applied migration, then runs it again.
15func RedoContext(ctx context.Context, db *sql.DB, dir string, opts ...OptionsFunc) error {
16	option := &options{}
17	for _, f := range opts {
18		f(option)
19	}
20	migrations, err := CollectMigrations(dir, minVersion, maxVersion)
21	if err != nil {
22		return err
23	}
24	var (
25		currentVersion int64
26	)
27	if option.noVersioning {
28		if len(migrations) == 0 {
29			return nil
30		}
31		currentVersion = migrations[len(migrations)-1].Version
32	} else {
33		if currentVersion, err = GetDBVersionContext(ctx, db); err != nil {
34			return err
35		}
36	}
37
38	current, err := migrations.Current(currentVersion)
39	if err != nil {
40		return err
41	}
42	current.noVersioning = option.noVersioning
43
44	if err := current.DownContext(ctx, db); err != nil {
45		return err
46	}
47	if err := current.UpContext(ctx, db); err != nil {
48		return err
49	}
50	return nil
51}