@pi-r/redis 0.5.0 → 0.6.1
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/client/index.js +212 -134
- package/package.json +4 -4
- package/types/index.d.ts +26 -10
package/client/index.js
CHANGED
|
@@ -8,10 +8,10 @@ const Db = require("@e-mc/db");
|
|
|
8
8
|
const DbPool = require('@e-mc/db/pool');
|
|
9
9
|
const REDIS_V4 = Db.checkSemVer("redis" /* STRINGS.MODULE_NAME */, 4);
|
|
10
10
|
class RedisPool extends DbPool {
|
|
11
|
-
getConnection() {
|
|
12
|
-
return
|
|
11
|
+
async getConnection() {
|
|
12
|
+
return this.client;
|
|
13
13
|
}
|
|
14
|
-
close() {
|
|
14
|
+
async close() {
|
|
15
15
|
return this.client.disconnect();
|
|
16
16
|
}
|
|
17
17
|
isEmpty() {
|
|
@@ -22,7 +22,7 @@ class RedisPool extends DbPool {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
const POOL_STATE = {};
|
|
25
|
-
function getClient(db, options, poolKey) {
|
|
25
|
+
async function getClient(db, options, poolKey) {
|
|
26
26
|
const socket = options.socket || (options.socket = {});
|
|
27
27
|
if (!poolKey) {
|
|
28
28
|
socket.keepAlive = false;
|
|
@@ -93,55 +93,55 @@ async function setCredential(item) {
|
|
|
93
93
|
client.password = password;
|
|
94
94
|
}
|
|
95
95
|
const usePool = item.usePool;
|
|
96
|
-
if (usePool) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
if (!usePool) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
let pool;
|
|
100
|
+
username = undefined;
|
|
101
|
+
password = undefined;
|
|
102
|
+
if (typeof usePool === 'string' && (username = client.username || (0, util_1.parseConnectionString)(uri)?.username)) {
|
|
103
|
+
[password, pool] = DbPool.validateKey(POOL_STATE, username, usePool);
|
|
104
|
+
if (pool) {
|
|
105
|
+
pool.add(item, password);
|
|
106
|
+
return;
|
|
106
107
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (timeout > 0) {
|
|
129
|
-
poolOptions.acquireTimeoutMillis ?? (poolOptions.acquireTimeoutMillis = timeout);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
const target = new RedisPool(await getClient(redis, client, poolKey), poolKey, username && password ? { username, password } : undefined).add(item);
|
|
134
|
-
target.parent = POOL_STATE;
|
|
135
|
-
target.success = 1;
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
item.usePool = false;
|
|
139
|
-
delete client.isolationPoolOptions;
|
|
140
|
-
}
|
|
108
|
+
}
|
|
109
|
+
const poolKey = getPoolKey(client);
|
|
110
|
+
if ((pool = POOL_STATE[poolKey]) && !pool.closed) {
|
|
111
|
+
pool.add(item);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const config = this.getPoolConfig("redis" /* STRINGS.MODULE_NAME */, password);
|
|
115
|
+
const poolOptions = client.isolationPoolOptions || (client.isolationPoolOptions = {});
|
|
116
|
+
if (config) {
|
|
117
|
+
const { min, max, idle, queue_max, queue_idle, timeout } = config;
|
|
118
|
+
if (min >= 0) {
|
|
119
|
+
poolOptions.min ?? (poolOptions.min = min);
|
|
120
|
+
}
|
|
121
|
+
if (max > 0) {
|
|
122
|
+
poolOptions.max ?? (poolOptions.max = max);
|
|
123
|
+
}
|
|
124
|
+
if (idle > 0) {
|
|
125
|
+
poolOptions.idleTimeoutMillis ?? (poolOptions.idleTimeoutMillis = idle);
|
|
126
|
+
}
|
|
127
|
+
if (queue_max >= 0) {
|
|
128
|
+
poolOptions.maxWaitingClients ?? (poolOptions.maxWaitingClients = queue_max);
|
|
141
129
|
}
|
|
142
|
-
|
|
143
|
-
|
|
130
|
+
if (queue_idle > 0) {
|
|
131
|
+
poolOptions.softIdleTimeoutMillis ?? (poolOptions.softIdleTimeoutMillis = queue_idle);
|
|
144
132
|
}
|
|
133
|
+
if (timeout > 0) {
|
|
134
|
+
poolOptions.acquireTimeoutMillis ?? (poolOptions.acquireTimeoutMillis = timeout);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
const target = new RedisPool(await getClient(redis, client, poolKey), poolKey, username && password ? { username, password } : undefined).add(item);
|
|
139
|
+
target.parent = POOL_STATE;
|
|
140
|
+
target.success = 1;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
item.usePool = false;
|
|
144
|
+
delete client.isolationPoolOptions;
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
exports.setCredential = setCredential;
|
|
@@ -204,6 +204,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
204
204
|
item.transactionState &= ~64 /* DB_TRANSACTION.AUTH */;
|
|
205
205
|
return client;
|
|
206
206
|
};
|
|
207
|
+
if (this.host?.username) {
|
|
208
|
+
this.applyCommand(...batch);
|
|
209
|
+
}
|
|
207
210
|
for (let i = 0; i < length; ++i) {
|
|
208
211
|
const item = batch[i];
|
|
209
212
|
const { source, uri, key, format = 'HASH', search, aggregate, update, options: clientOptions = {}, cacheObjectKey, ignoreCache } = item;
|
|
@@ -226,13 +229,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
226
229
|
continue;
|
|
227
230
|
}
|
|
228
231
|
item.transactionState = 1 /* DB_TRANSACTION.ACTIVE */;
|
|
232
|
+
const command = (0, types_1.isPlainObject)(clientOptions.command) ? redis.commandOptions(clientOptions.command) : null;
|
|
229
233
|
const uuidKey = (credential.uuidKey || (credential.uuidKey = (onceCredential ? batch[0] : item).credential?.uuidKey));
|
|
230
234
|
const targetObject = typeof checkObject === 'string' ? this.hasCoerce("redis" /* STRINGS.MODULE_NAME */, 'options', uuidKey) && (0, types_1.asFunction)(checkObject) : checkObject;
|
|
231
|
-
const
|
|
232
|
-
const cacheValue = renewCache ? { sessionKey, renewCache } : sessionKey;
|
|
233
|
-
const command = (0, types_1.isPlainObject)(clientOptions.command) ? redis.commandOptions(clientOptions.command) : null;
|
|
235
|
+
const cacheValue = ignoreCache === undefined ? sessionKey : Array.isArray(ignoreCache) ? { sessionKey, exclusiveOf: ignoreCache } : { sessionKey, renewCache: ignoreCache === 0 };
|
|
234
236
|
let queryString = '', rows;
|
|
235
|
-
if (caching && ignoreCache !== true
|
|
237
|
+
if (caching && ignoreCache !== true) {
|
|
236
238
|
if ((0, types_1.isObject)(search)) {
|
|
237
239
|
queryString = Db.asString(search, true);
|
|
238
240
|
}
|
|
@@ -240,10 +242,10 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
240
242
|
queryString = Db.asString(aggregate, true);
|
|
241
243
|
}
|
|
242
244
|
else if (!targetObject) {
|
|
243
|
-
queryString = Db.asString(key);
|
|
245
|
+
queryString = Db.asString(key, true);
|
|
244
246
|
}
|
|
245
247
|
else if (cacheObjectKey) {
|
|
246
|
-
queryString = Db.asString(key) + '_' + targetObject.toString() + cacheObjectKey;
|
|
248
|
+
queryString = Db.asString(key, true) + '_' + targetObject.toString() + cacheObjectKey;
|
|
247
249
|
}
|
|
248
250
|
if (queryString) {
|
|
249
251
|
queryString += '_' + format;
|
|
@@ -283,65 +285,130 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
283
285
|
const b = (arg) => typeof arg === 'number' || Buffer.isBuffer(arg) ? arg.toString() : arg;
|
|
284
286
|
if (update) {
|
|
285
287
|
commandType = this.commandType.UPDATE;
|
|
286
|
-
const values = (!Array.isArray(update) ? [update] : update).map(target => {
|
|
288
|
+
const values = (!Array.isArray(update) ? [update] : update).map(async (target) => {
|
|
287
289
|
return new Promise(async (success, failed) => {
|
|
288
|
-
let { key: k, value: v, format: f
|
|
289
|
-
|
|
290
|
+
let { key: k, value: v, format: f, NX, XX, options: setOptions = {} } = target;
|
|
291
|
+
f = ((0, types_1.isString)(f) ? f.toUpperCase() : 'HASH');
|
|
292
|
+
if (v === undefined && f !== 'JSON') {
|
|
290
293
|
success(target);
|
|
291
294
|
return;
|
|
292
295
|
}
|
|
296
|
+
const has = (n) => typeof n === 'number' && n > 0;
|
|
293
297
|
const failKey = () => failed((0, types_1.errorMessage)(f, "Invalid key" /* ERR_DB.KEY */, Db.asString(k) || "Unknown" /* ERR_MESSAGE.UNKNOWN */));
|
|
294
298
|
const failValue = () => failed((0, types_1.errorMessage)(f, "Invalid value" /* ERR_DB.VALUE */, Db.asString(v) || "Unknown" /* ERR_MESSAGE.UNKNOWN */));
|
|
295
299
|
const commandSet = (0, types_1.isPlainObject)(setOptions.command) && redis.commandOptions(setOptions.command);
|
|
296
|
-
let pending;
|
|
297
|
-
if (
|
|
300
|
+
let pending, codeMin = 0, EX, PX, EXAT, PXAT, KEEPTTL;
|
|
301
|
+
if (f === 'JSON') {
|
|
298
302
|
if (typeof k !== 'string') {
|
|
299
303
|
failKey();
|
|
300
304
|
return;
|
|
301
305
|
}
|
|
302
|
-
const path = target.path || '$';
|
|
303
306
|
if (this.hasCoerce("redis" /* STRINGS.MODULE_NAME */, 'options', uuidKey)) {
|
|
304
307
|
if ((0, types_1.isString)(v) && v.startsWith('new')) {
|
|
305
308
|
({ outV: v } = (0, types_1.coerceObject)({ outV: v }));
|
|
306
309
|
}
|
|
307
310
|
}
|
|
308
|
-
|
|
309
|
-
|
|
311
|
+
let { path = '$', command: cmd, start, stop, index } = target;
|
|
312
|
+
const name = ((0, types_1.isString)(cmd) ? cmd.toUpperCase() : 'SET');
|
|
313
|
+
if (Array.isArray(v) && name !== 'ARRAPPEND' && name !== 'ARRINSERT' && name !== 'MSET') {
|
|
314
|
+
v = v[0];
|
|
315
|
+
}
|
|
316
|
+
switch (name) {
|
|
317
|
+
case 'ARRAPPEND':
|
|
318
|
+
pending = commandSet ? client.json.arrAppend(commandSet, k, path, ...(Array.isArray(v) ? v : [v])) : client.json.arrAppend(k, path, ...(Array.isArray(v) ? v : [v]));
|
|
319
|
+
break;
|
|
320
|
+
case 'ARRINDEX':
|
|
321
|
+
codeMin = -1;
|
|
322
|
+
pending = commandSet ? client.json.arrIndex(commandSet, k, path, v, start, stop) : client.json.arrIndex(k, path, v, start, stop);
|
|
323
|
+
break;
|
|
324
|
+
case 'ARRINSERT':
|
|
325
|
+
if (typeof index === 'number' || (0, types_1.isString)(index) && !isNaN(index = parseInt(index))) {
|
|
326
|
+
pending = commandSet ? client.json.arrInsert(commandSet, k, path, index, ...(Array.isArray(v) ? v : [v])) : client.json.arrInsert(k, path, index, ...(Array.isArray(v) ? v : [v]));
|
|
327
|
+
}
|
|
328
|
+
break;
|
|
329
|
+
case 'ARRPOP':
|
|
330
|
+
codeMin = -Infinity;
|
|
331
|
+
pending = commandSet ? client.json.arrPop(commandSet, k, path, index) : client.json.arrPop(k, path, index);
|
|
332
|
+
break;
|
|
333
|
+
case 'ARRTRIM':
|
|
334
|
+
if ((typeof start === 'number' || (0, types_1.isString)(start) && !isNaN(start = parseInt(start))) && (typeof stop === 'number' || (0, types_1.isString)(stop) && !isNaN(stop = parseInt(stop)))) {
|
|
335
|
+
pending = commandSet ? client.json.arrTrim(commandSet, k, path, start, stop) : client.json.arrTrim(k, path, start, stop);
|
|
336
|
+
}
|
|
337
|
+
break;
|
|
338
|
+
case 'DEL':
|
|
339
|
+
case 'FORGET':
|
|
340
|
+
pending = commandSet ? client.json[name === 'DEL' ? 'del' : 'forget'](commandSet, k, path) : client.json[name === 'DEL' ? 'del' : 'forget'](k, path);
|
|
341
|
+
break;
|
|
342
|
+
case 'MERGE':
|
|
343
|
+
pending = commandSet ? client.json.merge(commandSet, k, path, v) : client.json.merge(k, path, v);
|
|
344
|
+
break;
|
|
345
|
+
case 'MSET': {
|
|
346
|
+
const data = (Array.isArray(v) ? v : [v])
|
|
347
|
+
.filter((m) => m.value !== undefined)
|
|
348
|
+
.map((m) => {
|
|
349
|
+
m.key || (m.key = k);
|
|
350
|
+
m.path || (m.path = path);
|
|
351
|
+
return m;
|
|
352
|
+
});
|
|
353
|
+
if (data.length) {
|
|
354
|
+
pending = commandSet ? client.json.mSet(commandSet, data) : client.json.mSet(data);
|
|
355
|
+
}
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
case 'NUMINCRBY':
|
|
359
|
+
case 'NUMMULTBY':
|
|
360
|
+
if (typeof v === 'number' || (0, types_1.isString)(v) && !isNaN(v = parseFloat(v))) {
|
|
361
|
+
pending = commandSet ? client.json[name === 'NUMINCRBY' ? 'numIncrBy' : 'numMultBy'](commandSet, k, path, v) : client.json[name === 'NUMINCRBY' ? 'numIncrBy' : 'numMultBy'](k, path, v);
|
|
362
|
+
}
|
|
363
|
+
break;
|
|
364
|
+
case 'STRAPPEND':
|
|
365
|
+
if ((0, types_1.isString)(v)) {
|
|
366
|
+
pending = commandSet ? client.json.strAppend(commandSet, k, path, v) : client.json.strAppend(k, path, v);
|
|
367
|
+
}
|
|
368
|
+
break;
|
|
369
|
+
default: {
|
|
370
|
+
const flags = NX ? { NX } : XX ? { XX } : undefined;
|
|
371
|
+
pending = commandSet ? client.json.set(commandSet, k, path, v, flags) : client.json.set(k, path, v, flags);
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
310
375
|
}
|
|
311
376
|
else if (typeof k === 'string' || Buffer.isBuffer(k)) {
|
|
377
|
+
({ EX, PX, EXAT, PXAT, KEEPTTL } = target);
|
|
312
378
|
const field = target.field;
|
|
313
379
|
if (field === undefined && field === null) {
|
|
314
380
|
if (a(v)) {
|
|
315
|
-
const flags = setOptions.set;
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if ('PXAT' in flags) {
|
|
338
|
-
PXAT || (PXAT = flags.PXAT);
|
|
339
|
-
delete flags.PXAT;
|
|
340
|
-
}
|
|
381
|
+
const flags = setOptions.set || {};
|
|
382
|
+
if (NX) {
|
|
383
|
+
flags.NX = true;
|
|
384
|
+
}
|
|
385
|
+
if (XX) {
|
|
386
|
+
flags.XX = true;
|
|
387
|
+
}
|
|
388
|
+
if (has(EX)) {
|
|
389
|
+
flags.EX = EX;
|
|
390
|
+
EX = 0;
|
|
391
|
+
}
|
|
392
|
+
if (has(PX)) {
|
|
393
|
+
flags.PX = PX;
|
|
394
|
+
PX = 0;
|
|
395
|
+
}
|
|
396
|
+
if (has(EXAT)) {
|
|
397
|
+
flags.EXAT = EXAT;
|
|
398
|
+
EXAT = 0;
|
|
399
|
+
}
|
|
400
|
+
if (has(PXAT)) {
|
|
401
|
+
flags.PXAT = PXAT;
|
|
402
|
+
PXAT = 0;
|
|
341
403
|
}
|
|
342
|
-
|
|
404
|
+
if (KEEPTTL) {
|
|
405
|
+
flags.KEEPTTL = true;
|
|
406
|
+
KEEPTTL = false;
|
|
407
|
+
}
|
|
408
|
+
codeMin = NaN;
|
|
409
|
+
pending = commandSet ? client.set(commandSet, k, v, flags) : client.set(k, v, flags);
|
|
343
410
|
}
|
|
344
|
-
else if (
|
|
411
|
+
else if ((0, types_1.isObject)(v)) {
|
|
345
412
|
let valid = true;
|
|
346
413
|
if (NX || XX) {
|
|
347
414
|
valid = await client.exists(k) === 1;
|
|
@@ -358,6 +425,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
358
425
|
}
|
|
359
426
|
else if (NX) {
|
|
360
427
|
if (a(field) && a(v)) {
|
|
428
|
+
codeMin = -1;
|
|
361
429
|
pending = commandSet ? client.hSetNX(commandSet, k, b(field), b(v)) : client.hSetNX(k, b(field), b(v));
|
|
362
430
|
}
|
|
363
431
|
}
|
|
@@ -380,43 +448,52 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
380
448
|
return;
|
|
381
449
|
}
|
|
382
450
|
if (pending) {
|
|
383
|
-
pending.then(code => {
|
|
384
|
-
if (code === 'OK' || typeof code === 'number' || code ===
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
451
|
+
pending.then(async (code) => {
|
|
452
|
+
if (code === undefined || code === null || code !== -Infinity && (0, types_1.isString)(code) && code !== 'OK' || typeof code === 'number' && code <= codeMin || Array.isArray(code) && code.every(resp => resp === null || typeof resp === 'number' && resp <= codeMin)) {
|
|
453
|
+
failValue();
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
let ttl = false;
|
|
457
|
+
if (!isNaN(codeMin) && (has(EX) || has(PX) || has(EXAT) || has(PXAT) || (ttl = !!KEEPTTL))) {
|
|
458
|
+
const expire = setOptions.expire;
|
|
459
|
+
let mode;
|
|
460
|
+
if (expire) {
|
|
461
|
+
if (expire.NX) {
|
|
462
|
+
mode = 'NX';
|
|
463
|
+
}
|
|
464
|
+
else if (expire.XX) {
|
|
465
|
+
mode = 'XX';
|
|
466
|
+
}
|
|
467
|
+
else if (expire.GT) {
|
|
468
|
+
mode = 'GT';
|
|
469
|
+
}
|
|
470
|
+
else if (expire.LT) {
|
|
471
|
+
mode = 'LT';
|
|
402
472
|
}
|
|
403
|
-
(has(EX) ? client.expire(k, EX, mode) : has(PX) ? client.pExpire(k, PX, mode) : EXAT > 0 ? client.expireAt(k, EXAT, mode) : client.pExpireAt(k, PXAT, mode))
|
|
404
|
-
.then(valid => {
|
|
405
|
-
if (valid) {
|
|
406
|
-
success(target);
|
|
407
|
-
}
|
|
408
|
-
else {
|
|
409
|
-
failed((0, types_1.errorMessage)(f, "Invalid value" /* ERR_DB.VALUE */, has(EX) ? 'EX: ' + EX : has(PX) ? 'PX: ' + PX : EXAT > 0 ? 'EXAT: ' + EX : 'PXAT: ' + PXAT));
|
|
410
|
-
}
|
|
411
|
-
})
|
|
412
|
-
.catch(err => failed(err));
|
|
413
473
|
}
|
|
414
|
-
|
|
415
|
-
|
|
474
|
+
if (ttl) {
|
|
475
|
+
PX = await client.pTTL(k).catch(err => {
|
|
476
|
+
failed(err);
|
|
477
|
+
return 0;
|
|
478
|
+
});
|
|
479
|
+
if (PX <= 0) {
|
|
480
|
+
success(target);
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
416
483
|
}
|
|
484
|
+
(has(EX) ? client.expire(k, EX, mode) : has(PX) ? client.pExpire(k, PX, mode) : has(EXAT) ? client.expireAt(k, EXAT, mode) : client.pExpireAt(k, PXAT, mode))
|
|
485
|
+
.then(valid => {
|
|
486
|
+
if (valid) {
|
|
487
|
+
success(target);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
failed((0, types_1.errorMessage)(f, "Invalid value" /* ERR_DB.VALUE */, has(EX) ? 'EX: ' + EX : has(PX) ? 'PX: ' + PX : has(EXAT) ? 'EXAT: ' + EX : 'PXAT: ' + PXAT));
|
|
491
|
+
}
|
|
492
|
+
})
|
|
493
|
+
.catch(err => failed(err));
|
|
417
494
|
}
|
|
418
495
|
else {
|
|
419
|
-
|
|
496
|
+
success(target);
|
|
420
497
|
}
|
|
421
498
|
})
|
|
422
499
|
.catch(err => failed(err));
|
|
@@ -460,13 +537,14 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
460
537
|
}
|
|
461
538
|
}
|
|
462
539
|
catch (err) {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
client.ft.dropIndex(idx).catch(err => this.writeFail([`Unable to drop ${target === search ? 'search' : 'aggregate'} index`, idx], err, { type: 65536 /* LOG_TYPE.DB */, fatal: false }));
|
|
540
|
+
if (err instanceof Error) {
|
|
541
|
+
throw err;
|
|
542
|
+
}
|
|
467
543
|
}
|
|
468
|
-
|
|
469
|
-
|
|
544
|
+
finally {
|
|
545
|
+
if (idx && idx !== index) {
|
|
546
|
+
client.ft.dropIndex(idx).catch(err => this.writeFail([`Unable to drop ${target === search ? 'search' : 'aggregate'} index`, idx], err, { type: 65536 /* LOG_TYPE.DB */, fatal: false }));
|
|
547
|
+
}
|
|
470
548
|
}
|
|
471
549
|
}
|
|
472
550
|
else if (key) {
|
|
@@ -474,10 +552,10 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
474
552
|
if (Array.isArray(key)) {
|
|
475
553
|
switch (format.toUpperCase()) {
|
|
476
554
|
case 'HKEYS':
|
|
477
|
-
data = await Promise.all(key.map(k => client.hKeys(...command ? [command, k] : [k])));
|
|
555
|
+
data = await Promise.all(key.map(async (k) => client.hKeys(...command ? [command, k] : [k])));
|
|
478
556
|
break;
|
|
479
557
|
case 'HVALS':
|
|
480
|
-
data = await Promise.all(key.map(k => client.hVals(...command ? [command, k] : [k])));
|
|
558
|
+
data = await Promise.all(key.map(async (k) => client.hVals(...command ? [command, k] : [k])));
|
|
481
559
|
break;
|
|
482
560
|
case 'JSON':
|
|
483
561
|
data = (await (command ? client.json.mGet(command, key.map(c => b(c)), item.path || '$') : client.json.mGet(key.map(c => b(c)), item.path || '$'))).flat();
|
|
@@ -548,12 +626,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
548
626
|
}
|
|
549
627
|
}
|
|
550
628
|
return this.processRows(batch, tasks, {
|
|
551
|
-
disconnect: () => clients.forEach(item => item.disconnect()),
|
|
629
|
+
disconnect: () => clients.forEach(async (item) => item.disconnect()),
|
|
552
630
|
parallel
|
|
553
631
|
}, outResult);
|
|
554
632
|
}
|
|
555
633
|
exports.executeBatchQuery = executeBatchQuery;
|
|
556
|
-
function checkTimeout(value, limit = 0) {
|
|
634
|
+
async function checkTimeout(value, limit = 0) {
|
|
557
635
|
return DbPool.checkTimeout(POOL_STATE, value, limit);
|
|
558
636
|
}
|
|
559
637
|
exports.checkTimeout = checkTimeout;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/redis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Redis client driver for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"types": "client/index.d.ts",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@e-mc/db": "^0.
|
|
25
|
-
"@e-mc/types": "^0.
|
|
26
|
-
"redis": "^4.6.
|
|
24
|
+
"@e-mc/db": "^0.8.1",
|
|
25
|
+
"@e-mc/types": "^0.8.1",
|
|
26
|
+
"redis": "^4.6.12"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ import type { DbDataSource } from '@e-mc/types/lib/squared';
|
|
|
3
3
|
import type { CascadeAction, ExecuteAction, ServerAuth } from '@e-mc/types/lib/db';
|
|
4
4
|
|
|
5
5
|
import type { CommandOptions } from '@redis/client/dist/lib/command-options';
|
|
6
|
-
import type { ClientCommandOptions } from '@redis/client/dist/lib/client';
|
|
6
|
+
import type { ClientCommandOptions, JMSetItem } from '@redis/client/dist/lib/client';
|
|
7
7
|
import type { RedisClientOptions } from '@redis/client';
|
|
8
8
|
import type { RedisCommandArgument } from '@redis/client/dist/lib/commands';
|
|
9
9
|
import type { RedisJSON } from '@redis/json/dist/commands';
|
|
10
|
-
import type { AggregateOptions, RediSearchSchema, SearchOptions } from 'redis';
|
|
10
|
+
import type { AggregateOptions, RediSearchSchema, SearchOptions, SetOptions } from 'redis';
|
|
11
11
|
|
|
12
12
|
export interface RedisDataSource extends DbDataSource<string, PlainObject, ArrayOf<RedisSetValue> | ArrayOf<RedisJSONValue>, string | RedisCredential, string>, CascadeAction, AuthValue {
|
|
13
13
|
source: "redis";
|
|
@@ -29,26 +29,35 @@ export interface RedisDataSource extends DbDataSource<string, PlainObject, Array
|
|
|
29
29
|
|
|
30
30
|
export type RedisCredential = ServerAuth;
|
|
31
31
|
|
|
32
|
-
export interface
|
|
32
|
+
export interface RedisCommand<T = "HASH" | "JSON" | undefined, U = unknown, V = unknown> {
|
|
33
33
|
format: T;
|
|
34
|
+
command?: string;
|
|
34
35
|
key?: U;
|
|
35
|
-
field?: V;
|
|
36
36
|
value?: V;
|
|
37
37
|
NX?: boolean;
|
|
38
38
|
XX?: boolean;
|
|
39
|
-
EX?: number;
|
|
40
|
-
PX?: number;
|
|
41
|
-
EXAT?: number;
|
|
42
|
-
PXAT?: number;
|
|
43
39
|
options?: {
|
|
44
|
-
set?:
|
|
40
|
+
set?: SetOptions;
|
|
45
41
|
expire?: { [K in RedisExpireCondition]?: boolean; };
|
|
46
42
|
command?: RedisCommandOptions;
|
|
47
43
|
};
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
export interface
|
|
46
|
+
export interface RedisSetValue extends RedisCommand<"HASH", RedisCommandArgument, RedisCommandValue | RedisHSETObject> {
|
|
47
|
+
field?: RedisCommandValue | RedisHSETObject;
|
|
48
|
+
EX?: number;
|
|
49
|
+
PX?: number;
|
|
50
|
+
EXAT?: number;
|
|
51
|
+
PXAT?: number;
|
|
52
|
+
KEEPTTL?: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface RedisJSONValue extends RedisCommand<"JSON", string, ArrayOf<RedisJSON>> {
|
|
56
|
+
command?: RedisCommandJSON;
|
|
51
57
|
path?: string;
|
|
58
|
+
start?: NumString;
|
|
59
|
+
stop?: NumString;
|
|
60
|
+
index?: NumString;
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
export interface RedisQuery {
|
|
@@ -58,7 +67,14 @@ export interface RedisQuery {
|
|
|
58
67
|
options?: PlainObject;
|
|
59
68
|
}
|
|
60
69
|
|
|
70
|
+
export interface JsonMSetItem {
|
|
71
|
+
key: RedisCommandArgument;
|
|
72
|
+
path: RedisCommandArgument;
|
|
73
|
+
value: RedisJSON;
|
|
74
|
+
}
|
|
75
|
+
|
|
61
76
|
export type RedisFormat = "HASH" | "JSON";
|
|
77
|
+
export type RedisCommandJSON = "ARRAPPEND" | "ARRINDEX" | "ARRINSERT" | "ARRPOP" | "ARRTRIM" | "DEL" | "FORGET" | "MERGE" | "MSET" | "NUMINCRBY" | "NUMMULTBY" | "SET" | "STRAPPEND";
|
|
62
78
|
export type RedisExpireCondition = "NX" | "XX" | "GT" | "LT";
|
|
63
79
|
export type RedisCommandValue = RedisCommandArgument | number;
|
|
64
80
|
export type RedisCommandOptions = CommandOptions<ClientCommandOptions>;
|