This commit is contained in:
Lizandro Guarnizo
2026-05-01 13:44:37 -05:00
parent be28fea806
commit 3f6eb7dddc
7 changed files with 191 additions and 12 deletions
+24 -5
View File
@@ -1,6 +1,7 @@
package services
import (
"context"
"database/sql"
"fmt"
"strings"
@@ -14,6 +15,9 @@ import (
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
)
// connTimeout es el tiempo máximo para establecer una conexión a la DB externa.
const connTimeout = 8 * time.Second
// QueryResult contiene el resultado de una consulta SQL.
type QueryResult struct {
Columns []string `json:"columns"`
@@ -39,16 +43,16 @@ func openDynamicDB(c models.ConxDb) (*sql.DB, error) {
switch {
case strings.Contains(driver, "postgres"):
driverName = "postgres"
dsn = fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable", host, port, user, pass)
dsn = fmt.Sprintf("host=%s port=%s user=%s password=%s sslmode=disable connect_timeout=8", host, port, user, pass)
case strings.Contains(driver, "mysql") || strings.Contains(driver, "mariadb"):
driverName = "mysql"
dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/", user, pass, host, port)
dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/?timeout=8s&readTimeout=20s&writeTimeout=20s", user, pass, host, port)
case strings.Contains(driver, "sqlite"):
driverName = "sqlite3"
dsn = host // para sqlite el host es la ruta del archivo
case strings.Contains(driver, "sqlserver") || strings.Contains(driver, "mssql"):
driverName = "sqlserver"
dsn = fmt.Sprintf("sqlserver://%s:%s@%s:%s", user, pass, host, port)
dsn = fmt.Sprintf("sqlserver://%s:%s@%s:%s?dial+timeout=8", user, pass, host, port)
default:
return nil, fmt.Errorf("driver no soportado: %s", driver)
}
@@ -59,6 +63,13 @@ func openDynamicDB(c models.ConxDb) (*sql.DB, error) {
}
db.SetConnMaxLifetime(30 * time.Second)
db.SetMaxOpenConns(2)
// Verificar conectividad inmediatamente para fallar rápido en lugar de bloquear al hacer la primera query
ctx, cancel := context.WithTimeout(context.Background(), connTimeout)
defer cancel()
if err := db.PingContext(ctx); err != nil {
db.Close()
return nil, fmt.Errorf("no se pudo conectar al servidor de base de datos: %w", err)
}
return db, nil
}
@@ -169,7 +180,9 @@ func ListDatabases(conx models.ConxDb) ([]string, error) {
return []string{"main"}, nil
}
rows, err := db.Query(query)
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
rows, err := db.QueryContext(ctx, query)
if err != nil {
return nil, err
}
@@ -253,13 +266,19 @@ func openDynamicDBWithName(c models.ConxDb, dbName string) (*sql.DB, error) {
var dsn string
switch {
case strings.Contains(driver, "postgres"):
dsn = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", host, port, user, pass, dbName)
dsn = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable connect_timeout=8", host, port, user, pass, dbName)
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, err
}
db.SetConnMaxLifetime(30 * time.Second)
db.SetMaxOpenConns(2)
ctx, cancel := context.WithTimeout(context.Background(), connTimeout)
defer cancel()
if err := db.PingContext(ctx); err != nil {
db.Close()
return nil, fmt.Errorf("no se pudo conectar a la base de datos '%s': %w", dbName, err)
}
return db, nil
default:
return openDynamicDB(c)
+1 -1
View File
@@ -291,7 +291,7 @@ func obtenerEnlaceBold(contrato *models.Contrato) string {
},
Description: desc,
Reference: fmt.Sprintf("contrato-%d", contrato.ID),
CallbackURL: cfg.CallbackUrl,
CallbackURL: cfg.CallbackUrl + fmt.Sprintf("?ref=contrato-%d", contrato.ID),
}
result, err := CreateBoldPaymentLink(cfg, req)