From f3a3a60c8015334287a4332676747f1b1f35a612 Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Thu, 3 Aug 2023 22:33:37 +0200 Subject: [PATCH] do not start with V1 database --- internal/adapters/database.go | 49 ++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/internal/adapters/database.go b/internal/adapters/database.go index ff74207..8ddc31f 100644 --- a/internal/adapters/database.go +++ b/internal/adapters/database.go @@ -37,6 +37,7 @@ type GormLogger struct { SourceField string IgnoreErrRecordNotFound bool Debug bool + Silent bool } func NewLogger(slowThreshold time.Duration, debug bool) *GormLogger { @@ -44,27 +45,46 @@ func NewLogger(slowThreshold time.Duration, debug bool) *GormLogger { SlowThreshold: slowThreshold, Debug: debug, IgnoreErrRecordNotFound: true, + Silent: false, SourceField: "src", } } -func (l *GormLogger) LogMode(logger.LogLevel) logger.Interface { +func (l *GormLogger) LogMode(level logger.LogLevel) logger.Interface { + if level == logger.Silent { + l.Silent = true + } else { + l.Silent = false + } return l } func (l *GormLogger) Info(ctx context.Context, s string, args ...interface{}) { + if l.Silent { + return + } logrus.WithContext(ctx).Infof(s, args...) } func (l *GormLogger) Warn(ctx context.Context, s string, args ...interface{}) { + if l.Silent { + return + } logrus.WithContext(ctx).Warnf(s, args...) } func (l *GormLogger) Error(ctx context.Context, s string, args ...interface{}) { + if l.Silent { + return + } logrus.WithContext(ctx).Errorf(s, args...) } func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { + if l.Silent { + return + } + elapsed := time.Since(begin) sql, rows := fc() fields := logrus.Fields{ @@ -156,14 +176,37 @@ func NewSqlRepository(db *gorm.DB) (*SqlRepo, error) { db: db, } - err := repo.migrate() - if err != nil { + if err := repo.preCheck(); err != nil { + return nil, fmt.Errorf("failed to initialize database: %w", err) + } + + if err := repo.migrate(); err != nil { return nil, fmt.Errorf("failed to initialize database: %w", err) } return repo, nil } +func (r *SqlRepo) preCheck() error { + // WireGuard Portal v1 database migration table + type DatabaseMigrationInfo struct { + Version string `gorm:"primaryKey"` + Applied time.Time + } + + // temporarily disable logger as the next request might fail (intentionally) + r.db.Logger.LogMode(logger.Silent) + defer func() { r.db.Logger.LogMode(logger.Info) }() + + lastVersion := DatabaseMigrationInfo{} + err := r.db.Order("applied desc, version desc").FirstOrInit(&lastVersion).Error + if err != nil { + return nil // we probably don't have a V1 database =) + } + + return fmt.Errorf("detected a WireGuard Portal V1 database (version: %s) - please migrate first", lastVersion.Version) +} + func (r *SqlRepo) migrate() error { logrus.Tracef("sysstat migration: %v", r.db.AutoMigrate(&SysStat{})) logrus.Tracef("user migration: %v", r.db.AutoMigrate(&domain.User{}))