45 lines
1.4 KiB
Go
45 lines
1.4 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"embed"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
_ "github.com/jackc/pgx/v5/stdlib" // pgx/v5 driver for database/sql
|
|
"github.com/pressly/goose/v3"
|
|
)
|
|
|
|
// RunMigrations applies all pending goose migrations from the embedded FS.
|
|
// It uses the pgx/v5/stdlib bridge so that goose's database/sql interface
|
|
// can speak to the same Postgres as the rest of the application.
|
|
//
|
|
// Call RunMigrations once at startup, before constructing the router.
|
|
// goose.Up is idempotent — already-applied migrations are skipped.
|
|
func RunMigrations(ctx context.Context, pool *pgxpool.Pool, migrationsFS embed.FS) error {
|
|
// Extract the DSN from the pool's connection config.
|
|
connConfig := pool.Config().ConnConfig
|
|
dsn := connConfig.ConnString()
|
|
|
|
// Open a database/sql connection for goose. The pgx/v5 stdlib driver is
|
|
// registered by the blank import above.
|
|
sqlDB, err := sql.Open("pgx/v5", dsn)
|
|
if err != nil {
|
|
return fmt.Errorf("migrate: open sql.DB: %w", err)
|
|
}
|
|
sqlDB.SetMaxOpenConns(2) // goose runs sequentially — no need for a large pool
|
|
defer sqlDB.Close()
|
|
|
|
// Point goose at the embedded FS so no on-disk files are needed.
|
|
goose.SetBaseFS(migrationsFS)
|
|
if err := goose.SetDialect("postgres"); err != nil {
|
|
return fmt.Errorf("migrate: set dialect: %w", err)
|
|
}
|
|
|
|
if err := goose.Up(sqlDB, "migrations"); err != nil {
|
|
return fmt.Errorf("migrate: goose up: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|