package db import ( "context" "embed" "fmt" "github.com/golang-migrate/migrate/v4" _ "github.com/golang-migrate/migrate/v4/database/postgres" "github.com/golang-migrate/migrate/v4/source/iofs" "github.com/jackc/pgx/v5/pgxpool" ) //go:embed migrations/*.sql var migrationsFS embed.FS func Connect(ctx context.Context, dsn string) (*pgxpool.Pool, error) { pool, err := pgxpool.New(ctx, dsn) if err != nil { return nil, fmt.Errorf("create pool: %w", err) } if err := pool.Ping(ctx); err != nil { return nil, fmt.Errorf("ping db: %w", err) } return pool, nil } // Migrate führt die eingebetteten Migrationen aus. // // `dsn` ist die postgres://-URL aus config.DSN(). Hier stand früher eine // eigene Umrechnung von key=value in eine URL, die Nutzer und Passwort // unmaskiert hineinschrieb – siehe die Begründung bei config.DSN(). func Migrate(dsn string) error { src, err := iofs.New(migrationsFS, "migrations") if err != nil { return fmt.Errorf("load migrations: %w", err) } m, err := migrate.NewWithSourceInstance("iofs", src, dsn) if err != nil { return fmt.Errorf("init migrate: %w", err) } if err := m.Up(); err != nil && err != migrate.ErrNoChange { return fmt.Errorf("run migrations: %w", err) } return nil }