2025-10-15 10:43:58 -04:00

64 lines
1.5 KiB
Go

package config
import (
"fmt"
"log"
"sync"
"time"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var (
db *gorm.DB
once sync.Once
dbErr error
)
// GetDB retorna la conexión a la base de datos
func GetDatabaseConnection(cfg *Config) *gorm.DB {
once.Do(func() {
dsn := fmt.Sprintf(
"host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
cfg.DBHost, cfg.DBPort, cfg.DBUser, cfg.DBPassword, cfg.DBName,
)
// Reintentos automáticos
maxRetries := 3
for i := 0; i < maxRetries; i++ {
db, dbErr = gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
})
if dbErr == nil {
break
}
log.Printf("⚠️ Intento %d de conexión fallido: %v", i+1, dbErr)
time.Sleep(2 * time.Second)
}
if dbErr != nil {
log.Fatalf("❌ No se pudo conectar a la BD después de varios intentos: %v", dbErr)
}
// Configuración del pool
sqlDB, err := db.DB()
if err != nil {
log.Fatalf("❌ Error al obtener objeto SQL: %v", err)
}
// Validación inmediata
if err := sqlDB.Ping(); err != nil {
log.Fatalf("❌ Error al hacer ping a la BD: %v", err)
}
sqlDB.SetMaxOpenConns(cfg.DBMaxOpenConns) // Conexiones máximas
sqlDB.SetMaxIdleConns(cfg.DBMaxIdleConns) // Conexiones inactivas permitidas
sqlDB.SetConnMaxLifetime(cfg.DBConnMaxLifetime * time.Minute) // Tiempo máximo de vida
log.Println("✅ Conexión a la BD establecida correctamente")
})
return db
}