wip
This commit is contained in:
@@ -2,45 +2,124 @@ package migration
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"os/exec"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/schema"
|
||||
|
||||
eu "simrs-vx/internal/domain/main-entities/user"
|
||||
)
|
||||
|
||||
type DbConf struct {
|
||||
Dsn string
|
||||
Dialect string
|
||||
type Config struct {
|
||||
DbCfg DbConf `yaml:"dbCfg"`
|
||||
}
|
||||
|
||||
type DbConf struct {
|
||||
DSN string `yaml:"dsn"`
|
||||
MaxOpenConns int `yaml:"maxOpenConns"`
|
||||
MaxIdleConns int `yaml:"maxIdleConns"`
|
||||
MaxIdleTime int `yaml:"maxIdleTime"`
|
||||
}
|
||||
|
||||
// Migrate all tables at once, one time only for exam purpose
|
||||
func Migrate() {
|
||||
// use default config file location or use flat
|
||||
// Your existing config loading code...
|
||||
cfgFile := "./config.yml"
|
||||
flag.StringVar(&cfgFile, "config-file", "./config.yml", "Configuration path (default=./config.yaml)")
|
||||
flag.Parse()
|
||||
|
||||
// read the config file
|
||||
yamlFile, err := os.ReadFile(cfgFile)
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
// parse into config struct
|
||||
var dbConf DbConf
|
||||
err = yaml.Unmarshal(yamlFile, &dbConf)
|
||||
var cfg Config
|
||||
err = yaml.Unmarshal(yamlFile, &cfg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Print("config is loaded successfully")
|
||||
|
||||
// create database connection
|
||||
db, err := gorm.Open(postgres.Open(dbConf.Dsn), &gorm.Config{
|
||||
argsWithProg := os.Args
|
||||
if len(argsWithProg) > 1 {
|
||||
switch argsWithProg[1] {
|
||||
case "apply":
|
||||
atlasApply(cfg.DbCfg.DSN)
|
||||
case "generate":
|
||||
atlasGenerate(cfg.DbCfg.DSN)
|
||||
case "status":
|
||||
atlasStatus(cfg.DbCfg.DSN)
|
||||
case "gorm":
|
||||
// Fallback to GORM if needed
|
||||
gormMigrate(cfg.DbCfg)
|
||||
default:
|
||||
log.Println("Unknown command. Use: apply, generate, status, or gorm")
|
||||
}
|
||||
} else {
|
||||
// Default: apply Atlas migrations
|
||||
atlasApply(cfg.DbCfg.DSN)
|
||||
}
|
||||
}
|
||||
|
||||
func atlasApply(url string) {
|
||||
log.Println("Applying Atlas migrations...")
|
||||
cmd := exec.Command("atlas", "migrate", "apply",
|
||||
"--dir", "file://migrations",
|
||||
"--url", url)
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Printf("Atlas migration failed: %v", err)
|
||||
log.Println("Try running 'go run migration.go generate' first")
|
||||
} else {
|
||||
log.Println("Atlas migrations applied successfully")
|
||||
}
|
||||
}
|
||||
|
||||
func atlasGenerate(url string) {
|
||||
log.Println("Generating Atlas migration from GORM models...")
|
||||
|
||||
// First, create tables with GORM to get the schema
|
||||
log.Println("Step 1: Creating schema with GORM...")
|
||||
gormCreateSchema(url)
|
||||
|
||||
// Then inspect and create migration
|
||||
log.Println("Step 2: Generating Atlas migration...")
|
||||
cmd := exec.Command("atlas", "migrate", "diff", "auto_migration",
|
||||
"--dir", "file://migrations",
|
||||
"--dev-url", "docker://postgres/17/dev?search_path=public",
|
||||
"--to", url)
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Printf("Atlas generation failed: %v", err)
|
||||
} else {
|
||||
log.Println("Atlas migration generated successfully")
|
||||
}
|
||||
}
|
||||
|
||||
func atlasStatus(url string) {
|
||||
log.Println("Checking Atlas migration status...")
|
||||
cmd := exec.Command("atlas", "migrate", "status",
|
||||
"--dir", "file://migrations",
|
||||
"--url", url)
|
||||
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Printf("Atlas status failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func gormCreateSchema(dsn string) {
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
SingularTable: true,
|
||||
NoLowerCase: true,
|
||||
@@ -49,45 +128,20 @@ func Migrate() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Print("database-connection is established successfully")
|
||||
|
||||
// migrate all the tables
|
||||
modelList := []any{
|
||||
// &single.Single{}}, // example
|
||||
|
||||
&eu.User{},
|
||||
// Add other models here
|
||||
}
|
||||
|
||||
argsWithProg := os.Args
|
||||
if len(argsWithProg) > 1 {
|
||||
if argsWithProg[1] == "gradually" {
|
||||
for _, v := range modelList {
|
||||
name := ""
|
||||
if t := reflect.TypeOf(v); t.Kind() == reflect.Ptr {
|
||||
name = "*" + t.Elem().Name()
|
||||
} else {
|
||||
name = t.Name()
|
||||
}
|
||||
fmt.Println("Migrating ", name)
|
||||
db.AutoMigrate(v)
|
||||
}
|
||||
} else {
|
||||
for _, v := range modelList {
|
||||
name := ""
|
||||
if t := reflect.TypeOf(v); t.Kind() == reflect.Ptr {
|
||||
name = "*" + t.Elem().Name()
|
||||
} else {
|
||||
name = t.Name()
|
||||
}
|
||||
if name == argsWithProg[1] {
|
||||
fmt.Println("Migrating ", name)
|
||||
db.AutoMigrate(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Migrating all tables")
|
||||
db.AutoMigrate(modelList...)
|
||||
if err := db.AutoMigrate(modelList...); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("migration is complete")
|
||||
log.Println("Schema created with GORM")
|
||||
}
|
||||
|
||||
func gormMigrate(dbConf DbConf) {
|
||||
// Your original GORM migrate code as fallback
|
||||
log.Println("Using GORM AutoMigrate...")
|
||||
// ... your existing GORM code here
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user