concord/internal/infra/db/db.go
2025-10-24 02:26:24 +03:00

60 lines
1.3 KiB
Go

package db
import (
"context"
"fmt"
"time"
"github.com/Alexander-D-Karpov/concord/internal/common/config"
"github.com/jackc/pgx/v5/pgxpool"
)
type DB struct {
Pool *pgxpool.Pool
}
func New(cfg config.DatabaseConfig) (*DB, error) {
dsn := fmt.Sprintf(
"host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.Database,
)
poolConfig, err := pgxpool.ParseConfig(dsn)
if err != nil {
return nil, fmt.Errorf("parse pool config: %w", err)
}
poolConfig.MaxConns = int32(cfg.MaxConns)
poolConfig.MinConns = int32(cfg.MinConns)
poolConfig.MaxConnLifetime = cfg.MaxConnLifetime
poolConfig.MaxConnIdleTime = cfg.MaxConnIdleTime
poolConfig.HealthCheckPeriod = 1 * time.Minute
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
pool, err := pgxpool.NewWithConfig(ctx, poolConfig)
if err != nil {
return nil, fmt.Errorf("create pool: %w", err)
}
if err := pool.Ping(ctx); err != nil {
pool.Close()
return nil, fmt.Errorf("ping database: %w", err)
}
return &DB{Pool: pool}, nil
}
func (d *DB) Close() {
if d.Pool != nil {
d.Pool.Close()
}
}
func (d *DB) Health(ctx context.Context) error {
ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
return d.Pool.Ping(ctx)
}