package cmd import ( "database/sql" "errors" "fmt" "github.com/golang-migrate/migrate/v4" "github.com/rs/zerolog" ) type MigrateCmd[E any] struct { program *Program[E] } func (cmd *MigrateCmd[E]) Execute([]string) (finalErr error) { cmd.program.LoggingOptions.SetMinLoggingLevel(zerolog.InfoLevel) log := cmd.program.Logger db, err := sql.Open("postgres", cmd.program.DatabaseOptions.DSN) if err != nil { return err } defer func() { if err := db.Close(); err != nil && finalErr != nil { finalErr = fmt.Errorf("could not close db: %w", err) } }() if err := cmd.program.dbSchema.Migrate(db, cmd.program.Logger); err != nil { if errors.Is(err, migrate.ErrNoChange) { log.Info().Msg("The database is already up-to-date") } else { return fmt.Errorf("failed to run migration: %w", err) } } else { log.Info().Msg("database successfully upgraded") } return nil } func SetupMigrateCmd[E any](program *Program[E]) *MigrateCmd[E] { cmd := MigrateCmd[E]{ program: program, } migrate, err := program.Parser.AddCommand( "migrate", "Migrate the DB to the right version", "", &cmd) if err != nil { program.Logger.Fatal().Msg(err.Error()) } migrate.EnvNamespace = "MIGRATE" return &cmd }