ultisuite-backend/internal/dbmigrate/migrate.go
2026-05-24 00:03:36 +02:00

65 lines
1.4 KiB
Go

package dbmigrate
import (
"errors"
"fmt"
"log/slog"
"os"
"strings"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/ultisuite/ulti-backend/migrations"
)
// Up applies pending SQL migrations. No-op when ULTID_AUTO_MIGRATE=false.
func Up(databaseURL string) error {
if !autoMigrateEnabled() {
slog.Info("database auto-migrate disabled")
return nil
}
if strings.TrimSpace(databaseURL) == "" {
return fmt.Errorf("empty database URL")
}
source, err := iofs.New(migrations.Files, ".")
if err != nil {
return fmt.Errorf("migration source: %w", err)
}
m, err := migrate.NewWithSourceInstance("iofs", source, databaseURL)
if err != nil {
return fmt.Errorf("migrate init: %w", err)
}
defer func() {
srcErr, dbErr := m.Close()
if srcErr != nil {
slog.Warn("migrate close source", "error", srcErr)
}
if dbErr != nil {
slog.Warn("migrate close database", "error", dbErr)
}
}()
if err := m.Up(); err != nil {
if errors.Is(err, migrate.ErrNoChange) {
slog.Info("database schema up to date")
return nil
}
return fmt.Errorf("migrate up: %w", err)
}
slog.Info("database migrations applied")
return nil
}
func autoMigrateEnabled() bool {
v := strings.ToLower(strings.TrimSpace(os.Getenv("ULTID_AUTO_MIGRATE")))
if v == "false" || v == "0" || v == "no" {
return false
}
return true
}