148 lines
4.4 KiB
JavaScript
148 lines
4.4 KiB
JavaScript
// poolSingleton.mjs
|
|
// Conexión Singleton a base de datos (pg/Pool) para CORE y TENANTS.
|
|
// Cambios mínimos respecto a tu versión original.
|
|
|
|
import { Pool } from 'pg';
|
|
|
|
// Utilidad mínima para booleans
|
|
const isTrue = (v) => String(v).toLowerCase() === 'true';
|
|
|
|
// --------------------- CORE ---------------------
|
|
class DatabaseCore {
|
|
static instance = null;
|
|
|
|
constructor() {
|
|
if (DatabaseCore.instance) {
|
|
return DatabaseCore.instance; // <-- corrección: antes devolvía Database.instance
|
|
}
|
|
|
|
const host = process.env.CORE_DB_HOST;
|
|
const user = process.env.CORE_DB_USER;
|
|
const password = process.env.CORE_DB_PASS;
|
|
const database = process.env.CORE_DB_NAME;
|
|
const port = process.env.CORE_DB_PORT;
|
|
const ssl =
|
|
isTrue(process.env.CORE_PGSSL ?? process.env.PGSSL)
|
|
? { rejectUnauthorized: false }
|
|
: undefined;
|
|
|
|
const config = {
|
|
host,
|
|
user,
|
|
password,
|
|
database,
|
|
port: port ? Number(port) : undefined,
|
|
ssl,
|
|
};
|
|
|
|
this.host = host;
|
|
this.dbName = database;
|
|
this.connection = new Pool(config);
|
|
|
|
DatabaseCore.instance = this;
|
|
}
|
|
|
|
async query(sql, params) {
|
|
return this.connection.query(sql, params);
|
|
}
|
|
|
|
async connect() { // idempotente a nivel de pool; retorna un client
|
|
return this.connection.connect();
|
|
}
|
|
|
|
async getClient() { // alias simple, conserva tu API
|
|
return this.connection.connect();
|
|
}
|
|
|
|
async release() { // cierra TODO el pool (uso excepcional)
|
|
await this.connection.end();
|
|
}
|
|
}
|
|
|
|
// --------------------- TENANTS ---------------------
|
|
class DatabaseTenants {
|
|
static instance = null;
|
|
|
|
constructor() {
|
|
if (DatabaseTenants.instance) {
|
|
return DatabaseTenants.instance; // <-- corrección: antes devolvía Database.instance
|
|
}
|
|
|
|
const host = process.env.TENANTS_DB_HOST;
|
|
const user = process.env.TENANTS_DB_USER;
|
|
const password = process.env.TENANTS_DB_PASS;
|
|
const database = process.env.TENANTS_DB_NAME;
|
|
const port = process.env.TENANTS_DB_PORT;
|
|
const ssl =
|
|
isTrue(process.env.TENANTS_PGSSL ?? process.env.PGSSL)
|
|
? { rejectUnauthorized: false }
|
|
: undefined;
|
|
|
|
const config = {
|
|
host,
|
|
user,
|
|
password,
|
|
database,
|
|
port: port ? Number(port) : undefined,
|
|
ssl,
|
|
};
|
|
|
|
this.host = host;
|
|
this.dbName = database;
|
|
this.connection = new Pool(config);
|
|
|
|
DatabaseTenants.instance = this;
|
|
}
|
|
|
|
async query(sql, params) {
|
|
return this.connection.query(sql, params);
|
|
}
|
|
|
|
async connect() { // idempotente a nivel de pool; retorna un client
|
|
return this.connection.connect();
|
|
}
|
|
|
|
async getClient() { // alias simple, conserva tu API
|
|
return this.connection.connect();
|
|
}
|
|
|
|
async release() { // cierra TODO el pool (uso excepcional)
|
|
await this.connection.end();
|
|
}
|
|
}
|
|
|
|
// Instancias únicas por el cache de módulos de Node/ESM + guardas estáticas
|
|
const poolCore = new DatabaseCore();
|
|
const poolTenants = new DatabaseTenants();
|
|
|
|
// --------------------- Healthchecks aquí dentro ---------------------
|
|
async function verificarConexionCore() {
|
|
try {
|
|
console.log(`[ PG ] Comprobando accesibilidad a la db ${poolCore.dbName} del host ${poolCore.host} ...`);
|
|
const client = await poolCore.getClient();
|
|
const { rows } = await client.query('SELECT NOW() AS ahora');
|
|
console.log(`[ PG ] Conexión con ${poolCore.dbName} OK. Hora DB:`, rows[0].ahora);
|
|
client.release();
|
|
} catch (error) {
|
|
console.error('[ PG ] Error al conectar con la base de datos al iniciar:', error.message);
|
|
console.error('[ PG ] Revisar credenciales, accesos de red y firewall.');
|
|
}
|
|
}
|
|
|
|
async function verificarConexionTenants() {
|
|
try {
|
|
console.log(`[ PG ] Comprobando accesibilidad a la db ${poolTenants.dbName} del host ${poolTenants.host} ...`);
|
|
const client = await poolTenants.getClient();
|
|
const { rows } = await client.query('SELECT NOW() AS ahora');
|
|
console.log(`[ PG ] Conexión con ${poolTenants.dbName} OK. Hora DB:`, rows[0].ahora);
|
|
client.release();
|
|
} catch (error) {
|
|
console.error('[ PG ] Error al conectar con la base de datos al iniciar:', error.message);
|
|
console.error('[ PG ] Revisar credenciales, accesos de red y firewall.');
|
|
}
|
|
}
|
|
|
|
// Exports (mantengo tu patrón)
|
|
export default { poolCore, poolTenants, verificarConexionCore, verificarConexionTenants };
|
|
export { poolCore, poolTenants, verificarConexionCore, verificarConexionTenants };
|
|
// export { DatabaseCore, DatabaseTenants }; // si lo necesitás para tests
|