// Make sure the database at the URL is up to date with respect to // migrations, or return an error. The migration scripts are taken // from `basedir/{scheme}`, with the scheme coming from the URL. func Migrate(dburl, basedir string) (uint64, error) { u, err := url.Parse(dburl) if err != nil { return 0, errors.Wrap(err, "parsing database URL") } migrationsPath := filepath.Join(basedir, DriverForScheme(u.Scheme)) if _, err := os.Stat(migrationsPath); err != nil { if os.IsNotExist(err) { return 0, errors.Wrapf(err, "migrations dir %s does not exist; driver %s not supported", migrationsPath, u.Scheme) } return 0, errors.Wrapf(err, "verifying migrations directory %s exists", migrationsPath) } errs, _ := migrate.UpSync(dburl, migrationsPath) if len(errs) > 0 { return 0, errors.Wrap(compositeError{errs}, "migrating database") } version, err := migrate.Version(dburl, migrationsPath) if err != nil { return 0, err } return version, nil }
func main() { flag.Usage = func() { helpCmd() } flag.Parse() command := flag.Arg(0) if *version { fmt.Println(Version) os.Exit(0) } if *migrationsPath == "" { *migrationsPath, _ = os.Getwd() } switch command { case "create": verifyMigrationsPath(*migrationsPath) name := flag.Arg(1) if name == "" { fmt.Println("Please specify name.") os.Exit(1) } migrationFile, err := migrate.Create(*url, *migrationsPath, name) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Printf("Version %v migration files created in %v:\n", migrationFile.Version, *migrationsPath) fmt.Println(migrationFile.UpFile.FileName) fmt.Println(migrationFile.DownFile.FileName) case "migrate": verifyMigrationsPath(*migrationsPath) relativeN := flag.Arg(1) relativeNInt, err := strconv.Atoi(relativeN) if err != nil { fmt.Println("Unable to parse param <n>.") os.Exit(1) } timerStart = time.Now() pipe := pipep.New() go migrate.Migrate(pipe, *url, *migrationsPath, relativeNInt) ok := writePipe(pipe) printTimer() if !ok { os.Exit(1) } case "goto": verifyMigrationsPath(*migrationsPath) toVersion := flag.Arg(1) toVersionInt, err := strconv.Atoi(toVersion) if err != nil || toVersionInt < 0 { fmt.Println("Unable to parse param <v>.") os.Exit(1) } currentVersion, err := migrate.Version(*url, *migrationsPath) if err != nil { fmt.Println(err) os.Exit(1) } relativeNInt := toVersionInt - int(currentVersion) timerStart = time.Now() pipe := pipep.New() go migrate.Migrate(pipe, *url, *migrationsPath, relativeNInt) ok := writePipe(pipe) printTimer() if !ok { os.Exit(1) } case "up": verifyMigrationsPath(*migrationsPath) timerStart = time.Now() pipe := pipep.New() go migrate.Up(pipe, *url, *migrationsPath) ok := writePipe(pipe) printTimer() if !ok { os.Exit(1) } case "down": verifyMigrationsPath(*migrationsPath) timerStart = time.Now() pipe := pipep.New() go migrate.Down(pipe, *url, *migrationsPath) ok := writePipe(pipe) printTimer() if !ok { os.Exit(1) } case "redo": verifyMigrationsPath(*migrationsPath) timerStart = time.Now() pipe := pipep.New() go migrate.Redo(pipe, *url, *migrationsPath) ok := writePipe(pipe) printTimer() if !ok { os.Exit(1) } case "reset": verifyMigrationsPath(*migrationsPath) timerStart = time.Now() pipe := pipep.New() go migrate.Reset(pipe, *url, *migrationsPath) ok := writePipe(pipe) printTimer() if !ok { os.Exit(1) } case "version": verifyMigrationsPath(*migrationsPath) version, err := migrate.Version(*url, *migrationsPath) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Println(version) default: fallthrough case "help": helpCmd() } }
func CheckPatch() uint64 { patch, _ := migrate.Version("sqlite3://"+option.String("dbpath"), "migrations") return patch }