bonsaif 1.10.33 → 1.10.34
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/lib/hookup/redis.js +140 -29
- package/package.json +1 -1
package/lib/hookup/redis.js
CHANGED
|
@@ -14,41 +14,103 @@ const scan=async(options,db, cursor, pattern, count)=>{ // SCAN cursor [MATCH p
|
|
|
14
14
|
const redisConn = await exec.redisConn(options);
|
|
15
15
|
const start = Date.now();
|
|
16
16
|
|
|
17
|
-
cursor = cursor!=null ? cursor : '0';
|
|
17
|
+
cursor = cursor!=null ? String(cursor) : '0';
|
|
18
18
|
pattern = pattern!=null ? pattern : '*';
|
|
19
|
-
count = count!=null ? count : 100;
|
|
19
|
+
count = count!=null ? parseInt(count) : 100;
|
|
20
20
|
|
|
21
21
|
return new Promise((resolve, reject)=>{
|
|
22
22
|
try{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
// Esperar a que se seleccione la DB antes de ejecutar SCAN
|
|
24
|
+
redisConn.select(db, function(selectErr) {
|
|
25
|
+
if (selectErr) {
|
|
26
|
+
const end = Date.now();
|
|
27
|
+
const time = end - start;
|
|
28
|
+
resolve({"scan":"error", "cursor":"0", "keys":[], "count":0, "iterations":0, "err":selectErr, "time":utl.milisegundosASegundos(time)});
|
|
29
|
+
try{ exec.redisClose(redisConn); }catch(e){}
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
// Iterar automáticamente hasta obtener todas las keys
|
|
34
|
+
let allKeys = [];
|
|
35
|
+
let currentCursor = cursor;
|
|
36
|
+
let iterations = 0;
|
|
37
|
+
const maxIterations = 10000; // Protección contra loops infinitos
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
const scanIteration = () => {
|
|
40
|
+
iterations++;
|
|
41
|
+
|
|
42
|
+
if (iterations > maxIterations) {
|
|
43
|
+
const end = Date.now();
|
|
44
|
+
const time = end - start;
|
|
45
|
+
resolve({"scan":"max_iterations", "cursor":currentCursor, "keys":allKeys, "count":allKeys.length, "iterations":iterations, "err":"SCAN: max iterations exceeded", "time":utl.milisegundosASegundos(time)});
|
|
46
|
+
try{ exec.redisClose(redisConn); }catch(e){}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
redisConn.scan(currentCursor, 'MATCH', pattern, 'COUNT', count, function (err, res) {
|
|
51
|
+
if (err) {
|
|
52
|
+
const end = Date.now();
|
|
53
|
+
const time = end - start;
|
|
54
|
+
resolve({"scan":"error", "cursor":currentCursor, "keys":allKeys, "count":allKeys.length, "iterations":iterations, "err":err, "time":utl.milisegundosASegundos(time)});
|
|
55
|
+
try{ exec.redisClose(redisConn); }catch(e){}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const newCursor = res[0];
|
|
60
|
+
const keys = res[1] || [];
|
|
61
|
+
|
|
62
|
+
// Acumular keys
|
|
63
|
+
allKeys = allKeys.concat(keys);
|
|
64
|
+
|
|
65
|
+
utl.log(`${tag} SCAN iteration=${iterations} cursor=${currentCursor}->${newCursor} keys=${keys.length} total=${allKeys.length}`);
|
|
66
|
+
|
|
67
|
+
// Si el cursor es "0", terminamos
|
|
68
|
+
if (newCursor === '0') {
|
|
69
|
+
const end = Date.now();
|
|
70
|
+
const time = end - start;
|
|
71
|
+
|
|
72
|
+
const result = {
|
|
73
|
+
"scan": "ok",
|
|
74
|
+
"cursor": newCursor,
|
|
75
|
+
"keys": allKeys,
|
|
76
|
+
"count": allKeys.length,
|
|
77
|
+
"iterations": iterations,
|
|
78
|
+
"err": null,
|
|
79
|
+
"time": utl.milisegundosASegundos(time)
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
utl.log(`${tag} SCAN COMPLETE: returning ${allKeys.length} keys in ${iterations} iterations`);
|
|
83
|
+
|
|
84
|
+
resolve(result);
|
|
85
|
+
|
|
86
|
+
try{
|
|
87
|
+
exec.redisClose(redisConn);
|
|
88
|
+
utl.log(`${tag} SCAN connection closed successfully`);
|
|
89
|
+
}catch(e){
|
|
90
|
+
utl.log(`${tag} err.scan close: ${e}`);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
// Continuar iterando
|
|
94
|
+
currentCursor = newCursor;
|
|
95
|
+
scanIteration();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
};
|
|
42
99
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
utl.log('err.scan '+e);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
100
|
+
// Iniciar iteración
|
|
101
|
+
scanIteration();
|
|
102
|
+
});
|
|
49
103
|
}catch(e){
|
|
50
|
-
utl.log(
|
|
51
|
-
|
|
104
|
+
utl.log(`${tag} err scan: ${e}`);
|
|
105
|
+
const end = Date.now();
|
|
106
|
+
const time = end - start;
|
|
107
|
+
// Cerrar conexión en caso de error
|
|
108
|
+
try{
|
|
109
|
+
exec.redisClose(redisConn);
|
|
110
|
+
}catch(closeErr){
|
|
111
|
+
utl.log(`${tag} err closing connection after error: ${closeErr}`);
|
|
112
|
+
}
|
|
113
|
+
resolve({"scan":"error", "cursor":"0", "keys":[], "count":0, "iterations":0, "err":e, "time":utl.milisegundosASegundos(time)});
|
|
52
114
|
}
|
|
53
115
|
})
|
|
54
116
|
}
|
|
@@ -108,6 +170,31 @@ const get=async( options, db, key )=>{
|
|
|
108
170
|
})
|
|
109
171
|
}
|
|
110
172
|
|
|
173
|
+
const type=async( options, db, key )=>{ // TYPE key
|
|
174
|
+
const exec = require("./exec");
|
|
175
|
+
const redisConn = await exec.redisConn(options);
|
|
176
|
+
const start = Date.now();
|
|
177
|
+
|
|
178
|
+
return new Promise((resolve, reject)=>{
|
|
179
|
+
try{
|
|
180
|
+
redisConn.select(db,function() { /* ... */ });
|
|
181
|
+
redisConn.type(key, function (err, res) {
|
|
182
|
+
const end = Date.now();
|
|
183
|
+
const time = end - start;
|
|
184
|
+
|
|
185
|
+
resolve({"type":key, "err":err, "res":res, "time":utl.milisegundosASegundos(time)});
|
|
186
|
+
try{
|
|
187
|
+
exec.redisClose(redisConn);
|
|
188
|
+
}catch(e){
|
|
189
|
+
utl.log('err.type '+e);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}catch(e){
|
|
193
|
+
utl.log('err type'+e);
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
|
|
111
198
|
|
|
112
199
|
const incrby=async(options, db, key,value,expire, counter )=>{
|
|
113
200
|
const exec = require("./exec");
|
|
@@ -784,6 +871,7 @@ const dbsize=async( options, db )=>{ // DBSIZE
|
|
|
784
871
|
}
|
|
785
872
|
|
|
786
873
|
const api=async(options, dbm, json)=>{
|
|
874
|
+
//utl.log('json recibido: '+JSON.stringify(json));
|
|
787
875
|
const exec = require("./exec");
|
|
788
876
|
|
|
789
877
|
const start = Date.now();
|
|
@@ -800,7 +888,7 @@ const api=async(options, dbm, json)=>{
|
|
|
800
888
|
let lstop = json.stop!=null?json.stop*1:-1;
|
|
801
889
|
let {field:id, val:vid} = getFirstField(filter);
|
|
802
890
|
|
|
803
|
-
let ltdml = ['sinter','sunionstore','scard','hmget','hfind','upsert','set','get','scan','incrby','sadd','srem','smembers','hset','hgetall','del','incrbyfloat','expireat','setnx','hsetnx','hmset','expire','lrange','keys','dbsize'];
|
|
891
|
+
let ltdml = ['sinter','sunionstore','scard','hmget','hfind','upsert','set','get','type','scan','incrby','sadd','srem','smembers','hset','hgetall','del','incrbyfloat','expireat','setnx','hsetnx','hmset','expire','lrange','keys','dbsize'];
|
|
804
892
|
for (let x of ltdml){
|
|
805
893
|
if (utl.ObjectEmpty(json,x)){
|
|
806
894
|
dml = x; break;
|
|
@@ -812,14 +900,36 @@ const api=async(options, dbm, json)=>{
|
|
|
812
900
|
let keysArray = json.keys!=null ? json.keys : [];
|
|
813
901
|
let fieldsArray = json.fields!=null ? json.fields : [];
|
|
814
902
|
let destination = json.destination!=null ? json.destination : '';
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
let
|
|
903
|
+
|
|
904
|
+
// Parsear parámetros específicos para SCAN
|
|
905
|
+
let cursor = '0';
|
|
906
|
+
let pattern = '*';
|
|
907
|
+
let scan_count = 100;
|
|
908
|
+
|
|
909
|
+
if (dml === 'scan' && Array.isArray(key)) {
|
|
910
|
+
// Si scan viene como array: ["0", "COUNT", "100"] o ["0", "MATCH", "pattern", "COUNT", "100"]
|
|
911
|
+
cursor = key[0] || '0';
|
|
912
|
+
for (let i = 1; i < key.length; i++) {
|
|
913
|
+
if (key[i] === 'MATCH' && i + 1 < key.length) {
|
|
914
|
+
pattern = key[i + 1];
|
|
915
|
+
i++;
|
|
916
|
+
} else if (key[i] === 'COUNT' && i + 1 < key.length) {
|
|
917
|
+
scan_count = parseInt(key[i + 1]);
|
|
918
|
+
i++;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
} else {
|
|
922
|
+
// Parámetros tradicionales
|
|
923
|
+
cursor = json.cursor!=null ? json.cursor : '0';
|
|
924
|
+
pattern = json.pattern!=null ? json.pattern : (typeof key === 'string' ? key : '*');
|
|
925
|
+
scan_count = json.count!=null ? json.count : 100;
|
|
926
|
+
}
|
|
818
927
|
|
|
819
928
|
let r;
|
|
820
929
|
switch (dml){
|
|
821
930
|
case 'set': r = await set(options,dbm,key,value,expire); break;
|
|
822
931
|
case 'get': r = await get(options,dbm,key); break;
|
|
932
|
+
case 'type': r = await type(options,dbm,key); break;
|
|
823
933
|
case 'hfind': r = await hfind(options,dbm,key,filter,order,limit); break;
|
|
824
934
|
case 'upsert': r = await upsert(options,dbm,key,value,id,vid,expire); break;
|
|
825
935
|
case 'scan': r = await scan(options,dbm,cursor,pattern,scan_count); break;
|
|
@@ -934,6 +1044,7 @@ module.exports ={
|
|
|
934
1044
|
scan,
|
|
935
1045
|
set,
|
|
936
1046
|
get,
|
|
1047
|
+
type,
|
|
937
1048
|
incrby,
|
|
938
1049
|
sadd,
|
|
939
1050
|
srem,
|