package cmd import ( "errors" "fmt" "github.com/golang-migrate/migrate/v4" "github.com/rs/zerolog" "orus.io/orus-io/go-orusapi/database" ) type MigrateCmd[E any] struct { program *Program[E] } func (cmd *MigrateCmd[E]) Execute([]string) error { cmd.program.LoggingOptions.SetMinLoggingLevel(zerolog.InfoLevel) log := cmd.program.Logger m, err := database.NewMigrate(cmd.program.DatabaseOptions.DSN, cmd.program.dbMigrateSource) if err != nil { return fmt.Errorf("failed to init migration engine: %w", err) } defer func() { if sourceErr, databaseErr := m.Close(); sourceErr != nil || databaseErr != nil { if sourceErr != nil { log.Err(err).Msg("error closing Migrate source") } if databaseErr != nil { log.Err(err).Msg("error closing Migrate database") } } }() if err := m.Up(); 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 }