aboutsummaryrefslogblamecommitdiff
path: root/cmd/shorg/migrator/migrator.go
blob: 01dd8194af8365a2866d3b29166c1d29273362f2 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                

        
                       





                                        

                                  

                              
                             

 
                              









                                                                 
                                                                              



                                                                    
                                                                                              












                                                                       
                                                                              



                                                                    
                                                                                              























                                                                                                  
                                                                              



                                                                    
                                                                                              























                                                                                                
                                                                              



                                                                    
                                                                                              












                                                                       
                                                                              



                                                                    
                                                                                              












                                                                         
                                                                              



                                                                    
                                                                                              













                                                                                                   










































                                                                                                                  














                                                                                             
package migrator

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/uptrace/bun/migrate"
	"github.com/urfave/cli/v2"
	"sh.org.ru/migrations"
	"sh.org.ru/pkg/config"
	"sh.org.ru/pkg/db"
	"sh.org.ru/pkg/model"
)

func Migrator() *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/config.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations.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/config.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations.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/config.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations.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/config.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations.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/config.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations.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/config.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					migrator, err := newMigrator(c, migrations.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
				},
			},
			{
				Name:  "import",
				Usage: "import json with quotes",
				Flags: []cli.Flag{
					&cli.StringFlag{
						Name:  "config",
						Value: "./config/config.yaml",
						Usage: "config",
					},
				},
				Action: func(c *cli.Context) error {
					configFile := c.String("config")
					cfg, err := config.New(configFile)
					if err != nil {
						return err
					}
					db := db.New(cfg.DB)
					file := c.Args().First()
					quotes := []string{}
					fp, err := os.Open(file)
					if err != nil {
						return err
					}
					defer fp.Close()

					if err := json.NewDecoder(fp).Decode(&quotes); err != nil {
						return err
					}

					for _, text := range quotes {
						q := &model.Quote{
							Quote:    text,
							Approved: true,
							Archive:  true,
						}
						if _, err := db.NewInsert().Model(q).Exec(c.Context); err != nil {
							return err
						}
					}

					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
}