bonsaif 1.10.39 → 1.10.41
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/README.md +0 -133
- package/lib/execute.js +15 -4
- package/lib/hookup/exec.js +2 -4
- package/lib/hookup/mariadb.js +10 -28
- package/lib/hookup/mongodb.js +177 -193
- package/lib/hookup/mongoose.js +126 -12
- package/lib/hookup/postgres.js +27 -35
- package/lib/hookup/redis.js +42 -162
- package/package.json +14 -5
- package/tests/config.js +64 -0
package/lib/hookup/mongoose.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ::: B[]NSAIF() ::: => 2024
|
|
3
3
|
* Hookup para Mongoose (MongoDB ORM)
|
|
4
|
+
* Compatible con múltiples versiones de Node y Mongoose
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
'use strict';
|
|
@@ -9,15 +10,64 @@ const utl = require('../utl');
|
|
|
9
10
|
let debug = false;
|
|
10
11
|
let tag = ` ::: B[]NSAIF() ::: => mongoose.js `;
|
|
11
12
|
|
|
13
|
+
// Validar disponibilidad de Mongoose
|
|
14
|
+
let mongoose = null;
|
|
15
|
+
let isMongooseAvailable = false;
|
|
16
|
+
let mongooseVersion = null;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
mongoose = require('mongoose');
|
|
20
|
+
isMongooseAvailable = true;
|
|
21
|
+
mongooseVersion = mongoose.version;
|
|
22
|
+
|
|
23
|
+
// Validar versión de Node
|
|
24
|
+
const nodeVersion = process.version;
|
|
25
|
+
const nodeMajor = parseInt(nodeVersion.split('.')[0].substring(1));
|
|
26
|
+
|
|
27
|
+
if (nodeMajor < 12) {
|
|
28
|
+
utl.log(`${tag} WARNING: Node ${nodeVersion} no es compatible con Mongoose. Se requiere Node >= 12.0.0`);
|
|
29
|
+
isMongooseAvailable = false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
} catch (e) {
|
|
33
|
+
utl.log(`${tag} Mongoose no está instalado. Para usar mongoose, instala: npm install mongoose@"^6.12.0" (Node 12-14) o mongoose@"^8.0.0" (Node >= 16.20.1)`);
|
|
34
|
+
isMongooseAvailable = false;
|
|
35
|
+
}
|
|
36
|
+
|
|
12
37
|
// Cache de modelos dinámicos por base de datos y colección
|
|
13
38
|
const modelCache = new Map();
|
|
14
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Validar que Mongoose esté disponible
|
|
42
|
+
*/
|
|
43
|
+
const checkMongooseAvailable = () => {
|
|
44
|
+
if (!isMongooseAvailable) {
|
|
45
|
+
return {
|
|
46
|
+
result: {
|
|
47
|
+
dml: 'error',
|
|
48
|
+
time: 0,
|
|
49
|
+
code: 503,
|
|
50
|
+
error: 1,
|
|
51
|
+
msg: 'Mongoose no está disponible en este sistema',
|
|
52
|
+
details: {
|
|
53
|
+
nodeVersion: process.version,
|
|
54
|
+
mongooseInstalled: mongoose !== null,
|
|
55
|
+
recommendation: process.version.startsWith('v12') || process.version.startsWith('v14')
|
|
56
|
+
? 'Instala: npm install mongoose@^6.12.0'
|
|
57
|
+
: 'Instala: npm install mongoose@^8.0.0 (requiere Node >= 16.20.1)'
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
data: []
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
};
|
|
65
|
+
|
|
15
66
|
/**
|
|
16
67
|
* Parsear schema dinámico recibido del cliente
|
|
17
68
|
* Convierte definición simple a Schema de Mongoose
|
|
18
69
|
*/
|
|
19
70
|
const parseSchema = (schemaDefinition) => {
|
|
20
|
-
const mongoose = require('mongoose');
|
|
21
71
|
const parsedSchema = {};
|
|
22
72
|
|
|
23
73
|
for (const [field, def] of Object.entries(schemaDefinition)) {
|
|
@@ -72,7 +122,9 @@ const parseSchema = (schemaDefinition) => {
|
|
|
72
122
|
* Conectar a MongoDB usando Mongoose
|
|
73
123
|
*/
|
|
74
124
|
const connect = async (options) => {
|
|
75
|
-
const
|
|
125
|
+
const availabilityError = checkMongooseAvailable();
|
|
126
|
+
if (availabilityError) throw new Error(availabilityError.result.msg);
|
|
127
|
+
|
|
76
128
|
const { uri = '', poolSize = 10, debug: debugMode = false } = options.endpoint;
|
|
77
129
|
|
|
78
130
|
try {
|
|
@@ -81,15 +133,31 @@ const connect = async (options) => {
|
|
|
81
133
|
return mongoose.connection;
|
|
82
134
|
}
|
|
83
135
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
minPoolSize: 2,
|
|
136
|
+
// Opciones compatibles con múltiples versiones de Mongoose
|
|
137
|
+
const connectOptions = {
|
|
87
138
|
serverSelectionTimeoutMS: 15000,
|
|
88
139
|
socketTimeoutMS: 45000,
|
|
89
140
|
connectTimeoutMS: 10000
|
|
90
|
-
}
|
|
141
|
+
};
|
|
91
142
|
|
|
92
|
-
|
|
143
|
+
// Mongoose 6.x y 7.x usan useNewUrlParser, useUnifiedTopology
|
|
144
|
+
// Mongoose 8.x los depreca
|
|
145
|
+
const majorVersion = parseInt(mongooseVersion.split('.')[0]);
|
|
146
|
+
|
|
147
|
+
if (majorVersion >= 6) {
|
|
148
|
+
// Mongoose 6.x, 7.x, 8.x
|
|
149
|
+
connectOptions.maxPoolSize = poolSize;
|
|
150
|
+
connectOptions.minPoolSize = 2;
|
|
151
|
+
} else {
|
|
152
|
+
// Mongoose 5.x
|
|
153
|
+
connectOptions.poolSize = poolSize;
|
|
154
|
+
connectOptions.useNewUrlParser = true;
|
|
155
|
+
connectOptions.useUnifiedTopology = true;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
await mongoose.connect(uri, connectOptions);
|
|
159
|
+
|
|
160
|
+
debugMode ? utl.log(`${tag} [Mongoose ${mongooseVersion}] conectado a ${uri}`) : '';
|
|
93
161
|
return mongoose.connection;
|
|
94
162
|
} catch (e) {
|
|
95
163
|
utl.log(`${tag} [Mongoose] error de conexión:`, e);
|
|
@@ -101,7 +169,6 @@ const connect = async (options) => {
|
|
|
101
169
|
* Obtener o crear modelo dinámico para una colección
|
|
102
170
|
*/
|
|
103
171
|
const getModel = (db, collection, schemaDefinition = null) => {
|
|
104
|
-
const mongoose = require('mongoose');
|
|
105
172
|
const cacheKey = schemaDefinition
|
|
106
173
|
? `${db}.${collection}.custom.${JSON.stringify(schemaDefinition)}`
|
|
107
174
|
: `${db}.${collection}.generic`;
|
|
@@ -147,6 +214,9 @@ const getModel = (db, collection, schemaDefinition = null) => {
|
|
|
147
214
|
* FIND - Búsqueda dinámica
|
|
148
215
|
*/
|
|
149
216
|
const find = async (options, db, collection, query) => {
|
|
217
|
+
const availabilityError = checkMongooseAvailable();
|
|
218
|
+
if (availabilityError) return availabilityError;
|
|
219
|
+
|
|
150
220
|
const start = Date.now();
|
|
151
221
|
|
|
152
222
|
try {
|
|
@@ -200,6 +270,9 @@ const find = async (options, db, collection, query) => {
|
|
|
200
270
|
* FINDONE - Buscar un solo documento
|
|
201
271
|
*/
|
|
202
272
|
const findOne = async (options, db, collection, query) => {
|
|
273
|
+
const availabilityError = checkMongooseAvailable();
|
|
274
|
+
if (availabilityError) return availabilityError;
|
|
275
|
+
|
|
203
276
|
const start = Date.now();
|
|
204
277
|
|
|
205
278
|
try {
|
|
@@ -250,6 +323,9 @@ const findOne = async (options, db, collection, query) => {
|
|
|
250
323
|
* COUNT - Contar documentos
|
|
251
324
|
*/
|
|
252
325
|
const count = async (options, db, collection, query) => {
|
|
326
|
+
const availabilityError = checkMongooseAvailable();
|
|
327
|
+
if (availabilityError) return availabilityError;
|
|
328
|
+
|
|
253
329
|
const start = Date.now();
|
|
254
330
|
|
|
255
331
|
try {
|
|
@@ -295,6 +371,9 @@ const count = async (options, db, collection, query) => {
|
|
|
295
371
|
* INSERT - Crear documento
|
|
296
372
|
*/
|
|
297
373
|
const insert = async (options, db, collection, query) => {
|
|
374
|
+
const availabilityError = checkMongooseAvailable();
|
|
375
|
+
if (availabilityError) return availabilityError;
|
|
376
|
+
|
|
298
377
|
const start = Date.now();
|
|
299
378
|
|
|
300
379
|
try {
|
|
@@ -346,6 +425,9 @@ const insert = async (options, db, collection, query) => {
|
|
|
346
425
|
* INSERTMANY - Crear múltiples documentos
|
|
347
426
|
*/
|
|
348
427
|
const insertMany = async (options, db, collection, query) => {
|
|
428
|
+
const availabilityError = checkMongooseAvailable();
|
|
429
|
+
if (availabilityError) return availabilityError;
|
|
430
|
+
|
|
349
431
|
const start = Date.now();
|
|
350
432
|
|
|
351
433
|
try {
|
|
@@ -392,6 +474,9 @@ const insertMany = async (options, db, collection, query) => {
|
|
|
392
474
|
* UPDATE - Actualizar documento(s)
|
|
393
475
|
*/
|
|
394
476
|
const update = async (options, db, collection, query) => {
|
|
477
|
+
const availabilityError = checkMongooseAvailable();
|
|
478
|
+
if (availabilityError) return availabilityError;
|
|
479
|
+
|
|
395
480
|
const start = Date.now();
|
|
396
481
|
|
|
397
482
|
try {
|
|
@@ -442,6 +527,9 @@ const update = async (options, db, collection, query) => {
|
|
|
442
527
|
* UPDATEMANY - Actualizar múltiples documentos
|
|
443
528
|
*/
|
|
444
529
|
const updateMany = async (options, db, collection, query) => {
|
|
530
|
+
const availabilityError = checkMongooseAvailable();
|
|
531
|
+
if (availabilityError) return availabilityError;
|
|
532
|
+
|
|
445
533
|
const start = Date.now();
|
|
446
534
|
|
|
447
535
|
try {
|
|
@@ -492,6 +580,9 @@ const updateMany = async (options, db, collection, query) => {
|
|
|
492
580
|
* UPSERT - Actualizar o insertar
|
|
493
581
|
*/
|
|
494
582
|
const upsert = async (options, db, collection, query) => {
|
|
583
|
+
const availabilityError = checkMongooseAvailable();
|
|
584
|
+
if (availabilityError) return availabilityError;
|
|
585
|
+
|
|
495
586
|
const start = Date.now();
|
|
496
587
|
|
|
497
588
|
try {
|
|
@@ -554,6 +645,9 @@ const upsert = async (options, db, collection, query) => {
|
|
|
554
645
|
* DELETE - Eliminar documento(s)
|
|
555
646
|
*/
|
|
556
647
|
const deleteOne = async (options, db, collection, query) => {
|
|
648
|
+
const availabilityError = checkMongooseAvailable();
|
|
649
|
+
if (availabilityError) return availabilityError;
|
|
650
|
+
|
|
557
651
|
const start = Date.now();
|
|
558
652
|
|
|
559
653
|
try {
|
|
@@ -600,6 +694,9 @@ const deleteOne = async (options, db, collection, query) => {
|
|
|
600
694
|
* DELETEMANY - Eliminar múltiples documentos
|
|
601
695
|
*/
|
|
602
696
|
const deleteMany = async (options, db, collection, query) => {
|
|
697
|
+
const availabilityError = checkMongooseAvailable();
|
|
698
|
+
if (availabilityError) return availabilityError;
|
|
699
|
+
|
|
603
700
|
const start = Date.now();
|
|
604
701
|
|
|
605
702
|
try {
|
|
@@ -646,6 +743,9 @@ const deleteMany = async (options, db, collection, query) => {
|
|
|
646
743
|
* AGGREGATE - Pipeline de agregación
|
|
647
744
|
*/
|
|
648
745
|
const aggregate = async (options, db, collection, query) => {
|
|
746
|
+
const availabilityError = checkMongooseAvailable();
|
|
747
|
+
if (availabilityError) return availabilityError;
|
|
748
|
+
|
|
649
749
|
const start = Date.now();
|
|
650
750
|
|
|
651
751
|
try {
|
|
@@ -691,6 +791,9 @@ const aggregate = async (options, db, collection, query) => {
|
|
|
691
791
|
* DISTINCT - Valores únicos
|
|
692
792
|
*/
|
|
693
793
|
const distinct = async (options, db, collection, query) => {
|
|
794
|
+
const availabilityError = checkMongooseAvailable();
|
|
795
|
+
if (availabilityError) return availabilityError;
|
|
796
|
+
|
|
694
797
|
const start = Date.now();
|
|
695
798
|
|
|
696
799
|
try {
|
|
@@ -736,10 +839,12 @@ const distinct = async (options, db, collection, query) => {
|
|
|
736
839
|
* DBS - Listar todas las bases de datos
|
|
737
840
|
*/
|
|
738
841
|
const dbs = async (options) => {
|
|
842
|
+
const availabilityError = checkMongooseAvailable();
|
|
843
|
+
if (availabilityError) return availabilityError;
|
|
844
|
+
|
|
739
845
|
const start = Date.now();
|
|
740
846
|
|
|
741
847
|
try {
|
|
742
|
-
const mongoose = require('mongoose');
|
|
743
848
|
await connect(options);
|
|
744
849
|
|
|
745
850
|
const adminDb = mongoose.connection.db.admin();
|
|
@@ -780,10 +885,12 @@ const dbs = async (options) => {
|
|
|
780
885
|
* COLLECTIONS - Listar todas las colecciones de una base de datos
|
|
781
886
|
*/
|
|
782
887
|
const collections = async (options, db) => {
|
|
888
|
+
const availabilityError = checkMongooseAvailable();
|
|
889
|
+
if (availabilityError) return availabilityError;
|
|
890
|
+
|
|
783
891
|
const start = Date.now();
|
|
784
892
|
|
|
785
893
|
try {
|
|
786
|
-
const mongoose = require('mongoose');
|
|
787
894
|
await connect(options);
|
|
788
895
|
|
|
789
896
|
const dbConn = mongoose.connection.useDb(db);
|
|
@@ -825,10 +932,12 @@ const collections = async (options, db) => {
|
|
|
825
932
|
* DROP - Eliminar una colección completa
|
|
826
933
|
*/
|
|
827
934
|
const drop = async (options, db, collection) => {
|
|
935
|
+
const availabilityError = checkMongooseAvailable();
|
|
936
|
+
if (availabilityError) return availabilityError;
|
|
937
|
+
|
|
828
938
|
const start = Date.now();
|
|
829
939
|
|
|
830
940
|
try {
|
|
831
|
-
const mongoose = require('mongoose');
|
|
832
941
|
await connect(options);
|
|
833
942
|
|
|
834
943
|
const dbConn = mongoose.connection.useDb(db);
|
|
@@ -870,6 +979,9 @@ const drop = async (options, db, collection) => {
|
|
|
870
979
|
* API - Router principal para todas las operaciones
|
|
871
980
|
*/
|
|
872
981
|
const api = async (options, db, body) => {
|
|
982
|
+
const availabilityError = checkMongooseAvailable();
|
|
983
|
+
if (availabilityError) return availabilityError;
|
|
984
|
+
|
|
873
985
|
let { dml = '', collection = '' } = body;
|
|
874
986
|
|
|
875
987
|
// Si dml es 'api', buscar el DML real en el body
|
|
@@ -984,5 +1096,7 @@ module.exports = {
|
|
|
984
1096
|
collections,
|
|
985
1097
|
drop,
|
|
986
1098
|
connect,
|
|
987
|
-
getModel
|
|
1099
|
+
getModel,
|
|
1100
|
+
isMongooseAvailable,
|
|
1101
|
+
mongooseVersion
|
|
988
1102
|
};
|
package/lib/hookup/postgres.js
CHANGED
|
@@ -13,19 +13,16 @@ const qson = async (o, alias, query,dml,ip)=>{
|
|
|
13
13
|
let headers = '';
|
|
14
14
|
const start = Date.now();
|
|
15
15
|
let tipo = 'query';
|
|
16
|
-
|
|
17
16
|
return new Promise(function(resolve, reject) {
|
|
17
|
+
//2022/08/27 VRSZ Se cambia el la utileria para consumirmo por mysql ya que mariadb no regresa los campos de las columnas
|
|
18
18
|
const {port='', uri = '', user='', password='', debug=false } = o.endpoint ? o.endpoint:{};
|
|
19
19
|
const {db=''} = o.options ? o.options : {};
|
|
20
20
|
|
|
21
21
|
const { Client } = require('pg');
|
|
22
22
|
const client = new Client({ host:uri, user, port , password, database :db });
|
|
23
|
-
|
|
24
23
|
client.connect(function(e){
|
|
25
24
|
if(e){
|
|
26
25
|
utl.log(`${tag} [postgres] is OFFline`,e);
|
|
27
|
-
resolve({"result":{dml, headers, time:0, code:e.code ? e.code:0, error:1, msg:e.message ? e.message:''}, results:e});
|
|
28
|
-
return;
|
|
29
26
|
}else{
|
|
30
27
|
debug ? utl.log(`${tag} [postgres] connection is online `):'';
|
|
31
28
|
}
|
|
@@ -35,6 +32,7 @@ const qson = async (o, alias, query,dml,ip)=>{
|
|
|
35
32
|
tipo = 'select';
|
|
36
33
|
}
|
|
37
34
|
|
|
35
|
+
//2023/11/07 Recuperar id
|
|
38
36
|
if (query.toLowerCase().includes("insert ") && query.toLowerCase().includes(" into ")){
|
|
39
37
|
query = query.replace(';','');
|
|
40
38
|
query = query + ' RETURNING id';
|
|
@@ -44,40 +42,34 @@ const qson = async (o, alias, query,dml,ip)=>{
|
|
|
44
42
|
client.query(query, function(err, res) {
|
|
45
43
|
const end = Date.now();
|
|
46
44
|
const time = end - start;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
headers = headers+
|
|
45
|
+
client.end(function(){
|
|
46
|
+
debug ? utl.log(`${tag} [postgres] connection is closing connection `):'';
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (err) {
|
|
50
|
+
resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:err.code ? err.code:0, error:1, msg:err.routine ? err.routine:''}, results:err});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
data = res.rows ? res.rows: [];
|
|
54
|
+
let rowCount = res.rowCount ? res.rowCount:0;
|
|
55
|
+
|
|
56
|
+
if (tipo!='select'){
|
|
57
|
+
data =[{"insert_id":data[0] ? data[0].id : 0, "changed_rows":rowCount}];
|
|
58
|
+
headers = 'insert_id|changed_rows';
|
|
59
|
+
}else{
|
|
60
|
+
if (data.length==0){
|
|
61
|
+
let {fields=[]} = res ? res : {};
|
|
62
|
+
for (let field of fields ){
|
|
63
|
+
if (headers.length>0){
|
|
64
|
+
headers = headers+'|';
|
|
67
65
|
}
|
|
68
|
-
|
|
69
|
-
try{ headers = Object.keys(data[0]); headers = headers.join("|"); }catch(e){}
|
|
66
|
+
headers = headers+field.name;
|
|
70
67
|
}
|
|
68
|
+
}else{
|
|
69
|
+
try{ headers = Object.keys(data[0]); headers = headers.join("|"); }catch(e){}
|
|
71
70
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}catch(e){
|
|
75
|
-
resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:500, error:1, msg:e.message}, results:e});
|
|
76
|
-
}finally{
|
|
77
|
-
// Cerrar conexión SIEMPRE
|
|
78
|
-
client.end(function(){
|
|
79
|
-
debug ? utl.log(`${tag} [postgres] connection is closing connection `):'';
|
|
80
|
-
});
|
|
71
|
+
}
|
|
72
|
+
resolve({"result":{dml, headers, time:utl.milisegundosASegundos(time), code:200, error:0}, data});
|
|
81
73
|
}
|
|
82
74
|
});
|
|
83
75
|
});
|