Skip to content

Commit

Permalink
Migrations pre/post hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
josephbuchma committed Dec 28, 2017
1 parent fc11bd2 commit e33fb3c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 15 deletions.
3 changes: 1 addition & 2 deletions file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,9 @@ func ReadMigrationFiles(path string, filenameRegex *regexp.Regexp) (files Migrat
filename string
d direction.Direction
}
tmpFiles := make([]*tmpFile, 0)
var tmpFiles []*tmpFile
tmpFileMap := map[Version]map[direction.Direction]tmpFile{}
for _, file := range ioFiles {

version, name, d, err := parseFilenameSchema(file.Name(), filenameRegex)
if err == nil {
if _, ok := tmpFileMap[version]; !ok {
Expand Down
60 changes: 56 additions & 4 deletions migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package migrate

import (
"context"
"errors"
"fmt"
"io/ioutil"
"path"
Expand All @@ -14,21 +15,53 @@ import (
"github.com/db-journey/migrate/file"
)

// Option for New
type Option func(h *Handle) error

// WithHooks allows to add pre/post migration hooks.
func WithHooks(pre, post func(f file.File) error) Option {
return func(h *Handle) error {
h.preHook = pre
h.postHook = post
return nil
}
}

// Handle encapsulates migrations functionality
type Handle struct {
drv driver.Driver
migrationsPath string
locked bool
fatalErr error

preHook, postHook func(f file.File) error
}

// New Handle instance
func New(url, migrationsPath string) (*Handle, error) {
// Open migrations Handle
func Open(url, migrationsPath string, opts ...Option) (*Handle, error) {
d, err := driver.New(url)
if err != nil {
return nil, err
}
return &Handle{drv: d, migrationsPath: migrationsPath}, nil
return New(d, migrationsPath, opts...)
}

// New migrations Handle
func New(drv driver.Driver, migrationsPath string, opts ...Option) (*Handle, error) {
if drv == nil {
return nil, errors.New("driver can't be nil")
}
h := &Handle{
drv: drv,
migrationsPath: migrationsPath,
}
for _, configure := range opts {
err := configure(h)
if err != nil {
return nil, err
}
}
return h, nil
}

// Up applies all available migrations.
Expand Down Expand Up @@ -262,7 +295,15 @@ func (m *Handle) drvMigrate(ctx context.Context, f file.File) error {
case <-ctx.Done():
return fmt.Errorf("interrupted before applying version %d: %s", f.Version, ctx.Err())
default:
return m.drv.Migrate(f)
err := runHookIfNotNil(m.preHook, "pre", f)
if err != nil {
return err
}
err = m.drv.Migrate(f)
if err != nil {
return err
}
return runHookIfNotNil(m.postHook, "post", f)
}
}

Expand All @@ -276,3 +317,14 @@ func (m *Handle) readMigrationFilesAndGetVersions() (file.MigrationFiles, file.V
versions, err := m.drv.Versions()
return files, versions, err
}

func runHookIfNotNil(hook func(f file.File) error, name string, f file.File) error {
if hook == nil {
return nil
}
err := hook(f)
if err != nil {
return fmt.Errorf("%s-hook for migration %q failed: %s", name, f.FileName, err)
}
return nil
}
18 changes: 9 additions & 9 deletions shortcuts.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
// Up applies all available migrations.
// Up is a shortcut for Handle.Up
func Up(url, migrationsPath string) error {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return err
}
Expand All @@ -26,7 +26,7 @@ func Up(url, migrationsPath string) error {
// Down rolls back all migrations.
// Down is a shortcut for Handle.Down
func Down(url, migrationsPath string) error {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return err
}
Expand All @@ -37,7 +37,7 @@ func Down(url, migrationsPath string) error {
// Redo rolls back the most recently applied migration, then runs it again.
// Redo is a shortcut for Handle.Redo
func Redo(url, migrationsPath string) error {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return err
}
Expand All @@ -48,7 +48,7 @@ func Redo(url, migrationsPath string) error {
// Reset runs the down and up migration function.
// Reset is a shortcut for Handle.Reset
func Reset(url, migrationsPath string) error {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return err
}
Expand All @@ -59,7 +59,7 @@ func Reset(url, migrationsPath string) error {
// Migrate applies relative +n/-n migrations.
// Migrate is a shortcut for Handle.Migrate
func Migrate(url, migrationsPath string, relativeN int) error {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return err
}
Expand All @@ -70,7 +70,7 @@ func Migrate(url, migrationsPath string, relativeN int) error {
// Version returns the current migration version.
// Version is a shortcut for Handle.Version
func Version(url, migrationsPath string) (file.Version, error) {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return 0, err
}
Expand All @@ -81,7 +81,7 @@ func Version(url, migrationsPath string) (file.Version, error) {
// Versions returns applied versions.
// Versions is a shortcut for Handle.Versions
func Versions(url, migrationsPath string) (file.Versions, error) {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return nil, err
}
Expand All @@ -92,7 +92,7 @@ func Versions(url, migrationsPath string) (file.Versions, error) {
// PendingMigrations returns list of pending migration files
// PendingMigrations is a shortcut for Handle.PendingMigrations
func PendingMigrations(url, migrationsPath string) (file.Files, error) {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return nil, err
}
Expand All @@ -103,7 +103,7 @@ func PendingMigrations(url, migrationsPath string) (file.Files, error) {
// Create applies relative +n/-n migrations.
// Create is a shortcut for Handle.Create
func Create(url, migrationsPath, name string) (*file.MigrationFile, error) {
m, err := New(url, migrationsPath)
m, err := Open(url, migrationsPath)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit e33fb3c

Please sign in to comment.