@@ -55,19 +55,61 @@ func (e ErrDirty) Error() string {
5555 return fmt .Sprintf ("Dirty database version %v. Fix and force version." , e .Version )
5656}
5757
58+ // PostStepCallback is a callback function type that can be used to execute a
59+ // Golang based migration step after a SQL based migration step has been
60+ // executed. The callback function receives the migration and the database
61+ // driver as arguments.
62+ type PostStepCallback func (migr * Migration , driver database.Driver ) error
63+
5864// options is a set of optional options that can be set when a Migrate instance
5965// is created.
6066type options struct {
67+ // postStepCallbacks is a map of PostStepCallback functions that can be
68+ // used to execute a Golang based migration step after a SQL based
69+ // migration step has been executed. The key is the migration version
70+ // and the value is the callback function that should be run _after_ the
71+ // step was executed (but within the same database transaction).
72+ postStepCallbacks map [uint ]PostStepCallback
6173}
6274
6375// defaultOptions returns a new options struct with default values.
6476func defaultOptions () options {
65- return options {}
77+ return options {
78+ postStepCallbacks : make (map [uint ]PostStepCallback ),
79+ }
6680}
6781
6882// Option is a function that can be used to set options on a Migrate instance.
6983type Option func (* options )
7084
85+ // WithPostStepCallbacks is an option that can be used to set a map of
86+ // PostStepCallback functions that can be used to execute a Golang based
87+ // migration step after a SQL based migration step has been executed. The key is
88+ // the migration version and the value is the callback function that should be
89+ // run _after_ the step was executed (but before the version is marked as
90+ // cleanly executed). An error returned from the callback will cause the
91+ // migration to fail and the step to be marked as dirty.
92+ func WithPostStepCallbacks (
93+ postStepCallbacks map [uint ]PostStepCallback ) Option {
94+
95+ return func (o * options ) {
96+ o .postStepCallbacks = postStepCallbacks
97+ }
98+ }
99+
100+ // WithPostStepCallback is an option that can be used to set a PostStepCallback
101+ // function that can be used to execute a Golang based migration step after the
102+ // SQL based migration step with the given version number has been executed. The
103+ // callback is the function that should be run _after_ the step was executed
104+ // (but before the version is marked as cleanly executed). An error returned
105+ // from the callback will cause the migration to fail and the step to be marked
106+ // as dirty.
107+ func WithPostStepCallback (version uint , callback PostStepCallback ) Option {
108+ return func (o * options ) {
109+ o .postStepCallbacks [version ] = callback
110+ }
111+ }
112+
71113type Migrate struct {
72114 sourceName string
73115 sourceDrv source.Driver
@@ -775,6 +817,25 @@ func (m *Migrate) runMigrations(ret <-chan interface{}) error {
775817 if err := m .databaseDrv .Run (migr .BufferedBody ); err != nil {
776818 return err
777819 }
820+
821+ // If there is a post execution function for
822+ // this migration, run it now.
823+ cb , ok := m .opts .postStepCallbacks [migr .Version ]
824+ if ok {
825+ m .logVerbosePrintf ("Running post step " +
826+ "callback for %v\n " , migr .LogString ())
827+
828+ err := cb (migr , m .databaseDrv )
829+ if err != nil {
830+ return fmt .Errorf ("failed to " +
831+ "execute post " +
832+ "step callback: %w" ,
833+ err )
834+ }
835+
836+ m .logVerbosePrintf ("Post step callback " +
837+ "finished for %v\n " , migr .LogString ())
838+ }
778839 }
779840
780841 // set clean state
0 commit comments