package database import ( "forge.cadoles.com/Cadoles/emissary/internal/command/common" "forge.cadoles.com/Cadoles/emissary/internal/migrate" "github.com/pkg/errors" "github.com/urfave/cli/v2" "gitlab.com/wpetit/goweb/logger" ) const ( MigrateVersionUp = "up" MigrateVersionLatest = "latest" MigrateVersionDown = "down" ) func MigrateCommand() *cli.Command { return &cli.Command{ Name: "migrate", Usage: "Migrate database schema to latest version", Flags: []cli.Flag{ &cli.StringFlag{ Name: "target", Usage: "Migration target, default to latest", Value: "latest", }, &cli.IntFlag{ Name: "force", Usage: "Force migration to version", Value: -1, }, }, Action: func(ctx *cli.Context) error { conf, err := common.LoadConfig(ctx) if err != nil { return errors.Wrap(err, "Could not load configuration") } driver := string(conf.Server.Database.Driver) dsn := string(conf.Server.Database.DSN) migr, err := migrate.New("migrations", driver, dsn) if err != nil { return errors.WithStack(err) } version, dirty, err := migr.Version() if err != nil && !errors.Is(err, migrate.ErrNilVersion) { return errors.WithStack(err) } logger.Info( ctx.Context, "current database shema", logger.F("version", version), logger.F("dirty", dirty), ) target := ctx.String("target") force := ctx.Int("force") if force != -1 { logger.Info(ctx.Context, "forcing database schema version", logger.F("version", force)) if err := migr.Force(force); err != nil { return errors.WithStack(err) } return nil } switch target { case "": fallthrough case MigrateVersionLatest: err = migr.Up() case MigrateVersionDown: err = migr.Steps(-1) case MigrateVersionUp: err = migr.Steps(1) default: return errors.Errorf( "unknown migration target: '%s', available: '%s' (default), '%s' or '%s'", target, MigrateVersionLatest, MigrateVersionUp, MigrateVersionDown, ) } if err != nil && !errors.Is(err, migrate.ErrNoChange) { return errors.Wrap(err, "could not apply migration") } version, dirty, err = migr.Version() if err != nil && !errors.Is(err, migrate.ErrNilVersion) { return errors.WithStack(err) } logger.Info( ctx.Context, "database shema after migration", logger.F("version", version), logger.F("dirty", dirty), ) return nil }, } }