83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package migration
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"path/filepath"
|
|
"sort"
|
|
"sync"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
)
|
|
|
|
var Migrate = &Migration{
|
|
version: make(map[string]func(db *gorm.DB, version string) error),
|
|
}
|
|
|
|
type Migration struct {
|
|
db *gorm.DB
|
|
version map[string]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 string, f func(db *gorm.DB, version string) error) {
|
|
e.mutex.Lock()
|
|
defer e.mutex.Unlock()
|
|
if _, exists := e.version[k]; exists {
|
|
panic(fmt.Sprintf("duplicate migration version registered: %s", k))
|
|
}
|
|
e.version[k] = f
|
|
}
|
|
|
|
func (e *Migration) Migrate() {
|
|
versions := make([]string, 0)
|
|
for k := range e.version {
|
|
versions = append(versions, k)
|
|
}
|
|
if !sort.StringsAreSorted(versions) {
|
|
sort.Strings(versions)
|
|
}
|
|
var err error
|
|
var count int64
|
|
// GoAuto 改动(#48):版本存在性检查用 Warn 级会话,不回显 SQL。
|
|
// 上游每个版本都会打一条 SELECT count(*),几十个迁移就是几十行——真正
|
|
// 值得看的是下面 e.db.Debug() 执行的那些「确实要跑」的迁移。
|
|
checkDB := e.db.Session(&gorm.Session{Logger: e.db.Logger.LogMode(logger.Warn)})
|
|
applied, skipped := 0, 0
|
|
for _, v := range versions {
|
|
err = checkDB.Table("sys_migration").Where("version = ?", v).Count(&count).Error
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
if count > 0 {
|
|
// GoAuto 改动(#48):上游这里是 log.Println(count),每个已应用的
|
|
// 迁移打印一个裸 "1"——没有说明是什么、也没说是哪个版本。而且 log
|
|
// 写的是 stderr,启动脚本的 `2>&1 |` 会把它变成一整块红色错误,
|
|
// 看起来像迁移失败了。汇总成一行,走 stdout。
|
|
skipped++
|
|
count = 0
|
|
continue
|
|
}
|
|
err = (e.version[v])(e.db.Debug(), v)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
applied++
|
|
}
|
|
fmt.Printf("迁移完成:新执行 %d 个,跳过 %d 个(已应用)\n", applied, skipped)
|
|
}
|
|
|
|
func GetFilename(s string) string {
|
|
s = filepath.Base(s)
|
|
return s[:13]
|
|
}
|