package migrate import ( "errors" "fmt" "log/slog" "github.com/spf13/cobra" "git.avsdev.uk/Go/job-search/internal/cli" "git.avsdev.uk/Go/job-search/internal/store" ) func commandDown(opts *cli.Options) *cobra.Command { cmd := &cobra.Command{ Use: "down", Short: "Migrate SQLite database to a previous version", Long: `Roll back the most recent migrations. --steps 0 rolls back every migration which deletes all data and must be confirmed by providing -yes.`, Args: cobra.NoArgs, PersistentPreRun: func(cmd *cobra.Command, args []string) { slog.Debug("command persistent pre-run", "command", "migrate.down") }, PersistentPostRun: func(cmd *cobra.Command, args []string) { slog.Debug("command persistent post-run", "command", "migrate.down") }, RunE: func(cmd *cobra.Command, args []string) (err error) { slog.Debug("command run", "command", "migrate.down") yes, _ := cmd.Flags().GetBool("yes") steps, _ := cmd.Flags().GetUint("steps") migrator, db, err := openMigrator(cmd, opts, false, false) if err != nil { return err } defer closeDB(db, &err) results, err := store.StepDown(cmd.Context(), migrator, int(steps), yes) if len(results) == 0 && err == nil { fmt.Println("No changes made to database (empty)") return nil } if errors.Is(err, store.ErrWouldEmptyDatabase) { return fmt.Errorf( "%w\n\nTo confirm you wish to proceed, pass the --yes flag", err, ) } if printErr := printResults(cmd.OutOrStdout(), results); printErr != nil { return errors.Join(err, printErr) } if err != nil { return failure(cmd.OutOrStdout(), err) } return printVersion(cmd.Context(), cmd.OutOrStdout(), migrator) }, } cmd.Flags().Uint( "steps", 0, "number of migrations to roll back. 0 = all (deletes all data)", ) if err := cmd.MarkFlagRequired("steps"); err != nil { panic(err) // only fails if the flag isn't defined } cmd.Flags().BoolP( "yes", "y", false, "confirm you are intending to roll back every migration", ) return cmd }