github.com/solongordon/pop@v4.10.0+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 }