wip
This commit is contained in:
No files matched your search
Vendored
+7
-7
@@ -7,12 +7,12 @@
|
|||||||
"mode": "auto",
|
"mode": "auto",
|
||||||
"program": "${workspaceFolder}/cmd/main-api"
|
"program": "${workspaceFolder}/cmd/main-api"
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// "name": "Launch Package excel migrator",
|
"name": "Launch Package migratioon",
|
||||||
// "type": "go",
|
"type": "go",
|
||||||
// "request": "launch",
|
"request": "launch",
|
||||||
// "mode": "auto",
|
"mode": "auto",
|
||||||
// "program": "${workspaceFolder}/cmd/excelmigrator"
|
"program": "${workspaceFolder}/cmd/migration"
|
||||||
// }
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
env "dev" {
|
||||||
|
url = "postgres://moko:password@localhost:5432/simrs_vx1?sslmode=disable"
|
||||||
|
dev = "docker://postgres/17/dev?search_path=public"
|
||||||
|
migration {
|
||||||
|
dir = "file://migrations"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
-- Create "User" table
|
||||||
|
CREATE TABLE "User" (
|
||||||
|
"Id" bigserial NOT NULL,
|
||||||
|
"CreatedAt" text NULL,
|
||||||
|
"UpdatedAt" text NULL,
|
||||||
|
"DeteledAt" timestamptz NULL,
|
||||||
|
"Name" character varying(25) NOT NULL,
|
||||||
|
"Password" character varying(255) NOT NULL,
|
||||||
|
"Status_Code" character varying(10) NOT NULL,
|
||||||
|
"FailedLoginCount" smallint NULL,
|
||||||
|
PRIMARY KEY ("Id")
|
||||||
|
);
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- Modify "User" table
|
||||||
|
ALTER TABLE "User" ALTER COLUMN "Status_Code" TYPE character varying(11);
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- Modify "User" table
|
||||||
|
ALTER TABLE "User" ALTER COLUMN "CreatedAt" TYPE timestamptz;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
h1:6uh16WKu8m2VzaFju4mLFjCrEA9FJmxEYP/bKU9bLV4=
|
||||||
|
20250814082958_auto_migration.sql h1:r1gxPLhQuUmRZhfBomI2gGVA1hR7B4eXF3bYJGA9uVE=
|
||||||
|
20250814083106_auto_migration.sql h1:CeUsjDrrfxEl+VGDX+azPCXSu88HKZr+VTzAba4p/Vk=
|
||||||
|
20250814085334_auto_migration.sql h1:RokGeINUPr9iFKuQRyx9HHVVm5HS6fxyTN91gcG1Hgc=
|
||||||
@@ -7,7 +7,9 @@ toolchain go1.23.11
|
|||||||
require (
|
require (
|
||||||
github.com/karincake/apem v0.0.16-g
|
github.com/karincake/apem v0.0.16-g
|
||||||
github.com/karincake/dodol v0.0.1
|
github.com/karincake/dodol v0.0.1
|
||||||
|
github.com/karincake/getuk v0.1.0
|
||||||
github.com/karincake/lepet v0.0.1
|
github.com/karincake/lepet v0.0.1
|
||||||
|
golang.org/x/crypto v0.40.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/postgres v1.5.7
|
gorm.io/driver/postgres v1.5.7
|
||||||
gorm.io/gorm v1.25.10
|
gorm.io/gorm v1.25.10
|
||||||
@@ -26,11 +28,8 @@ require (
|
|||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/nxadm/tail v1.4.11 // indirect
|
github.com/nxadm/tail v1.4.11 // indirect
|
||||||
github.com/rs/zerolog v1.33.0 // indirect
|
github.com/rs/zerolog v1.33.0 // indirect
|
||||||
golang.org/x/crypto v0.40.0 // indirect
|
|
||||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||||
golang.org/x/net v0.42.0 // indirect
|
golang.org/x/net v0.42.0 // indirect
|
||||||
golang.org/x/sys v0.34.0 // indirect
|
golang.org/x/sys v0.34.0 // indirect
|
||||||
golang.org/x/text v0.27.0 // indirect
|
golang.org/x/text v0.27.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/karincake/apem => D:/Kuli/Sabbi/external/apem
|
|
||||||
@@ -20,8 +20,12 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
|||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/karincake/apem v0.0.16-g h1:jPIr/YiaJhVSftdA1PyB2tlDiQtFeTVZohO1qf0qpw0=
|
||||||
|
github.com/karincake/apem v0.0.16-g/go.mod h1:cQP2sJfDrLRIiwWoaLWw/z8uAya+DWu/FpmYeinMQXM=
|
||||||
github.com/karincake/dodol v0.0.1 h1:jUXmJh1r0Ei4fmHPZ6IUkoplW/V9d27L63JEl6zudL0=
|
github.com/karincake/dodol v0.0.1 h1:jUXmJh1r0Ei4fmHPZ6IUkoplW/V9d27L63JEl6zudL0=
|
||||||
github.com/karincake/dodol v0.0.1/go.mod h1:2f1NcvkvY0J3GMUkwILNDYVvRUpz0W3lpPp/Ha/Ld24=
|
github.com/karincake/dodol v0.0.1/go.mod h1:2f1NcvkvY0J3GMUkwILNDYVvRUpz0W3lpPp/Ha/Ld24=
|
||||||
|
github.com/karincake/getuk v0.1.0 h1:jcIsASrr0UDE528GN7Ua6n9UFyRgUypsWh8Or8wzCO0=
|
||||||
|
github.com/karincake/getuk v0.1.0/go.mod h1:NVnvxSGAkQ/xuq99FzWACvY5efyKPLFla1cKB8czm7c=
|
||||||
github.com/karincake/lepet v0.0.1 h1:eq/cwn5BBg0jWZ1c/MmvhFIBma0zBpVs2LwkfDOncy4=
|
github.com/karincake/lepet v0.0.1 h1:eq/cwn5BBg0jWZ1c/MmvhFIBma0zBpVs2LwkfDOncy4=
|
||||||
github.com/karincake/lepet v0.0.1/go.mod h1:U84w7olXO3BPJw2Hu6MBonFmJmPKaFjtyAj1HTu3z1A=
|
github.com/karincake/lepet v0.0.1/go.mod h1:U84w7olXO3BPJw2Hu6MBonFmJmPKaFjtyAj1HTu3z1A=
|
||||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import "gorm.io/gorm"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
type Base struct {
|
type Base struct {
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt" gorm:"type:timestamptz"`
|
||||||
UpdatedAt string `json:"updatedAt"`
|
UpdatedAt string `json:"updatedAt" gorm:"type:timestamptz"`
|
||||||
DeteledAt gorm.DeletedAt `json:"deletedAt,omitempty"`
|
DeteledAt gorm.DeletedAt `json:"deletedAt,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
type Main struct {
|
type Main struct {
|
||||||
Id uint `json:"id" gorm:"primaryKey"` // depends on the system architecture
|
Id uint `json:"id" gorm:"primaryKey"` // depends on the system architecture
|
||||||
Base
|
Base
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ type User struct {
|
|||||||
ecore.Main // adjust this according to the needs
|
ecore.Main // adjust this according to the needs
|
||||||
Name string `json:"name" gorm:"not null;size:25"`
|
Name string `json:"name" gorm:"not null;size:25"`
|
||||||
Password string `json:"password" gorm:"not null;size:255"`
|
Password string `json:"password" gorm:"not null;size:255"`
|
||||||
Status_Code erc.StatusCode `json:"status_code" gorm:"not null;size:10"`
|
Status_Code erc.StatusCode `json:"status_code" gorm:"not null;size:12"`
|
||||||
FailedLoginCount uint `json:"failedLoginCount"`
|
FailedLoginCount uint8 `json:"failedLoginCount" gorm:"type:smallint"`
|
||||||
}
|
}
|
||||||
@@ -2,45 +2,124 @@ package migration
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"os/exec"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"gorm.io/driver/postgres"
|
"gorm.io/driver/postgres"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/schema"
|
"gorm.io/gorm/schema"
|
||||||
|
|
||||||
|
eu "simrs-vx/internal/domain/main-entities/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
DbCfg DbConf `yaml:"dbCfg"`
|
||||||
|
}
|
||||||
|
|
||||||
type DbConf struct {
|
type DbConf struct {
|
||||||
Dsn string
|
DSN string `yaml:"dsn"`
|
||||||
Dialect string
|
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() {
|
func Migrate() {
|
||||||
// use default config file location or use flat
|
// Your existing config loading code...
|
||||||
cfgFile := "./config.yml"
|
cfgFile := "./config.yml"
|
||||||
flag.StringVar(&cfgFile, "config-file", "./config.yml", "Configuration path (default=./config.yaml)")
|
flag.StringVar(&cfgFile, "config-file", "./config.yml", "Configuration path (default=./config.yaml)")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// read the config file
|
|
||||||
yamlFile, err := os.ReadFile(cfgFile)
|
yamlFile, err := os.ReadFile(cfgFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse into config struct
|
var cfg Config
|
||||||
var dbConf DbConf
|
err = yaml.Unmarshal(yamlFile, &cfg)
|
||||||
err = yaml.Unmarshal(yamlFile, &dbConf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Print("config is loaded successfully")
|
|
||||||
|
|
||||||
// create database connection
|
argsWithProg := os.Args
|
||||||
db, err := gorm.Open(postgres.Open(dbConf.Dsn), &gorm.Config{
|
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{
|
NamingStrategy: schema.NamingStrategy{
|
||||||
SingularTable: true,
|
SingularTable: true,
|
||||||
NoLowerCase: true,
|
NoLowerCase: true,
|
||||||
@@ -49,45 +128,20 @@ func Migrate() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Print("database-connection is established successfully")
|
|
||||||
|
|
||||||
// migrate all the tables
|
|
||||||
modelList := []any{
|
modelList := []any{
|
||||||
// &single.Single{}}, // example
|
&eu.User{},
|
||||||
|
// Add other models here
|
||||||
}
|
}
|
||||||
|
|
||||||
argsWithProg := os.Args
|
if err := db.AutoMigrate(modelList...); err != nil {
|
||||||
if len(argsWithProg) > 1 {
|
log.Fatal(err)
|
||||||
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...)
|
|
||||||
}
|
}
|
||||||
|
log.Println("Schema created with GORM")
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("migration is complete")
|
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