bonsaif 1.10.32 → 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 +166 -37
- package/package.json +1 -1
package/lib/hookup/redis.js
CHANGED
|
@@ -14,48 +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
|
-
|
|
29
|
-
|
|
30
|
-
args.push('COUNT', count);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
redisConn.scan(args, function (err, res) {
|
|
34
|
-
if (err) {
|
|
35
|
-
reject(err);
|
|
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){}
|
|
36
30
|
return;
|
|
37
31
|
}
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
+
};
|
|
49
99
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
utl.log('err.scan '+e);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
100
|
+
// Iniciar iteración
|
|
101
|
+
scanIteration();
|
|
102
|
+
});
|
|
56
103
|
}catch(e){
|
|
57
|
-
utl.log(
|
|
58
|
-
|
|
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)});
|
|
59
114
|
}
|
|
60
115
|
})
|
|
61
116
|
}
|
|
@@ -115,6 +170,31 @@ const get=async( options, db, key )=>{
|
|
|
115
170
|
})
|
|
116
171
|
}
|
|
117
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
|
+
|
|
118
198
|
|
|
119
199
|
const incrby=async(options, db, key,value,expire, counter )=>{
|
|
120
200
|
const exec = require("./exec");
|
|
@@ -767,7 +847,31 @@ const keys=async( options, db, pattern )=>{ // KEYS pattern
|
|
|
767
847
|
})
|
|
768
848
|
}
|
|
769
849
|
|
|
850
|
+
const dbsize=async( options, db )=>{ // DBSIZE
|
|
851
|
+
const exec = require("./exec");
|
|
852
|
+
const redisConn = await exec.redisConn(options);
|
|
853
|
+
const start = Date.now();
|
|
854
|
+
return new Promise((resolve, reject)=>{
|
|
855
|
+
try{
|
|
856
|
+
redisConn.select(db,function() { /* ... */ });
|
|
857
|
+
redisConn.dbsize(function (err, res) {
|
|
858
|
+
const end = Date.now();
|
|
859
|
+
const time = end - start;
|
|
860
|
+
resolve({"dbsize":db, "count":res, "err":err, "res":res, "time":utl.milisegundosASegundos(time)});
|
|
861
|
+
try{
|
|
862
|
+
exec.redisClose(redisConn);
|
|
863
|
+
}catch(e){
|
|
864
|
+
utl.log('err.dbsize '+e);
|
|
865
|
+
}
|
|
866
|
+
});
|
|
867
|
+
}catch(e){
|
|
868
|
+
utl.log('err dbsize'+e);
|
|
869
|
+
}
|
|
870
|
+
})
|
|
871
|
+
}
|
|
872
|
+
|
|
770
873
|
const api=async(options, dbm, json)=>{
|
|
874
|
+
//utl.log('json recibido: '+JSON.stringify(json));
|
|
771
875
|
const exec = require("./exec");
|
|
772
876
|
|
|
773
877
|
const start = Date.now();
|
|
@@ -784,7 +888,7 @@ const api=async(options, dbm, json)=>{
|
|
|
784
888
|
let lstop = json.stop!=null?json.stop*1:-1;
|
|
785
889
|
let {field:id, val:vid} = getFirstField(filter);
|
|
786
890
|
|
|
787
|
-
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'];
|
|
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'];
|
|
788
892
|
for (let x of ltdml){
|
|
789
893
|
if (utl.ObjectEmpty(json,x)){
|
|
790
894
|
dml = x; break;
|
|
@@ -796,14 +900,36 @@ const api=async(options, dbm, json)=>{
|
|
|
796
900
|
let keysArray = json.keys!=null ? json.keys : [];
|
|
797
901
|
let fieldsArray = json.fields!=null ? json.fields : [];
|
|
798
902
|
let destination = json.destination!=null ? json.destination : '';
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
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
|
+
}
|
|
802
927
|
|
|
803
928
|
let r;
|
|
804
929
|
switch (dml){
|
|
805
930
|
case 'set': r = await set(options,dbm,key,value,expire); break;
|
|
806
931
|
case 'get': r = await get(options,dbm,key); break;
|
|
932
|
+
case 'type': r = await type(options,dbm,key); break;
|
|
807
933
|
case 'hfind': r = await hfind(options,dbm,key,filter,order,limit); break;
|
|
808
934
|
case 'upsert': r = await upsert(options,dbm,key,value,id,vid,expire); break;
|
|
809
935
|
case 'scan': r = await scan(options,dbm,cursor,pattern,scan_count); break;
|
|
@@ -822,6 +948,7 @@ const api=async(options, dbm, json)=>{
|
|
|
822
948
|
case 'expire': r = await expire(options,dbm,key,expire); break;
|
|
823
949
|
case 'lrange': r = await lrange(options,dbm,key,lstart,lstop); break;
|
|
824
950
|
case 'keys': r = await keys(options,dbm,key); break;
|
|
951
|
+
case 'dbsize': r = await dbsize(options,dbm); break;
|
|
825
952
|
case 'sinter': r = await sinter(options,dbm,Array.isArray(key) ? key : [key]); break;
|
|
826
953
|
case 'hmget': r = await hmget(options,dbm,key,fieldsArray); break;
|
|
827
954
|
case 'sunionstore': r = await sunionstore(options,dbm,destination,keysArray); break;
|
|
@@ -917,6 +1044,7 @@ module.exports ={
|
|
|
917
1044
|
scan,
|
|
918
1045
|
set,
|
|
919
1046
|
get,
|
|
1047
|
+
type,
|
|
920
1048
|
incrby,
|
|
921
1049
|
sadd,
|
|
922
1050
|
srem,
|
|
@@ -935,5 +1063,6 @@ module.exports ={
|
|
|
935
1063
|
expire,
|
|
936
1064
|
expireat,
|
|
937
1065
|
lrange,
|
|
938
|
-
keys
|
|
1066
|
+
keys,
|
|
1067
|
+
dbsize
|
|
939
1068
|
}
|