Log messages are lower-case event names with their details as key/value
attributes ("error" for errors), in place of formatted strings.
Loggable package take a WithLogger option as part of their "New*" call,
defaulting to slog.Default(). Each tags its lines with its `component`.
Some debug loggers print directly rather than using slog when in
terminal logging mode.
79 lines
2.0 KiB
Go
79 lines
2.0 KiB
Go
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")
|
|
|
|
m, db, err := openMigrator(cmd, opts, false, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer closeDB(db, &err)
|
|
|
|
results, err := store.StepDown(cmd.Context(), m, int(steps), yes)
|
|
|
|
if len(results) == 0 && err == nil {
|
|
fmt.Println("No changes made to database (empty)")
|
|
return nil
|
|
}
|
|
if 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(), m)
|
|
},
|
|
}
|
|
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
|
|
}
|