Files
query-orchestration/internal/database/migrations.go
T
2025-08-05 07:03:35 -07:00

91 lines
2.2 KiB
Go

package database
import (
"context"
"database/sql"
"embed"
"errors"
"fmt"
"log/slog"
"queryorchestration/internal/serviceconfig/database"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
"github.com/golang-migrate/migrate/v4/source/iofs"
_ "github.com/lib/pq"
)
func createDB(ctx context.Context, cfg database.ConfigProvider) error {
slog.Debug("creating connection to admin database", "uri", cfg.GetDBAdminDBURI())
db, err := sql.Open(cfg.GetDBDriver(), cfg.GetDBAdminDBURI())
if err != nil {
return fmt.Errorf("error opening admin database: %w", err)
}
slog.Debug("pinging admin database", "uri", cfg.GetDBAdminDBURI())
err = db.PingContext(ctx)
if err != nil {
return fmt.Errorf("error pinging admin database: %w", err)
}
slog.Debug("creating admin database", "uri", cfg.GetDBAdminDBURI())
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", cfg.GetDBName()))
if err != nil {
slog.Info("database not created", "name", cfg.GetDBName(), "error", err.Error())
} else {
slog.Info("database created", "name", cfg.GetDBName())
}
slog.Debug("creating connection to database", "uri", cfg.GetDBAdminDBURI())
db, err = sql.Open(cfg.GetDBDriver(), cfg.GetDBURI())
if err != nil {
return fmt.Errorf("error opening database: %w", err)
}
slog.Debug("pinging database", "uri", cfg.GetDBAdminDBURI())
err = db.PingContext(ctx)
if err != nil {
return fmt.Errorf("error pinging database: %w", err)
}
return nil
}
//go:embed migrations/*.sql
var migrations embed.FS
func RunMigrations(ctx context.Context, cfg database.ConfigProvider) error {
err := createDB(ctx, cfg)
if err != nil {
return err
}
source, err := iofs.New(migrations, "migrations")
if err != nil {
return err
}
m, err := migrate.NewWithSourceInstance("iofs", source, cfg.GetDBURI())
if err != nil {
return fmt.Errorf("failed to create migrate instance: %w", err)
}
err = m.Up()
if errors.Is(err, migrate.ErrNoChange) {
slog.Info("No migration changes required")
} else if err != nil {
return fmt.Errorf("failed to apply migrations: %w", err)
} else {
slog.Info("Migrations applied successfully!")
}
return nil
}