github.com/gogriddy/goose@v0.0.0-20180817174216-2c751e0981c8/lib/goose/migration_go.go (about) 1 package goose 2 3 import ( 4 "bytes" 5 "encoding/gob" 6 "fmt" 7 "io/ioutil" 8 "log" 9 "os" 10 "os/exec" 11 "path/filepath" 12 "strings" 13 ) 14 15 type templateData struct { 16 Version int64 17 Import string 18 Conf string // gob encoded DBConf 19 Direction Direction 20 Func string 21 InsertStmt string 22 } 23 24 func init() { 25 gob.Register(PostgresDialect{}) 26 gob.Register(MySqlDialect{}) 27 gob.Register(Sqlite3Dialect{}) 28 } 29 30 // 31 // Run a .go migration. 32 // 33 // In order to do this, we copy a modified version of the 34 // original .go migration, and execute it via `go run` along 35 // with a main() of our own creation. 36 // 37 func runGoMigration(conf *DBConf, path string, version int64, direction Direction) error { 38 // everything gets written to a temp dir, and zapped afterwards 39 d, e := ioutil.TempDir("", "goose") 40 if e != nil { 41 log.Fatal(e) 42 } 43 defer os.RemoveAll(d) 44 45 var bb bytes.Buffer 46 if err := gob.NewEncoder(&bb).Encode(conf); err != nil { 47 return err 48 } 49 50 // XXX: there must be a better way of making this byte array 51 // available to the generated code... 52 // but for now, print an array literal of the gob bytes 53 var sb bytes.Buffer 54 sb.WriteString("[]byte{ ") 55 for _, b := range bb.Bytes() { 56 sb.WriteString(fmt.Sprintf("0x%02x, ", b)) 57 } 58 sb.WriteString("}") 59 60 td := &templateData{ 61 Version: version, 62 Import: conf.Driver.Import, 63 Conf: sb.String(), 64 Direction: direction, 65 Func: fmt.Sprintf("%v_%v", strings.ToTitle(direction.String()), version), 66 InsertStmt: conf.Driver.Dialect.insertVersionSql(), 67 } 68 69 main, e := writeTemplateToFile(filepath.Join(d, "goose_main.go"), goMigrationDriverTemplate, td) 70 if e != nil { 71 log.Fatal(e) 72 } 73 74 outpath := filepath.Join(d, filepath.Base(path)) 75 if _, e = copyFile(outpath, path); e != nil { 76 log.Fatal(e) 77 } 78 79 cmd := exec.Command("go", "run", main, outpath) 80 cmd.Stdout = os.Stdout 81 cmd.Stderr = os.Stderr 82 if e = cmd.Run(); e != nil { 83 log.Fatal("`go run` failed: ", e) 84 } 85 86 return nil 87 }