@minervajs/helmet 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2024, 2025, Alexander Enrique Escobar O.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # MinervaJS-Helmet
2
+
3
+ ## 🛡️ Descripción
4
+
5
+ **MinervaJS-Helmet** es el módulo encargado de la **gestión unificada de conexiones y operaciones de base de datos** dentro del ecosistema **MinervaJS**.
6
+
7
+ Su función principal es abstraer el motor de base de datos (MySQL, PostgreSQL, Oracle, etc.) y exponer una **API homogénea**, permitiendo que el resto del sistema funcione de forma **JSON-driven**, desacoplada y extensible.
8
+
9
+ ---
10
+
11
+ ## 🎯 Objetivos
12
+
13
+ * Centralizar la gestión de conexiones a bases de datos
14
+ * Soportar múltiples motores de forma transparente
15
+ * Proveer una API común para:
16
+
17
+ * Consultas de lectura (SELECT)
18
+ * Operaciones de escritura (INSERT / UPDATE / DELETE / DDL)
19
+ * Procedimientos almacenados
20
+ * Facilitar la construcción de backends genéricos y dinámicos
21
+
22
+ ---
23
+
24
+ ## 🧱 Arquitectura
25
+
26
+ ```
27
+ MinervaJS
28
+ └── Helmet
29
+ ├── db_mysql.js
30
+ ├── db_postgres.js
31
+ ├── db_oracle.js
32
+ └── connections (cache interno)
33
+ ```
34
+
35
+ Helmet actúa como un **dispatcher**, delegando la ejecución a proveedores específicos que implementan un contrato estándar.
36
+
37
+ ---
38
+
39
+ ## 🔌 Contrato estándar de proveedores
40
+
41
+ Cada proveedor de base de datos debe implementar las siguientes funciones:
42
+
43
+ ```js
44
+ connect(config)
45
+ query(connection, sql, params = [])
46
+ execute(connection, sql, params = [])
47
+ call(connection, procedureName, params = {})
48
+ close(connection)
49
+ closeAll(config)
50
+ ```
51
+
52
+ Este contrato garantiza que Helmet pueda operar sin conocer los detalles del motor subyacente.
53
+
54
+ ---
55
+
56
+ ## 📦 Instalación
57
+
58
+ ```bash
59
+ npm install @minervajs/helmet
60
+ ```
61
+ ⚠️ Previous name: minervajs-helmet (deprecated)
62
+ > *(o incluir el módulo directamente dentro del proyecto MinervaJS)*
63
+
64
+ ---
65
+
66
+ ## ⚙️ Configuración de base de datos
67
+
68
+ Ejemplo de archivo `database.json`:
69
+
70
+ ```json
71
+ {
72
+ "mysqlMain": {
73
+ "type": "mysql",
74
+ "host": "localhost",
75
+ "port": 3306,
76
+ "user": "user",
77
+ "password": "password",
78
+ "database": "minerva"
79
+ }
80
+ }
81
+ ```
82
+
83
+ En la instalacion, puedes hacer uso del archivo muestra que esta en *\node_modules\minervajs-helmet\example\settings.js*
84
+
85
+ ---
86
+
87
+ ## 🚀 Uso básico
88
+
89
+ ```js
90
+ const helmet = require('./helmet');
91
+ const config = require('./database.json');
92
+ ```
93
+
94
+ ---
95
+
96
+ ### 🔍 Consultas de lectura (SELECT)
97
+
98
+ ```js
99
+ const rows = await helmet.query(
100
+ 'mysqlMain',
101
+ 'SELECT * FROM pais WHERE iso3 = ?',
102
+ ['SLV'],
103
+ config
104
+ );
105
+ ```
106
+
107
+ ---
108
+
109
+ ### ✏️ Operaciones de escritura
110
+
111
+ ```js
112
+ const result = await helmet.execute(
113
+ 'mysqlMain',
114
+ 'UPDATE pais SET nombre = ? WHERE iso3 = ?',
115
+ ['El Salvador', 'SLV'],
116
+ config
117
+ );
118
+
119
+ console.log(result.rowsAffected);
120
+ ```
121
+
122
+ ---
123
+
124
+ ### 🧠 Procedimientos almacenados
125
+
126
+ ```js
127
+ const result = await helmet.call(
128
+ 'mysqlMain',
129
+ 'sp_pais_insert',
130
+ {
131
+ p_iso3: 'SLV',
132
+ p_nombre: 'El Salvador',
133
+ p_leyenda: 'Centroamérica',
134
+ p_iso2: 'SV',
135
+ p_existe: { out: true }
136
+ },
137
+ config
138
+ );
139
+ ```
140
+
141
+ **Resultado estándar:**
142
+
143
+ ```js
144
+ {
145
+ resultSets: [...],
146
+ out: {
147
+ p_existe: 0
148
+ }
149
+ }
150
+ ```
151
+
152
+ ---
153
+
154
+ ## 🔐 Gestión de conexiones
155
+
156
+ * Una conexión por perfil de base de datos
157
+ * Reutilización automática
158
+ * Cache interno
159
+ * Cierre explícito
160
+
161
+ ```js
162
+ await helmet.close('mysqlMain', config);
163
+ await helmet.closeAll(config);
164
+ ```
165
+
166
+ ---
167
+
168
+ ## ⚠️ Manejo de errores
169
+
170
+ Helmet agrega contexto a los errores:
171
+
172
+ ```
173
+ [Helmet][mysql][execute] Duplicate entry
174
+ ```
175
+
176
+ Esto facilita el logging y el diagnóstico.
177
+
178
+ ---
179
+
180
+ ## 🧩 Integración JSON-driven (MinervaJS)
181
+
182
+ Helmet está diseñado para ejecutarse a partir de manifiestos JSON:
183
+
184
+ ```json
185
+ {
186
+ "database": "mysqlMain",
187
+ "procedure": "sp_pais_insert",
188
+ "params": {
189
+ "p_iso3": "$body.iso3",
190
+ "p_nombre": "$body.nombre",
191
+ "p_existe": { "out": true }
192
+ }
193
+ }
194
+ ```
195
+
196
+ La API ejecuta la operación sin conocer SQL ni lógica de negocio.
197
+
198
+ ---
199
+
200
+ ## ✅ Buenas prácticas
201
+
202
+ * Usar `query()` exclusivamente para SELECT
203
+ * Usar `execute()` para DML / DDL
204
+ * Encapsular lógica compleja en Stored Procedures
205
+ * Cerrar conexiones en shutdown de la aplicación
206
+ * Mantener la configuración desacoplada
207
+
208
+
209
+ ---
210
+
211
+ ## 🔮 Evolución futura
212
+
213
+ * Pooling de conexiones
214
+ * Transacciones (`begin / commit / rollback`)
215
+ * Multi-tenant
216
+ * Logging estructurado
217
+ * Métricas
218
+ * Soporte para nuevos motores
219
+
220
+ ---
221
+
222
+ ## 📌 Conclusión
223
+
224
+ **MinervaJS-Helmet** es el pilar de acceso a datos de MinervaJS.
225
+
226
+ Su diseño modular, homogéneo y desacoplado permite construir aplicaciones dinámicas, escalables y mantenibles, donde la lógica de negocio puede definirse de forma declarativa y evolucionar sin reescribir el backend.
227
+
228
+
229
+
230
+
231
+
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @module
3
+ * @name settings
4
+ * @description Modulo gestor de la coneccion a la base de datos
5
+ * Configuracion de la Base de Datos
6
+ *
7
+ * Se incluye un ejemplo de uso, segun el tipo de base de datos
8
+ */
9
+ exports.httpMsgFormat = 'HTML';
10
+ exports.Title = "MinervaJS - Helmet";
11
+ exports.Rights_Reserved = "2023-2025 © A&C Consultoría Informática";
12
+
13
+ module.exports = {
14
+ /*
15
+ * 'mi_postgres':
16
+ * {
17
+ * type: 'postgres',
18
+ * host: 'localhost o IP',
19
+ * port: 5432,
20
+ * user: 'usuario',
21
+ * password: 'contraseña',
22
+ * database: 'nombre_db'
23
+ * },
24
+ */
25
+ 'my_mysql':
26
+ {
27
+ type: 'mysql',
28
+ host: 'sql3.freesqldatabase.com', // 'localhost',
29
+ port: 3306, // 'puerto',
30
+ user: 'sql3772729', // 'usuario',
31
+ password: 'esUA3qpGKD', // 'contraseña',
32
+ database: 'sql3772729' // 'nombre_db'
33
+ },
34
+ /* 'my_oracle': {
35
+ * type: 'oracle',
36
+ * user: 'usuario',
37
+ * password: 'contraseña',
38
+ * connectString : '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=namehostoip)(PORT=port))(CONNECT_DATA=(SERVICE_NAME=servicename)))'
39
+ * },
40
+ * 'mi_mongodb': {
41
+ * type: 'mongodb',
42
+ * url: 'mongodb://localhost:27017/nombre_db'
43
+ * },
44
+ * 'mi_mariadb': {
45
+ * type: 'mariadb',
46
+ * host: 'localhost',
47
+ * port: 3306,
48
+ * user: 'mi_usuario',
49
+ * password: 'mi_contraseña',
50
+ * database: 'nombre_db'
51
+ * }
52
+ */
53
+ };
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @module lib/mariadb
3
+ * @description Módulo para la conexión y operaciones de MariaDB.
4
+ */
5
+
6
+ /**
7
+ * @constant
8
+ * @type {string}
9
+ * @default
10
+ */
11
+ const mariadb = require('mariadb/promise');
12
+
13
+ /**
14
+ * Establece una conexión a la base de datos MariaDB.
15
+ *
16
+ * @async
17
+ * @function connect
18
+ * @param {object} config - Configuración de la conexión.
19
+ * @returns {Promise<mariadb.Connection>} Objeto de conexión de MariaDB.
20
+ */
21
+ async function connect(config) {
22
+ try {
23
+ const connection = await mariadb.createConnection(config);
24
+ return connection;
25
+ } catch (error) {
26
+ console.error('Error al conectar a MariaDB:', error);
27
+ throw error;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Ejecuta una consulta SQL en la base de datos MariaDB.
33
+ *
34
+ * @async
35
+ * @function query
36
+ * @param {mariadb.Connection} connection - Objeto de conexión de MariaDB.
37
+ * @param {string} sql - Consulta SQL.
38
+ * @param {Array} [values] - Parámetros para la consulta.
39
+ * @returns {Promise<Array>} Filas resultantes de la consulta.
40
+ */
41
+ async function query(connection, sql, values = []) {
42
+ try {
43
+ const rows = await connection.query(sql, values);
44
+ return rows;
45
+ } catch (error) {
46
+ console.error('Error al ejecutar la consulta MariaDB:', error);
47
+ throw error;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Cierra la conexión a la base de datos MariaDB.
53
+ *
54
+ * @async
55
+ * @function close
56
+ * @param {mariadb.Connection} connection - Objeto de conexión de MariaDB.
57
+ * @returns {Promise<void>}
58
+ */
59
+ async function close(connection) {
60
+ try {
61
+ await connection.end();
62
+ } catch (error) {
63
+ console.error('Error al cerrar la conexión MariaDB:', error);
64
+ throw error;
65
+ }
66
+ }
67
+
68
+ module.exports = { connect, query, close };
69
+
@@ -0,0 +1,49 @@
1
+ const { MongoClient } = require('mongodb');
2
+
3
+ /**
4
+ * @module lib/mongodb
5
+ * @description Módulo para la conexión y operaciones de MongoDB. Comando: npm install mongodb
6
+ */
7
+
8
+ /**
9
+ * Establece una conexión a la base de datos MongoDB.
10
+ *
11
+ * @async
12
+ * @function connect
13
+ * @param {object} config - Configuración de la conexión.
14
+ * @returns {Promise<MongoClient>} Objeto de cliente de MongoDB.
15
+ */
16
+ async function connect(config) {
17
+ try {
18
+ const client = new MongoClient(config.url);
19
+ await client.connect();
20
+ return client;
21
+ } catch (error) {
22
+ console.error('Error al conectar a MongoDB:', error);
23
+ throw error;
24
+ }
25
+ }
26
+
27
+
28
+ // query
29
+ // logica
30
+
31
+
32
+ /**
33
+ * Cierra la conexión a la base de datos MongoDB.
34
+ *
35
+ * @async
36
+ * @function close
37
+ * @param {MongoClient} client - Objeto de cliente de MongoDB.
38
+ * @returns {Promise<void>}
39
+ */
40
+ async function close(client) {
41
+ try {
42
+ await client.close();
43
+ } catch (error) {
44
+ console.error('Error al cerrar la conexión MongoDB:', error);
45
+ throw error;
46
+ }
47
+ }
48
+
49
+ module.exports = { connect, close };
package/js/db_mysql.js ADDED
@@ -0,0 +1,162 @@
1
+ /**
2
+ * @module js/mysql
3
+ * @name Provider DB js/mysql
4
+ * @description Módulo proveedor MySQL para MinervaJS-Helmet.
5
+ * Implementa operaciones estándar: query, execute y call.
6
+ *
7
+ */
8
+
9
+ /**
10
+ * @constant
11
+ * @type {string}
12
+ * @default
13
+ */
14
+ const mysql = require('mysql2/promise'); // Usamos mysql2/promise para async/await
15
+
16
+ /**
17
+ * Establece una conexión a la base de datos MySQL.
18
+ *
19
+ * @async
20
+ * @function connect
21
+ * @param {object} config - Configuración de la conexión.
22
+ * @returns {Promise<mysql.Connection>} Objeto de conexión de MySQL.
23
+ */
24
+ async function connect(config)
25
+ {
26
+ try
27
+ {
28
+ const connection = await mysql.createConnection({
29
+ host: config.host,
30
+ port: config.port,
31
+ user: config.user,
32
+ password: config.password,
33
+ database: config.database,
34
+ });
35
+ return connection;
36
+ }
37
+ catch (error)
38
+ {
39
+ console.error('[MySQL][connect]', error.message);
40
+ throw error; // Re-lanzamos el error para que sea manejado por el llamador
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Ejecuta una consulta SQL en la base de datos MySQL.
46
+ *
47
+ * @async
48
+ * @function query
49
+ * @param {mysql.Connection} connection - Objeto de conexión de MySQL.
50
+ * @param {string} sql - Consulta SQL.
51
+ * @param {Array} [params] - Parámetros para la consulta.
52
+ * @returns {Promise<Array>} Filas resultantes de la consulta.
53
+ */
54
+ async function query(connection, sql, params = [])
55
+ {
56
+ try
57
+ {
58
+ const [rows, fields] = await connection.execute(sql, params);
59
+ return rows;
60
+ }
61
+ catch (error)
62
+ {
63
+ console.error('[MySQL][query]', error.message);
64
+ throw error;
65
+ }
66
+ }
67
+
68
+
69
+
70
+ /**
71
+ * Ejecuta una sentencia de escritura (INSERT, UPDATE, DELETE, DDL).
72
+ */
73
+ async function execute(connection, sql, params = [])
74
+ {
75
+ try {
76
+ const [result] = await connection.execute(sql, params);
77
+
78
+ return {
79
+ rowsAffected: result.affectedRows,
80
+ insertId: result.insertId || null
81
+ };
82
+ }
83
+ catch (error)
84
+ {
85
+ console.error('[MySQL][execute]', error.message);
86
+ throw error;
87
+ }
88
+ }
89
+
90
+
91
+ /**
92
+ * Ejecuta un procedimiento almacenado.
93
+ *
94
+ * Nota:
95
+ * MySQL maneja OUT params mediante variables de sesión (@var).
96
+ */
97
+ async function call(connection, procedureName, params = {}) {
98
+ try {
99
+ const keys = Object.keys(params);
100
+ const values = [];
101
+
102
+ const placeholders = keys.map(key => {
103
+ if (params[key]?.out) {
104
+ return `@${key}`;
105
+ }
106
+ values.push(params[key]);
107
+ return '?';
108
+ }).join(',');
109
+
110
+ // 1️ - Ejecutar CALL
111
+ const callSQL = `CALL ${procedureName}(${placeholders})`;
112
+ const [resultSets] = await connection.query(callSQL, values);
113
+
114
+ // 2️ - Recuperar OUT params
115
+ const outParams = keys.filter(k => params[k]?.out);
116
+ let out = {};
117
+
118
+ if (outParams.length > 0) {
119
+ const selectOut = `SELECT ${outParams.map(k => `@${k} AS ${k}`).join(',')}`;
120
+ const [rows] = await connection.query(selectOut);
121
+ out = rows[0];
122
+ }
123
+
124
+ return {
125
+ resultSets,
126
+ out
127
+ };
128
+ } catch (error) {
129
+ console.error('[MySQL][call]', error.message);
130
+ throw error;
131
+ }
132
+ }
133
+
134
+
135
+
136
+ /**
137
+ * Cierra la conexión a la base de datos MySQL.
138
+ *
139
+ * @async
140
+ * @function close
141
+ * @param {mysql.Connection} connection - Objeto de conexión de MySQL.
142
+ * @returns {Promise<void>}
143
+ */
144
+ async function close(connection)
145
+ {
146
+ try
147
+ { await connection.end(); }
148
+ catch (error)
149
+ {
150
+ console.error('[MySQL][close]', error.message);
151
+ throw error;
152
+ }
153
+ }
154
+
155
+ module.exports =
156
+ {
157
+ connect,
158
+ query,
159
+ execute,
160
+ call,
161
+ close
162
+ };
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @module js/oracle
3
+ * @name Provider DB js/oracle
4
+ * @description Módulo para la conexión y operaciones de Oracle.
5
+ */
6
+
7
+ /**
8
+ * @constant
9
+ * @type {string}
10
+ * @default
11
+ */
12
+ const oracledb = require('oracledb');
13
+
14
+
15
+ /**
16
+ * Establece una conexión a la base de datos Oracle.
17
+ *
18
+ * @async
19
+ * @function connect
20
+ * @param {object} config - Configuración de la conexión.
21
+ * @returns {Promise<oracledb.Connection>} Objeto de conexión de Oracle.
22
+ */
23
+ async function connect(config) {
24
+ try {
25
+ oracledb.outFormat = oracledb.OUT_FORMAT_OBJECT; // Para obtener resultados como objetos
26
+
27
+ const connection = await oracledb.getConnection({
28
+ user: config.user,
29
+ password: config.password,
30
+ connectString: config.connectString, // Ejemplo: 'localhost/XE' o una cadena de conexión TNS
31
+ });
32
+ return connection;
33
+ } catch (error) {
34
+ console.error('Error al conectar a Oracle:', error);
35
+ throw error;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Ejecuta una consulta SQL en la base de datos Oracle.
41
+ *
42
+ * @async
43
+ * @function query
44
+ * @param {oracledb.Connection} connection - Objeto de conexión de Oracle.
45
+ * @param {string} sql - Consulta SQL.
46
+ * @param {Array} [binds] - Parámetros para la consulta (bind variables).
47
+ * @returns {Promise<Array>} Filas resultantes de la consulta.
48
+ */
49
+ async function query(connection, sql, binds = []) {
50
+ try {
51
+ const result = await connection.execute(sql, binds);
52
+ return result.rows;
53
+ } catch (error) {
54
+ console.error('Error al ejecutar la consulta Oracle:', error);
55
+ throw error;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Cierra la conexión a la base de datos Oracle.
61
+ *
62
+ * @async
63
+ * @function close
64
+ * @param {oracledb.Connection} connection - Objeto de conexión de Oracle.
65
+ * @returns {Promise<void>}
66
+ */
67
+ async function close(connection) {
68
+ try {
69
+ await connection.close();
70
+ } catch (error) {
71
+ console.error('Error al cerrar la conexión Oracle:', error);
72
+ throw error;
73
+ }
74
+ }
75
+
76
+ module.exports = { connect, query, close };
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @module js/postgres
3
+ * @name Provider DB js/postgres
4
+ * @description Módulo para la conexión y operaciones del Proveedor PostgreSQL.
5
+ */
6
+
7
+ /**
8
+ * @constant
9
+ * @type {string}
10
+ * @default
11
+ */
12
+ const { Client } = require('pg');
13
+
14
+ /**
15
+ * Establece una conexión a la base de datos PostgreSQL.
16
+ *
17
+ * @async
18
+ * @function connect
19
+ * @name connect
20
+ * @param {object} config - Configuración de la conexión.
21
+ * @returns {Promise<Client>} Objeto de cliente de PostgreSQL.
22
+ */
23
+ async function connect(config)
24
+ {
25
+ const client = new Client(config);
26
+ await client.connect();
27
+ return client;
28
+ }
29
+
30
+ /**
31
+ * Ejecuta una consulta SQL en la base de datos PostgreSQL.
32
+ *
33
+ * @async
34
+ * @function query
35
+ * @name query
36
+ * @param {Client} client - Objeto de cliente de PostgreSQL.
37
+ * @param {string} sql - Consulta SQL.
38
+ * @returns {Promise<Array>} Filas resultantes de la consulta.
39
+ */
40
+ async function query(client, sql)
41
+ {
42
+ const result = await client.query(sql);
43
+ return result.rows;
44
+ }
45
+
46
+ /**
47
+ * Cierra la conexión a la base de datos PostgreSQL.
48
+ *
49
+ * @async
50
+ * @function close
51
+ * @name close
52
+ * @param {Client} client - Objeto de cliente de PostgreSQL.
53
+ * @returns {Promise<void>}
54
+ */
55
+ async function close(client)
56
+ {
57
+ await client.end();
58
+ }
59
+
60
+ module.exports = { connect, query, close };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@minervajs/helmet",
3
+ "version": "1.0.0",
4
+ "main": "src/db.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1"
7
+ },
8
+ "keywords": [
9
+ "DB",
10
+ "Multi DataBase",
11
+ "connect",
12
+ "MySQL",
13
+ "Oracle Client",
14
+ "PostGres",
15
+ "MinervaJS"
16
+ ],
17
+ "author": "alexander.enrique.escobar@gmail.com",
18
+ "license": "BSD-2-Clause",
19
+ "description": "Modulo para la gestion de coneccion a la base de datos, de diferentes tipos mediante el uso de sobre Carga y Herencia de clases",
20
+ "dependencies": {
21
+ "mysql2": "^3.14.0",
22
+ "oracledb": "^6.6.0",
23
+ "pg": "^8.14.1"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/Alexander-Escobar/MinervaJS.Helmet.git"
28
+ },
29
+ "bug": {
30
+ "url": "https://github.com/Alexander-Escobar/MinervaJS.Helmet.git/issues"
31
+ },
32
+ "homepage": "https://github.com/Alexander-Escobar/MinervaJS.Helmet.git#readme"
33
+ }
package/src/db.js ADDED
@@ -0,0 +1,246 @@
1
+ /**
2
+ *
3
+ * @name MinervaJS-Helmet
4
+ * @module MinervaJS-Helmet
5
+ * @description Gestor unificado de conexiones y ejecución de operaciones en múltiples motores de bases de datos.
6
+ */
7
+
8
+ const postgres = require('../js/db_postgres');
9
+ const mysql = require('../js/db_mysql');
10
+ const oracle = require('../js/db_oracle');
11
+ // const mongodb = require('./lib/mongodb');
12
+ // const mariadb = require('./lib/mariadb');
13
+
14
+ const connections = {};
15
+
16
+ /**
17
+ * Establece una conexión a la base de datos especificada.
18
+ *
19
+ * @async
20
+ * @function connect
21
+ * @name connect
22
+ * @param {string} databaseName - Perfil de la base de datos (clave de configuración)
23
+ * @returns {Promise<object>} Objeto de conexión.
24
+ * @throws {Error} Si la configuración no se encuentra o el tipo de base de datos no es soportado.
25
+ * @description Toma la configuracion y Establece una conexión a la base de datos especificada
26
+ */
27
+ async function connect(databaseName, config)
28
+ {
29
+ const dbConfig = config[databaseName];
30
+
31
+ if (!dbConfig)
32
+ { throw new Error(`Configuración de base de datos '${databaseName}' no encontrada.`); }
33
+
34
+ // Ya existe una conexión
35
+ if (connections[databaseName])
36
+ { return connections[databaseName]; }
37
+
38
+ switch (dbConfig.type)
39
+ {
40
+ case 'postgres':
41
+ connections[databaseName] = await postgres.connect(dbConfig);
42
+ break;
43
+ case 'mysql':
44
+ connections[databaseName] = await mysql.connect(dbConfig);
45
+ break;
46
+ // case 'mariadb':
47
+ // connections[databaseName] = await mariadb.connect(dbConfig);
48
+ // break;
49
+ case 'oracle':
50
+ connections[databaseName] = await oracle.connect(dbConfig);
51
+ break;
52
+ // case 'mongodb':
53
+ // connections[databaseName] = await mongodb.connect(dbConfig);
54
+ // break;
55
+ default:
56
+ throw new Error(`Tipo de base de datos '${dbConfig.type}' no soportado.`);
57
+ }
58
+
59
+ return connections[databaseName];
60
+ }
61
+
62
+
63
+ /**
64
+ * Dispatcher interno para query / execute / call
65
+ */
66
+ async function run(databaseName, target, params, config, mode)
67
+ {
68
+ const connection = await connect(databaseName, config);
69
+ const dbConfig = config[databaseName];
70
+
71
+ try {
72
+ switch (dbConfig.type) {
73
+ case 'postgres':
74
+ return await postgres[mode](connection, target, params);
75
+
76
+ case 'mysql':
77
+ return await mysql[mode](connection, target, params);
78
+
79
+ case 'oracle':
80
+ return await oracle[mode](connection, target, params);
81
+
82
+ default:
83
+ throw new Error(`Tipo de base de datos '${dbConfig.type}' no soportado.`);
84
+ }
85
+ }
86
+ catch (err)
87
+ {
88
+ throw new Error(`[Helmet][${dbConfig.type}][${mode}] ${err.message}`);
89
+ }
90
+ }
91
+
92
+
93
+
94
+ /**
95
+ * Ejecuta una consulta en la base de datos especificada.
96
+ *
97
+ * @async
98
+ * @function query
99
+ * @name query
100
+ * @param {string} databaseName - Perfil de la base de datos (clave de configuración)
101
+ * @param {string} sql - Consulta SQL, Sentencia SQL a ejecutar
102
+ * @param {Array} [binds] - Parámetros para la consulta (bind variables).
103
+ * @returns {Promise<Array>} Filas resultantes de la consulta.
104
+ * @throws {Error} Si el tipo de base de datos no es soportado para la operación 'query'.
105
+ * @description Ejecuta una sentencia SQL en la base de datos especificada y devuelve un objeto en un set de datos
106
+ */
107
+ // async function query(databaseName, sql, values = [], config)
108
+ // {
109
+ // const connection = await connect(databaseName, config);
110
+ // const dbConfig = config[databaseName];
111
+
112
+ // switch (dbConfig.type)
113
+ // {
114
+ // case 'postgres':
115
+ // return postgres.query(connection, sql);
116
+ // case 'mysql':
117
+ // return mysql.query(connection, sql, values);
118
+ // // case 'mariadb': // agregamos el caso MariaDB
119
+ // // return mariadb.query(connection, sql, binds);
120
+ // // break;
121
+ // case 'oracle':
122
+ // return oracle.query(connection, sql);
123
+ // // case 'mongodb':
124
+ // // // Adaptar la consulta SQL a la sintaxis de MongoDB
125
+ // // console.warn("La función 'query' no es directamente aplicable a MongoDB con sintaxis SQL.");
126
+ // // return null; // O lanzar un error
127
+ // default:
128
+ // throw new Error(`Tipo de base de datos '${dbConfig.type}' no soportado para la operación 'query'.`);
129
+ // }
130
+ // }
131
+
132
+ /**
133
+ * Ejecuta consultas de lectura (SELECT).
134
+ */
135
+ async function query(databaseName, sql, params = [], config)
136
+ {
137
+ return run(databaseName, sql, params, config, 'query');
138
+ }
139
+
140
+ /**
141
+ * Ejecuta sentencias de escritura (INSERT, UPDATE, DELETE, DDL).
142
+ */
143
+ async function execute(databaseName, sql, params = [], config)
144
+ {
145
+ return run(databaseName, sql, params, config, 'execute');
146
+ }
147
+
148
+
149
+ /**
150
+ * Ejecuta procedimientos almacenados o funciones.
151
+ */
152
+ async function call(databaseName, procedureName, params = {}, config)
153
+ {
154
+ return run(databaseName, procedureName, params, config, 'call');
155
+ }
156
+
157
+ /**
158
+ * Cierra la conexión a la base de datos especificada.
159
+ *
160
+ * @async
161
+ * @function close
162
+ * @name close
163
+ * @param {string} databaseName - Perfil de la base de datos (clave de configuración).
164
+ * @returns {Promise<void>}
165
+ * @description Cierra la conexion del Perfil de la base de datos especificada.
166
+ */
167
+ async function close(databaseName, config)
168
+ {
169
+ if (!connections[databaseName]) return;
170
+
171
+ const dbConfig = config[databaseName];
172
+ switch (dbConfig.type) {
173
+ case 'postgres':
174
+ await postgres.close(connections[databaseName]);
175
+ break;
176
+ case 'mysql':
177
+ await mysql.close(connections[databaseName]);
178
+ break;
179
+ // case 'mariadb': // agregamos el caso MariaDB
180
+ // await mariadb.close(connections[databaseName]);
181
+ // break;
182
+ case 'oracle':
183
+ await oracle.close(connections[databaseName]);
184
+ break;
185
+ // case 'mongodb':
186
+ // await mongodb.close(connections[databaseName]);
187
+ // break;
188
+ }
189
+ delete connections[databaseName];
190
+
191
+ }
192
+
193
+
194
+
195
+ /**
196
+ * @function
197
+ * @name execute
198
+ * @param {string} sql - Sentencia SQL a ejecutar
199
+ * @param {Promise<callback>} callback - objeto, para retornar la promesa
200
+ * @returns {result} result/err - Devuelve un objeto con el set de datos o un objeto err con la respuesta del error
201
+ * @description Ejecuta una sentencia SQL y devuelve un objeto en un set de datos
202
+ */
203
+ // async function execute(databaseName, sql, values = [], config)
204
+ // {
205
+ // const connection = await connect(databaseName, config);
206
+ // const dbConfig = config[databaseName];
207
+
208
+ // switch (dbConfig.type)
209
+ // {
210
+ // case 'postgres':
211
+ // return postgres.query(connection, sql);
212
+ // case 'mysql':
213
+ // return mysql.query(connection, sql, values);
214
+ // // case 'mariadb': // agregamos el caso MariaDB
215
+ // // return mariadb.query(connection, sql, binds);
216
+ // // break;
217
+ // case 'oracle':
218
+ // return oracle.query(connection, sql);
219
+ // // case 'mongodb':
220
+ // // // Adaptar la consulta SQL a la sintaxis de MongoDB
221
+ // // console.warn("La función 'query' no es directamente aplicable a MongoDB con sintaxis SQL.");
222
+ // // return null; // O lanzar un error
223
+ // default:
224
+ // throw new Error(`Tipo de base de datos '${dbConfig.type}' no soportado para la operación 'query'.`);
225
+ // }
226
+ // }
227
+
228
+ /**
229
+ * Cierra todas las conexiones activas.
230
+ */
231
+ async function closeAll(config)
232
+ {
233
+ for (const dbName of Object.keys(connections))
234
+ { await close(dbName, config); }
235
+ }
236
+
237
+ module.exports =
238
+ {
239
+ connect,
240
+ query,
241
+ execute,
242
+ call,
243
+ close,
244
+ closeAll
245
+ // ... otras funciones comunes
246
+ };