github.com/duskeagle/pop@v4.10.1-0.20190417200916-92f2b794aab5+incompatible/migration_box.go (about)

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