github.com/paweljw/pop/v5@v5.4.6/migration_box.go (about)

     1  package pop
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/gobuffalo/packd"
     7  	"github.com/gobuffalo/pop/v5/logging"
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  // MigrationBox is a wrapper around packr.Box and Migrator.
    12  // This will allow you to run migrations from a packed box
    13  // inside of a compiled binary.
    14  type MigrationBox struct {
    15  	Migrator
    16  	Box packd.Walkable
    17  }
    18  
    19  // NewMigrationBox from a packr.Box and a Connection.
    20  func NewMigrationBox(box packd.Walkable, c *Connection) (MigrationBox, error) {
    21  	fm := MigrationBox{
    22  		Migrator: NewMigrator(c),
    23  		Box:      box,
    24  	}
    25  
    26  	runner := func(f packd.File) func(mf Migration, tx *Connection) error {
    27  		return func(mf Migration, tx *Connection) error {
    28  			content, err := MigrationContent(mf, tx, f, true)
    29  			if err != nil {
    30  				return errors.Wrapf(err, "error processing %s", mf.Path)
    31  			}
    32  			if content == "" {
    33  				return nil
    34  			}
    35  			err = tx.RawQuery(content).Exec()
    36  			if err != nil {
    37  				return errors.Wrapf(err, "error executing %s, sql: %s", mf.Path, content)
    38  			}
    39  			return nil
    40  		}
    41  	}
    42  
    43  	err := fm.findMigrations(runner)
    44  	if err != nil {
    45  		return fm, err
    46  	}
    47  
    48  	return fm, nil
    49  }
    50  
    51  func (fm *MigrationBox) findMigrations(runner func(f packd.File) func(mf Migration, tx *Connection) error) error {
    52  	return fm.Box.Walk(func(p string, f packd.File) error {
    53  		info, err := f.FileInfo()
    54  		if err != nil {
    55  			return err
    56  		}
    57  		match, err := ParseMigrationFilename(info.Name())
    58  		if err != nil {
    59  			if strings.HasPrefix(err.Error(), "unsupported dialect") {
    60  				log(logging.Warn, "ignoring migration file with %s", err.Error())
    61  				return nil
    62  			}
    63  			return err
    64  		}
    65  		if match == nil {
    66  			log(logging.Warn, "ignoring file %s because it does not match the migration file pattern", info.Name())
    67  			return nil
    68  		}
    69  		mf := Migration{
    70  			Path:      p,
    71  			Version:   match.Version,
    72  			Name:      match.Name,
    73  			DBType:    match.DBType,
    74  			Direction: match.Direction,
    75  			Type:      match.Type,
    76  			Runner:    runner(f),
    77  		}
    78  		fm.Migrations[mf.Direction] = append(fm.Migrations[mf.Direction], mf)
    79  		return nil
    80  	})
    81  }