118 lines
2.8 KiB
Go
118 lines
2.8 KiB
Go
package cmd
|
|
|
|
import (
|
|
"ariga.io/atlas/sql/sqltool"
|
|
"context"
|
|
"entgo.io/ent/dialect"
|
|
"entgo.io/ent/dialect/sql/schema"
|
|
"errors"
|
|
"fmt"
|
|
entmigrate "framework_v2/internal/ent/migrate"
|
|
"framework_v2/internal/migrations"
|
|
"github.com/golang-migrate/migrate/v4"
|
|
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
|
_ "github.com/golang-migrate/migrate/v4/source/file"
|
|
"github.com/golang-migrate/migrate/v4/source/httpfs"
|
|
"github.com/spf13/cobra"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
var dsnCommand = &cobra.Command{
|
|
Use: "dsn",
|
|
Short: "生成 DSN",
|
|
Long: "生成 DSN",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
fmt.Print(config.DB.Driver + "://" + config.DB.DSN)
|
|
},
|
|
}
|
|
|
|
var migrateCommand = &cobra.Command{
|
|
Use: "migrate",
|
|
Short: "迁移数据库",
|
|
Long: "适用于生产环境的数据库迁移",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
RunMigrate()
|
|
},
|
|
}
|
|
|
|
var createMigrateCommand = &cobra.Command{
|
|
Use: "create-migrate",
|
|
Short: "新建迁移",
|
|
Long: "从 internal/ent 中新建迁移。在这之前,需要运行 go generate ./internal/ent",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
generateMigration()
|
|
},
|
|
}
|
|
|
|
// RunMigrate 为数据库函数
|
|
func RunMigrate() {
|
|
source, err := httpfs.New(http.FS(migrations.MigrationFS), ".")
|
|
|
|
mig, err := migrate.NewWithSourceInstance("httpfs", source, config.DB.Driver+"://"+config.DB.DSN)
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
timeStarted := time.Now()
|
|
|
|
str := fmt.Sprintf("Migration started at %s", timeStarted)
|
|
fmt.Println(str)
|
|
|
|
err = mig.Up()
|
|
|
|
if err != nil {
|
|
if errors.Is(err, migrate.ErrNoChange) {
|
|
fmt.Println("No change")
|
|
return
|
|
}
|
|
|
|
fmt.Println("Error: ", err)
|
|
|
|
version, isDirty, err := mig.Version()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
fmt.Println("Current version: ", version)
|
|
fmt.Println("Is dirty: ", isDirty)
|
|
|
|
fmt.Println("force to version: ", version-1)
|
|
err = mig.Force(int(version - 1))
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
timeFinished := time.Now()
|
|
str = fmt.Sprintf("Migration finished at %s", timeFinished)
|
|
fmt.Println(str)
|
|
}
|
|
|
|
func generateMigration() {
|
|
ctx := context.Background()
|
|
dir, err := sqltool.NewGooseDir("internal/migrations")
|
|
if err != nil {
|
|
log.Fatalf("failed creating atlas migration directory: %v", err)
|
|
}
|
|
// Migrate diff options.
|
|
opts := []schema.MigrateOption{
|
|
schema.WithDir(dir), // provide migration directory
|
|
schema.WithMigrationMode(schema.ModeInspect), // provide migration mode
|
|
schema.WithDialect(dialect.Postgres), // Ent dialect to use
|
|
|
|
}
|
|
if len(os.Args) != 3 {
|
|
log.Fatalln("migration name is required. Use: 'go run -mod=mod internal/ent/migrate/main.go <name>'")
|
|
}
|
|
|
|
err = entmigrate.NamedDiff(ctx, config.DB.Driver+"://"+config.DB.DSN, os.Args[2], opts...)
|
|
if err != nil {
|
|
log.Fatalf("failed generating migration file: %v", err)
|
|
}
|
|
}
|