package database import ( "context" "fmt" "time" "github.com/chorus-services/whoosh/internal/config" "github.com/jackc/pgx/v5/pgxpool" "github.com/rs/zerolog/log" ) type DB struct { Pool *pgxpool.Pool } func NewPostgresDB(cfg config.DatabaseConfig) (*DB, error) { config, err := pgxpool.ParseConfig(cfg.URL) if err != nil { return nil, fmt.Errorf("failed to parse database config: %w", err) } config.MaxConns = int32(cfg.MaxOpenConns) config.MinConns = int32(cfg.MaxIdleConns) config.MaxConnLifetime = time.Hour config.MaxConnIdleTime = time.Minute * 30 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() pool, err := pgxpool.NewWithConfig(ctx, config) if err != nil { return nil, fmt.Errorf("failed to create connection pool: %w", err) } if err := pool.Ping(ctx); err != nil { pool.Close() return nil, fmt.Errorf("failed to ping database: %w", err) } log.Info(). Str("host", cfg.Host). Int("port", cfg.Port). Str("database", cfg.Database). Msg("Connected to PostgreSQL") return &DB{Pool: pool}, nil } func (db *DB) Close() { if db.Pool != nil { db.Pool.Close() log.Info().Msg("Database connection closed") } } func (db *DB) Health(ctx context.Context) error { if err := db.Pool.Ping(ctx); err != nil { return fmt.Errorf("database health check failed: %w", err) } return nil }