diff --git a/pkg/migration/make.go b/pkg/migration/make.go new file mode 100644 index 0000000..fed7220 --- /dev/null +++ b/pkg/migration/make.go @@ -0,0 +1,127 @@ +package migration + +/* + * @Author: lwnmengjing + * @Date: 2023/8/12 09:15:17 + * @Last Modified by: lwnmengjing + * @Last Modified time: 2023/8/12 09:15:17 + */ + +import ( + "bytes" + "embed" + "log" + "log/slog" + "os" + "path/filepath" + "sort" + "strconv" + "sync" + "text/template" + "time" + + "github.com/spf13/cast" + "gorm.io/gorm" +) + +//go:embed *.tpl +var FS embed.FS + +var Migrate = &Migration{ + version: make(map[int]func(db *gorm.DB, version string) error), +} + +type Migration struct { + db *gorm.DB + version map[int]func(db *gorm.DB, version string) error + mutex sync.Mutex +} + +func (e *Migration) GetDb() *gorm.DB { + return e.db +} + +func (e *Migration) SetDb(db *gorm.DB) { + e.db = db +} + +func (e *Migration) SetVersion(k int, f func(db *gorm.DB, version string) error) { + e.mutex.Lock() + defer e.mutex.Unlock() + e.version[k] = f +} + +func (e *Migration) Migrate() { + versions := make([]int, 0) + for k := range e.version { + versions = append(versions, k) + } + if !sort.IntsAreSorted(versions) { + sort.Ints(versions) + } + var err error + var count int64 + for _, v := range versions { + err = e.db.Table("mss_boot_migration").Where("version = ?", v).Count(&count).Error + if err != nil { + log.Fatalf("get migration version error: %v", err) + } + if count > 0 { + log.Println(count) + count = 0 + continue + } + err = (e.version[v])(e.db, strconv.Itoa(v)) + if err != nil { + log.Fatalf("migrate version %d error: %v", v, err) + } + } +} + +func GetFilename(s string) int { + s = filepath.Base(s) + return cast.ToInt(s[:13]) +} + +func GenFile(system bool, path string) error { + t1, err := template.ParseFS(FS, "migrate.tpl") + if err != nil { + slog.Error("parse template error", slog.Any("err", err)) + return err + } + m := map[string]string{} + m["GenerateTime"] = strconv.FormatInt(time.Now().UnixNano()/1e6, 10) + m["Package"] = "custom" + if system { + m["Package"] = "system" + } + var b1 bytes.Buffer + err = t1.Execute(&b1, m) + if err != nil { + slog.Error("execute template error", slog.Any("err", err)) + return err + } + if system { + fileCreate(b1, filepath.Join(path, "system", m["GenerateTime"]+"_migrate.go")) + } else { + fileCreate(b1, filepath.Join(path, "custom", m["GenerateTime"]+"_migrate.go")) + } + return nil +} + +func fileCreate(content bytes.Buffer, name string) { + file, err := os.Create(name) + defer func(file *os.File) { + err := file.Close() + if err != nil { + log.Fatalln(err) + } + }(file) + if err != nil { + log.Println(err) + } + _, err = file.WriteString(content.String()) + if err != nil { + log.Println(err) + } +} diff --git a/pkg/migration/migrate.tpl b/pkg/migration/migrate.tpl new file mode 100644 index 0000000..300b7b4 --- /dev/null +++ b/pkg/migration/migrate.tpl @@ -0,0 +1,40 @@ +package {{.Package}} + +import ( + "runtime" + + "github.com/mss-boot-io/mss-boot/pkg/migration" + migrationModel "github.com/mss-boot-io/mss-boot/pkg/migration/models" + "gorm.io/gorm" +) + +func init() { + _, fileName, _, _ := runtime.Caller(0) + migration.Migrate.SetVersion(migration.GetFilename(fileName), _{{.GenerateTime}}Migrate) +} + +func _{{.GenerateTime}}Migrate(db *gorm.DB, version string) error { + return db.Transaction(func(tx *gorm.DB) error { + + // TODO: here to write the content to be changed + + // TODO: e.g. modify table field, please delete this code during use + //err := tx.Migrator().RenameColumn(&models.SysConfig{}, "config_id", "id") + //if err != nil { + // return err + //} + + // TODO: e.g. add table structure, please delete this code during use + //err = tx.Migrator().AutoMigrate( + // new(models.CasbinRule), + // ) + //if err != nil { + // return err + //} + + + return tx.Create(&migrationModel.Migration{ + Version: version, + }).Error + }) +} diff --git a/pkg/migration/models/migrate.go b/pkg/migration/models/migrate.go new file mode 100644 index 0000000..fac782a --- /dev/null +++ b/pkg/migration/models/migrate.go @@ -0,0 +1,12 @@ +package models + +import "time" + +type Migration struct { + Version string `gorm:"primaryKey"` + ApplyTime time.Time `gorm:"autoCreateTime"` +} + +func (Migration) TableName() string { + return "mss_boot_migration" +} diff --git a/pkg/textcolor.go b/pkg/textcolor.go new file mode 100644 index 0000000..44b9f5f --- /dev/null +++ b/pkg/textcolor.go @@ -0,0 +1,77 @@ +package pkg + +import "fmt" + +/* + * @Author: lwnmengjing + * @Date: 2023/8/10 00:14:22 + * @Last Modified by: lwnmengjing + * @Last Modified time: 2023/8/10 00:14:22 + */ + +// 前景 背景 颜色 +// --------------------------------------- +// 30 40 黑色 +// 31 41 红色 +// 32 42 绿色 +// 33 43 黄色 +// 34 44 蓝色 +// 35 45 紫红色 +// 36 46 青蓝色 +// 37 47 白色 +// +// 代码 意义 +// ------------------------- +// 0 终端默认设置 +// 1 高亮显示 +// 4 使用下划线 +// 5 闪烁 +// 7 反白显示 +// 8 不可见 + +const ( + TextBlack = iota + 30 + TextRed + TextGreen + TextYellow + TextBlue + TextMagenta + TextCyan + TextWhite +) + +func Black(msg string) string { + return SetColor(msg, 0, 0, TextBlack) +} + +func Red(msg string) string { + return SetColor(msg, 0, 0, TextRed) +} + +func Green(msg string) string { + return SetColor(msg, 0, 0, TextGreen) +} + +func Yellow(msg string) string { + return SetColor(msg, 0, 0, TextYellow) +} + +func Blue(msg string) string { + return SetColor(msg, 0, 0, TextBlue) +} + +func Magenta(msg string) string { + return SetColor(msg, 0, 0, TextMagenta) +} + +func Cyan(msg string) string { + return SetColor(msg, 0, 0, TextCyan) +} + +func White(msg string) string { + return SetColor(msg, 0, 0, TextWhite) +} + +func SetColor(msg string, conf, bg, text int) string { + return fmt.Sprintf("%c[%d;%d;%dm%s%c[0m", 0x1B, conf, bg, text, msg, 0x1B) +}