This commit is contained in:
dpurbosakti
2025-08-14 16:09:31 +07:00
parent 3c84d0d662
commit aa871a95bb
11 changed files with 153 additions and 66 deletions
+7 -4
View File
@@ -1,14 +1,17 @@
package core
import "gorm.io/gorm"
import (
"time"
"gorm.io/gorm"
)
type Base struct {
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
CreatedAt time.Time `json:"createdAt" gorm:"type:timestamptz"`
UpdatedAt string `json:"updatedAt" gorm:"type:timestamptz"`
DeteledAt gorm.DeletedAt `json:"deletedAt,omitempty"`
}
//
type Main struct {
Id uint `json:"id" gorm:"primaryKey"` // depends on the system architecture
Base
+2 -2
View File
@@ -9,6 +9,6 @@ type User struct {
ecore.Main // adjust this according to the needs
Name string `json:"name" gorm:"not null;size:25"`
Password string `json:"password" gorm:"not null;size:255"`
Status_Code erc.StatusCode `json:"status_code" gorm:"not null;size:10"`
FailedLoginCount uint `json:"failedLoginCount"`
Status_Code erc.StatusCode `json:"status_code" gorm:"not null;size:12"`
FailedLoginCount uint8 `json:"failedLoginCount" gorm:"type:smallint"`
}
+104 -50
View File
@@ -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
}