aboutsummaryrefslogblamecommitdiff
path: root/cmd/bun/main.go
blob: 62c94419f8442c8d025372503e3728126ee1daeb (plain) (tree)






























































































































































































                                                                                                   
package main

import (
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/uptrace/bun/migrate"
	"sh.org.ru/cmd/bun/migrations"
	"sh.org.ru/pkg/config"
	"sh.org.ru/pkg/db"

	"github.com/urfave/cli/v2"
)

func main() {
	app := &cli.App{
		Name: "bun",
		Commands: []*cli.Command{
			newDBCommand(migrations.Migrations),
		},
	}
	if err := app.Run(os.Args); err != nil {
		log.Fatal(err)
	}
}

func newDBCommand(migrations *migrate.Migrations) *cli.Command {
	return &cli.Command{
		Name:  "db",
		Usage: "manage database migrations",
		Subcommands: []*cli.Command{
			{
				Name:  "init",
				Usage: "create migration tables",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:  "config",
						Value: "./config/dev.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations)
					if err != nil {
						return err
					}
					log.Println("init")
					return migrator.Init(c.Context)
				},
			},
			{
				Name:  "migrate",
				Usage: "migrate database",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:  "config",
						Value: "./config/dev.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations)
					if err != nil {
						return err
					}

					group, err := migrator.Migrate(c.Context)
					if err != nil {
						return err
					}

					if group.ID == 0 {
						fmt.Printf("there are no new migrations to run\n")
						return nil
					}

					fmt.Printf("migrated to %s\n", group)
					return nil
				},
			},
			{
				Name:  "rollback",
				Usage: "rollback the last migration group",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:  "config",
						Value: "./config/dev.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations)
					if err != nil {
						return err
					}

					group, err := migrator.Rollback(c.Context)
					if err != nil {
						return err
					}

					if group.ID == 0 {
						fmt.Printf("there are no groups to roll back\n")
						return nil
					}

					fmt.Printf("rolled back %s\n", group)
					return nil
				},
			},
			{
				Name:  "lock",
				Usage: "lock migrations",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:  "config",
						Value: "./config/dev.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations)
					if err != nil {
						return err
					}

					return migrator.Lock(c.Context)
				},
			},
			{
				Name:  "unlock",
				Usage: "unlock migrations",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:  "config",
						Value: "./config/dev.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations)
					if err != nil {
						return err
					}

					return migrator.Unlock(c.Context)
				},
			},
			{
				Name:  "create",
				Usage: "create migration",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:  "config",
						Value: "./config/dev.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations)
					if err != nil {
						return err
					}

					name := strings.Join(c.Args().Slice(), "_")
					mf, err := migrator.CreateGoMigration(c.Context, name)
					if err != nil {
						return err
					}
					fmt.Printf("created migration %s (%s)\n", mf.Name, mf.Path)

					return nil
				},
			},
		},
	}
}

func newMigrator(c *cli.Context, migrations *migrate.Migrations) (*migrate.Migrator, error) {
	configFile := c.String("config")
	cfg, err := config.New(configFile)
	if err != nil {
		return nil, err
	}
	db := db.New(cfg.DB)

	migrator := migrate.NewMigrator(db, migrations)
	return migrator, nil
}