package database import ( "errors" "fmt" "io/fs" "log/slog" "sort" "strings" "bunker/commons" "bunker/server/internal/services/core" "github.com/pressly/goose/v3" ) var errMigrationsAlreadyRegistered = errors.New("migrations already registered") func (d *database) applyMigrations() error { d.logger.Info("Migrating database...") modules := make([]string, 0) for module := range d.migrations { modules = append(modules, module) } sort.Strings(modules) _ = goose.SetDialect(string(goose.DialectPostgres)) gooseLogger := commons.NewGooseLogger(d.logger) goose.SetLogger(gooseLogger) for _, module := range modules { d.logger.Info("Migrating database for module...", "module", module) goose.SetBaseFS(d.migrations[module]) goose.SetTableName(strings.ReplaceAll(module, "/", "_") + "_migrations") if err := goose.Up(d.db.DB, "migrations"); err != nil { return fmt.Errorf("%w: applying migrations for module '%s': %w", core.ErrDatabase, module, err) } moduleDBVersion, err := goose.GetDBVersion(d.db.DB) if err != nil { return fmt.Errorf("%w: get database version for module '%s': %w", core.ErrDatabase, module, err) } d.version += moduleDBVersion d.logger.Info( "Database for module migrated to latest version", "module", module, "module_db_version", moduleDBVersion, "db_version", d.version, ) } d.logger.Info("Database migrated.", "version", d.version) return nil } func (d *database) RegisterMigrations(moduleName string, fSys fs.FS) error { slog.Debug("Registering migrations for service.", "service", moduleName) if _, found := d.migrations[moduleName]; found { return fmt.Errorf( "%w: RegisterMigrations: module '%s': %w", core.ErrDatabase, moduleName, errMigrationsAlreadyRegistered, ) } d.migrations[moduleName] = fSys slog.Debug("Migrations for service successfully registered.", "service", moduleName) return nil }