hi-server/initialize/version.go

76 lines
2.2 KiB
Go

package initialize
import (
"errors"
"time"
gomigrate "github.com/golang-migrate/migrate/v4"
"github.com/perfect-panel/server/internal/model/user"
"gorm.io/gorm"
"github.com/perfect-panel/server/initialize/migrate"
"github.com/perfect-panel/server/internal/svc"
"github.com/perfect-panel/server/pkg/logger"
"github.com/perfect-panel/server/pkg/orm"
)
func Migrate(ctx *svc.ServiceContext) {
mc := orm.Mysql{
Config: ctx.Config.MySQL,
}
now := time.Now()
migrator := migrate.Migrate(mc.Dsn())
if err := migrator.Up(); err != nil {
if errors.Is(err, migrate.NoChange) {
logger.Info("[Migrate] database not change")
} else {
var dirtyErr gomigrate.ErrDirty
if errors.As(err, &dirtyErr) {
logger.Errorf("[Migrate] Dirty database version %d detected, trying auto-recovery", dirtyErr.Version)
forceVersion := int(dirtyErr.Version) - 1
if forceVersion < 0 {
forceVersion = 0
}
if forceErr := migrator.Force(forceVersion); forceErr != nil {
logger.Errorf("[Migrate] Force version error: %v", forceErr.Error())
panic(forceErr)
}
logger.Infof("[Migrate] Force version to %d, retrying migration", forceVersion)
if retryErr := migrator.Up(); retryErr != nil && !errors.Is(retryErr, migrate.NoChange) {
logger.Errorf("[Migrate] Retry Up error: %v", retryErr.Error())
panic(retryErr)
}
} else {
logger.Errorf("[Migrate] Up error: %v", err.Error())
panic(err)
}
}
} else {
logger.Info("[Migrate] Database change, took " + time.Since(now).String())
}
if err := EnsureSchemaCompatibility(ctx); err != nil {
logger.Errorf("[SchemaCompat] repair failed: %v", err.Error())
panic(err)
}
// if not found admin user
err := ctx.DB.Transaction(func(tx *gorm.DB) error {
var count int64
if err := tx.Model(&user.User{}).Count(&count).Error; err != nil {
return err
}
if count == 0 {
if err := migrate.CreateAdminUser(ctx.Config.Administrator.Email, ctx.Config.Administrator.Password, tx); err != nil {
logger.Errorf("[Migrate] CreateAdminUser error: %v", err.Error())
return err
}
logger.Info("[Migrate] Create admin user success")
}
return nil
})
if err != nil {
panic(err)
}
}