174 lines
3.7 KiB
Go
174 lines
3.7 KiB
Go
package db
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gitea.dwysokinski.me/twhelp/sessions/cmd/sessions/internal"
|
|
"gitea.dwysokinski.me/twhelp/sessions/internal/bundb/migrations"
|
|
"github.com/urfave/cli/v2"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func New() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "db",
|
|
Usage: "Manages database migrations",
|
|
Subcommands: []*cli.Command{
|
|
newMigrateCmd(),
|
|
newRollbackCmd(),
|
|
newCreateCmd(),
|
|
newStatusCmd(),
|
|
},
|
|
}
|
|
}
|
|
|
|
func newMigrateCmd() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "migrate",
|
|
Usage: "Migrates database",
|
|
Action: func(c *cli.Context) error {
|
|
logger := zap.L()
|
|
|
|
db, err := internal.NewBunDB()
|
|
if err != nil {
|
|
return fmt.Errorf("internal.NewBunDB: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = db.Close()
|
|
}()
|
|
|
|
migrator := migrations.NewMigrator(db)
|
|
|
|
if err = migrator.Init(c.Context); err != nil {
|
|
return fmt.Errorf("migrator.Init: %w", err)
|
|
}
|
|
|
|
group, err := migrator.Migrate(c.Context)
|
|
if err != nil {
|
|
return fmt.Errorf("migrator.Migrate: %w", err)
|
|
}
|
|
if group.ID == 0 {
|
|
logger.Info("there are no new migrations to run")
|
|
return nil
|
|
}
|
|
|
|
logger.Info("migrated to "+strconv.FormatInt(group.ID, 10), zap.Int64("id", group.ID))
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func newRollbackCmd() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "rollback",
|
|
Usage: "Rollbacks the last migration group",
|
|
Action: func(c *cli.Context) error {
|
|
logger := zap.L()
|
|
|
|
db, err := internal.NewBunDB()
|
|
if err != nil {
|
|
return fmt.Errorf("internal.NewBunDB: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = db.Close()
|
|
}()
|
|
|
|
migrator := migrations.NewMigrator(db)
|
|
|
|
group, err := migrator.Rollback(c.Context)
|
|
if err != nil {
|
|
return fmt.Errorf("migrator.Rollback: %w", err)
|
|
}
|
|
if group.ID == 0 {
|
|
logger.Info("there are no groups to roll back")
|
|
return nil
|
|
}
|
|
|
|
logger.Info("rolled back "+strconv.FormatInt(group.ID, 10), zap.Int64("id", group.ID))
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func newCreateCmd() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "create",
|
|
Usage: "Creates migration",
|
|
Subcommands: []*cli.Command{
|
|
{
|
|
Name: "go",
|
|
Usage: "Creates Go migration",
|
|
Action: func(c *cli.Context) error {
|
|
logger := zap.L()
|
|
|
|
migrator := migrations.NewMigrator(nil)
|
|
|
|
mf, err := migrator.CreateGoMigration(c.Context, strings.Join(c.Args().Slice(), "_"))
|
|
if err != nil {
|
|
return fmt.Errorf("migrator.CreateGoMigration: %w", err)
|
|
}
|
|
|
|
logger.Info("created migration", zap.String("name", mf.Name), zap.String("path", mf.Path))
|
|
|
|
return nil
|
|
},
|
|
},
|
|
{
|
|
Name: "sql",
|
|
Usage: "Creates SQL migration",
|
|
Action: func(c *cli.Context) error {
|
|
logger := zap.L()
|
|
|
|
migrator := migrations.NewMigrator(nil)
|
|
|
|
files, err := migrator.CreateSQLMigrations(c.Context, strings.Join(c.Args().Slice(), "_"))
|
|
if err != nil {
|
|
return fmt.Errorf("migrator.CreateSQLMigrations: %w", err)
|
|
}
|
|
|
|
for _, mf := range files {
|
|
logger.Info("created migration", zap.String("name", mf.Name), zap.String("path", mf.Path))
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func newStatusCmd() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "status",
|
|
Usage: "Prints migrations status",
|
|
Action: func(c *cli.Context) error {
|
|
logger := zap.L()
|
|
|
|
db, err := internal.NewBunDB()
|
|
if err != nil {
|
|
return fmt.Errorf("internal.NewBunDB: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = db.Close()
|
|
}()
|
|
|
|
migrator := migrations.NewMigrator(db)
|
|
|
|
ms, err := migrator.MigrationsWithStatus(c.Context)
|
|
if err != nil {
|
|
return fmt.Errorf("migrator.MigrationsWithStatus: %w", err)
|
|
}
|
|
|
|
logger.Info("migrations: " + ms.String())
|
|
logger.Info("last migration group: " + ms.LastGroup().String())
|
|
logger.Info("unapplied: " + ms.Unapplied().String())
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|