package database import ( "context" "log/slog" "github.com/jackc/pgx/v5/pgxpool" "git.unkin.net/unkin/golib/pg" "git.unkin.net/unkin/forgebot/migrations" ) // migrationLockName names the cluster-wide advisory lock the migration run // contends for. golib derives the key as FNV-1a/64 of this name, so every // replica must pass the same string to stay mutually exclusive. const migrationLockName = "forgebot-migrations" type DB struct { Pool *pgxpool.Pool } // New opens the pool and brings the schema up to date before returning, so the // API never serves against a half-migrated database. log may be nil. func New(ctx context.Context, dsn string, log *slog.Logger) (*DB, error) { pool, err := pg.NewMigrated(ctx, dsn, migrations.FS, pg.MigrateOptions{ LockName: migrationLockName, Logger: log, }) if err != nil { return nil, err } return &DB{Pool: pool}, nil } func (db *DB) Close() { db.Pool.Close() } func (db *DB) Healthy(ctx context.Context) bool { return db.Pool.Ping(ctx) == nil }