Skip to content

Commit

Permalink
Periodic output for long running migrations (#364)
Browse files Browse the repository at this point in the history
* Periodic output for long running migrations

* Periodic output for long running migrations with seconds
  • Loading branch information
nikitacrit authored Jun 15, 2022
1 parent 8d29bfc commit e7c5f69
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions migration_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package goose
import (
"database/sql"
"regexp"
"time"

"github.com/pkg/errors"
)
Expand All @@ -28,7 +29,7 @@ func runSQLMigration(db *sql.DB, statements []string, useTx bool, v int64, direc

for _, query := range statements {
verboseInfo("Executing statement: %s\n", clearStatement(query))
if _, err = tx.Exec(query); err != nil {
if err = execQuery(tx.Exec, query); err != nil {
verboseInfo("Rollback transaction")
tx.Rollback()
return errors.Wrapf(err, "failed to execute SQL query %q", clearStatement(query))
Expand All @@ -37,13 +38,13 @@ func runSQLMigration(db *sql.DB, statements []string, useTx bool, v int64, direc

if !noVersioning {
if direction {
if _, err := tx.Exec(GetDialect().insertVersionSQL(), v, direction); err != nil {
if err := execQuery(tx.Exec, GetDialect().insertVersionSQL(), v, direction); err != nil {
verboseInfo("Rollback transaction")
tx.Rollback()
return errors.Wrap(err, "failed to insert new goose version")
}
} else {
if _, err := tx.Exec(GetDialect().deleteVersionSQL(), v); err != nil {
if err := execQuery(tx.Exec, GetDialect().deleteVersionSQL(), v); err != nil {
verboseInfo("Rollback transaction")
tx.Rollback()
return errors.Wrap(err, "failed to delete goose version")
Expand All @@ -62,17 +63,17 @@ func runSQLMigration(db *sql.DB, statements []string, useTx bool, v int64, direc
// NO TRANSACTION.
for _, query := range statements {
verboseInfo("Executing statement: %s", clearStatement(query))
if _, err := db.Exec(query); err != nil {
if err := execQuery(db.Exec, query); err != nil {
return errors.Wrapf(err, "failed to execute SQL query %q", clearStatement(query))
}
}
if !noVersioning {
if direction {
if _, err := db.Exec(GetDialect().insertVersionSQL(), v, direction); err != nil {
if err := execQuery(db.Exec, GetDialect().insertVersionSQL(), v, direction); err != nil {
return errors.Wrap(err, "failed to insert new goose version")
}
} else {
if _, err := db.Exec(GetDialect().deleteVersionSQL(), v); err != nil {
if err := execQuery(db.Exec, GetDialect().deleteVersionSQL(), v); err != nil {
return errors.Wrap(err, "failed to delete goose version")
}
}
Expand All @@ -81,6 +82,31 @@ func runSQLMigration(db *sql.DB, statements []string, useTx bool, v int64, direc
return nil
}

func execQuery(fn func(string, ...interface{}) (sql.Result, error), query string, args ...interface{}) error {
if !verbose {
_, err := fn(query, args...)
return err
}

ch := make(chan error)

go func() {
_, err := fn(query, args...)
ch <- err
}()

t := time.Now()

for {
select {
case err := <-ch:
return err
case <-time.Tick(time.Minute):
verboseInfo("Executing statement still in progress for %v", time.Since(t).Round(time.Second))
}
}
}

const (
grayColor = "\033[90m"
resetColor = "\033[00m"
Expand Down

0 comments on commit e7c5f69

Please sign in to comment.