github.com/seeker-insurance/kit@v0.0.13/cmd/migrate/migrate.go (about) 1 package migrate 2 3 import ( 4 "fmt" 5 "os" 6 7 migrate "github.com/rubenv/sql-migrate" 8 "github.com/seeker-insurance/kit/assets" 9 "github.com/seeker-insurance/kit/db/psql" 10 "github.com/seeker-insurance/kit/log" 11 "github.com/spf13/cobra" 12 ) 13 14 const migrationsDir = "data/bin/migrations" 15 16 var MigrateCmd = &cobra.Command{ 17 Use: "migrate", 18 Short: "Run migrations on the database", 19 Long: `Can be used to forward and rollback migrations.`, 20 Run: run, 21 } 22 23 var ( 24 down, files bool 25 max int 26 ) 27 28 func init() { 29 MigrateCmd.Flags().BoolVar(&down, "down", false, "rollback migrations") 30 MigrateCmd.Flags().IntVar(&max, "max", 0, "number of migrations to run, default will run all") 31 MigrateCmd.Flags().BoolVar(&files, "files", false, fmt.Sprintf("use files directly rather than bindata")) 32 } 33 34 func run(cmd *cobra.Command, args []string) { 35 if len(args) == 1 && args[0] == "config" { 36 log.Check(writeConfig()) 37 return 38 } 39 40 dir := direction() 41 n, err := migrate.ExecMax(psql.DB.DB(), "postgres", getMigrations(), dir, max) 42 if err != nil { 43 log.Fatalf("migrate.run: migrate.ExecMax: %v", err) 44 } 45 if down { 46 log.Infof("Rolled-back %d migrations.\n", n) 47 } else { 48 log.Infof("Applied %d migrations.\n", n) 49 } 50 } 51 52 func MigrateAll() (int, error) { 53 return migrate.Exec(psql.DB.DB(), "postgres", getMigrations(), migrate.Up) 54 } 55 56 func PendingMigrationCount() (int, error) { 57 plans, _, err := migrate.PlanMigration(psql.DB.DB(), "postgres", getMigrations(), migrate.Up, 0) 58 if err != nil { 59 return -1, err 60 } 61 return len(plans), nil 62 } 63 64 func direction() migrate.MigrationDirection { 65 if down { 66 if max == 0 { 67 max = 1 68 } 69 return migrate.Down 70 } 71 return migrate.Up 72 } 73 74 func migrationsDirExists() bool { 75 if _, err := os.Stat(migrationsDir); os.IsNotExist(err) { 76 return false 77 } 78 return true 79 } 80 81 func getMigrations() migrate.MigrationSource { 82 if files && migrationsDirExists() { 83 return &migrate.FileMigrationSource{Dir: migrationsDir} 84 } 85 return &migrate.AssetMigrationSource{ 86 Asset: assets.Manager.Get, 87 AssetDir: assets.Manager.Dir, 88 Dir: migrationsDir, 89 } 90 }