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.
Files changed (2) hide show
  1. package/lib/hookup/redis.js +166 -37
  2. package/package.json +1 -1
@@ -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
- redisConn.select(db,function() { /* ... */ });
24
-
25
- let args = [cursor];
26
- if (pattern) {
27
- args.push('MATCH', pattern);
28
- }
29
- if (count) {
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
- const end = Date.now();
40
- const time = end - start;
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
- // res[0] es el nuevo cursor, res[1] es el array de keys
43
- resolve({
44
- "cursor": res[0],
45
- "keys": res[1],
46
- "count": res[1].length,
47
- "time": utl.milisegundosASegundos(time)
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
- try{
51
- exec.redisClose(redisConn);
52
- }catch(e){
53
- utl.log('err.scan '+e);
54
- }
55
- });
100
+ // Iniciar iteración
101
+ scanIteration();
102
+ });
56
103
  }catch(e){
57
- utl.log('err scan: '+e);
58
- reject(e);
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
- let cursor = json.cursor!=null ? json.cursor : '0';
800
- let pattern = json.pattern!=null ? json.pattern : key;
801
- let scan_count = json.count!=null ? json.count : 100;
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
  }
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "name": "bonsaif",
16
16
  "description": "bonsaif is a library to connect to bonsaif apis",
17
- "version": "1.10.32",
17
+ "version": "1.10.34",
18
18
  "main": "index.js",
19
19
  "directories": {
20
20
  "lib": "lib"