package migratecmd import ( "database/sql" "fmt" "strconv" "gitea.auvem.com/go-toolkit/migrate" "github.com/pressly/goose/v3" "github.com/spf13/cobra" ) // MigrateCmd returns the main migrate command. func MigrateCmd(sqlo *sql.DB) *cobra.Command { cmd := &cobra.Command{ Use: "migrate", Short: "Migrate the database", Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, } cmd.AddCommand(AllSubcommands(sqlo)...) return cmd } // AllSubcommands returns all subcommands of the migrate command. func AllSubcommands(sqlo *sql.DB) []*cobra.Command { return []*cobra.Command{ MigrateStatusCmd(sqlo), MigrateCreateCmd(sqlo), MigrateUpCmd(sqlo), MigrateUpToCmd(sqlo), MigrateDownCmd(sqlo), MigrateDownToCmd(sqlo), MigrateRedoCmd(sqlo), } } // MigrateStatusCmd returns a command to get database migration status. func MigrateStatusCmd(sqlo *sql.DB) *cobra.Command { return &cobra.Command{ Use: "status", Short: "Get database migration status", Run: func(cmd *cobra.Command, args []string) { if err := goose.Status(sqlo, migrate.MigrationsConfig().BasePath); err != nil { fmt.Printf("Error: Couldn't get migration status: %v\n", err) return } }, } } // MigrateCreateCmd returns a command to create a new migration. func MigrateCreateCmd(sqlo *sql.DB) *cobra.Command { cmd := &cobra.Command{ Use: "create [NAME] [TYPE]", Short: "Create a new migration", Args: cobra.ExactArgs(2), Run: func(cmd *cobra.Command, args []string) { sequential, err := cmd.Flags().GetBool("sequential") if err != nil { fmt.Printf("Error: Failed to get 'sequential' flag: %v\n", err) return } if sequential { goose.SetSequential(sequential) } if err := goose.Create(sqlo, "migrations", args[0], args[1]); err != nil { fmt.Printf("Error: Couldn't create migration: %v\n", err) return } }, } cmd.Flags().BoolP("sequential", "s", false, "Create a sequential migration") return cmd } // MigrateUpCmd returns a command to apply all available database migrations. func MigrateUpCmd(sqlo *sql.DB) *cobra.Command { return &cobra.Command{ Use: "up", Short: "Apply all available database migrations", Run: func(cmd *cobra.Command, args []string) { if err := goose.Up(sqlo, migrate.MigrationsConfig().BasePath); err != nil { fmt.Printf("Error: Couldn't apply migrations: %v\n", err) return } }, } } // MigrateUpToCmd returns a command to apply all available database migrations up to a specific version. func MigrateUpToCmd(sqlo *sql.DB) *cobra.Command { return &cobra.Command{ Use: "up-to [VERSION]", Short: "Apply all available database migrations up to a specific version", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { version, err := strconv.ParseInt(args[0], 10, 0) if err != nil { fmt.Printf("Error: Couldn't parse version: %v\n", err) return } if err := goose.UpTo(sqlo, migrate.MigrationsConfig().BasePath, version); err != nil { fmt.Printf("Error: Couldn't apply migrations to target version %d: %v\n", version, err) return } }, } } // MigrateDownCmd returns a command to rollback the most recent database migration. func MigrateDownCmd(sqlo *sql.DB) *cobra.Command { return &cobra.Command{ Use: "down", Short: "Rollback the most recent database migration", Run: func(cmd *cobra.Command, args []string) { if err := goose.Down(sqlo, migrate.MigrationsConfig().BasePath); err != nil { fmt.Printf("Error: Couldn't rollback migration: %v\n", err) return } }, } } // MigrateDownToCmd returns a command to rollback all database migrations down to a specific version. func MigrateDownToCmd(sqlo *sql.DB) *cobra.Command { return &cobra.Command{ Use: "down-to [VERSION]", Short: "Rollback all database migrations down to a specific version", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { version, err := strconv.ParseInt(args[0], 10, 0) if err != nil { fmt.Printf("Error: Couldn't parse version: %v\n", err) return } if err := goose.DownTo(sqlo, migrate.MigrationsConfig().BasePath, version); err != nil { fmt.Printf("Error: Couldn't rollback migrations to target version %d: %v\n", version, err) return } }, } } // MigrateRedoCmd returns a command to rollback the most recent database migration and reapply it. func MigrateRedoCmd(sqlo *sql.DB) *cobra.Command { return &cobra.Command{ Use: "redo", Short: "Rollback the most recent database migration and reapply it", Run: func(cmd *cobra.Command, args []string) { if err := goose.Redo(sqlo, migrate.MigrationsConfig().BasePath); err != nil { fmt.Printf("Error: Couldn't redo migration: %v\n", err) return } }, } }