// Create creates new migration files on disk func Create(url, migrationsPath, name string) (*file.MigrationFile, error) { d, err := driver.New(url) if err != nil { return nil, err } files, err := file.ReadMigrationFiles(migrationsPath, file.FilenameRegex(d.FilenameExtension())) if err != nil { return nil, err } version := uint64(0) if len(files) > 0 { lastFile := files[len(files)-1] version = lastFile.Version } version += 1 versionStr := strconv.FormatUint(version, 10) length := 4 // TODO(mattes) check existing files and try to guess length if len(versionStr)%length != 0 { versionStr = strings.Repeat("0", length-len(versionStr)%length) + versionStr } filenamef := "%s_%s.%s.%s" name = strings.Replace(name, " ", "_", -1) mfile := &file.MigrationFile{ Version: version, UpFile: &file.File{ Path: migrationsPath, FileName: fmt.Sprintf(filenamef, versionStr, name, "up", d.FilenameExtension()), Name: name, Content: []byte(""), Direction: direction.Up, }, DownFile: &file.File{ Path: migrationsPath, FileName: fmt.Sprintf(filenamef, versionStr, name, "down", d.FilenameExtension()), Name: name, Content: []byte(""), Direction: direction.Down, }, } if err := ioutil.WriteFile(path.Join(mfile.UpFile.Path, mfile.UpFile.FileName), mfile.UpFile.Content, 0644); err != nil { return nil, err } if err := ioutil.WriteFile(path.Join(mfile.DownFile.Path, mfile.DownFile.FileName), mfile.DownFile.Content, 0644); err != nil { return nil, err } return mfile, nil }
// initDriverAndReadMigrationFilesAndGetVersion is a small helper // function that is common to most of the migration funcs func initDriverAndReadMigrationFilesAndGetVersion(url, migrationsPath string) (driver.Driver, *file.MigrationFiles, uint64, error) { d, err := driver.New(url) if err != nil { return nil, nil, 0, err } files, err := file.ReadMigrationFiles(migrationsPath, file.FilenameRegex(d.FilenameExtension())) if err != nil { d.Close() // TODO what happens with errors from this func? return nil, nil, 0, err } version, err := d.Version() if err != nil { d.Close() // TODO what happens with errors from this func? return nil, nil, 0, err } return d, &files, version, nil }
// initDriverAndReadMigrationFilesAndGetMigratedVersions is a small helper // function that is very similar to initDriverAndReadMigrationFilesAndGetVersion // except it gets ALL applied versions from the database func initDriverAndReadMigrationFilesAndGetMigratedVersions(url, migrationsPath string) (driver.Driver, *file.MigrationFiles, []uint64, error) { emptyVersions := make([]uint64, 0) d, err := driver.New(url) if err != nil { return nil, nil, emptyVersions, err } files, err := file.ReadMigrationFiles(migrationsPath, file.FilenameRegex(d.FilenameExtension())) if err != nil { d.Close() // TODO what happens with errors from this func? return nil, nil, emptyVersions, err } migratedVersions, err := d.MigratedVersions() if err != nil { d.Close() // TODO what happens with errors from this func? return nil, nil, emptyVersions, err } return d, &files, migratedVersions, nil }