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) } }