go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/db/migration/action.go (about)

     1  /*
     2  
     3  Copyright (c) 2023 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package migration
     9  
    10  import (
    11  	"context"
    12  	"database/sql"
    13  
    14  	"go.charczuk.com/sdk/db"
    15  )
    16  
    17  // Action is a type that represents a migration action.
    18  type Action interface {
    19  	Action(context.Context, *db.Connection, *sql.Tx) error
    20  }
    21  
    22  // ActionFunc is a function that can be run during a migration step.
    23  type ActionFunc func(context.Context, *db.Connection, *sql.Tx) error
    24  
    25  // Action implements actioner.
    26  func (a ActionFunc) Action(ctx context.Context, conn *db.Connection, tx *sql.Tx) error {
    27  	return a(ctx, conn, tx)
    28  }
    29  
    30  // NoOp performs no action.
    31  func NoOp(_ context.Context, _ *db.Connection, _ *sql.Tx) error { return nil }
    32  
    33  // StatementSlice is an array of strings.
    34  type StatementSlice []string
    35  
    36  // Action implements Action.
    37  func (s StatementSlice) Action(ctx context.Context, c *db.Connection, tx *sql.Tx) (err error) {
    38  	for _, statement := range s {
    39  		_, err = c.Invoke(db.OptContext(ctx), db.OptTx(tx)).Exec(statement)
    40  		if err != nil {
    41  			return
    42  		}
    43  	}
    44  	return
    45  }
    46  
    47  // Statements returns a body func that executes the statments serially.
    48  func Statements(statements ...string) Action {
    49  	return StatementSlice(statements)
    50  }
    51  
    52  // Exec creates an Action that will run a statement with a given set of arguments.
    53  // It can be used in lieu of Statements, when parameterization is needed
    54  func Exec(statement string, args ...interface{}) Action {
    55  	return ActionFunc(func(ctx context.Context, c *db.Connection, tx *sql.Tx) (err error) {
    56  		_, err = c.Invoke(db.OptContext(ctx), db.OptTx(tx)).Exec(statement, args...)
    57  		return
    58  	})
    59  }
    60  
    61  // Actions creates an Action with a single body func that executes all the variadic argument actions serially
    62  func Actions(actions ...Action) Action {
    63  	return ActionFunc(func(ctx context.Context, c *db.Connection, tx *sql.Tx) (err error) {
    64  		for _, action := range actions {
    65  			err = action.Action(ctx, c, tx)
    66  			if err != nil {
    67  				return err
    68  			}
    69  		}
    70  		return
    71  	})
    72  }