@pi-r/redis 0.9.4 → 0.10.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 +30 -42
- package/client/pool.js +4 -0
- package/package.json +4 -4
- package/types/index.d.ts +4 -5
package/client/index.js
CHANGED
|
@@ -34,21 +34,14 @@ async function getClient(db, options, poolKey) {
|
|
|
34
34
|
else if (typeof socket.keepAlive !== 'number') {
|
|
35
35
|
socket.keepAlive = undefined;
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
delete POOL_STATE[poolKey];
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
client.connect()
|
|
45
|
-
.then(() => {
|
|
46
|
-
resolve(client);
|
|
47
|
-
})
|
|
48
|
-
.catch((err) => {
|
|
49
|
-
reject(err);
|
|
37
|
+
const client = db.createClient(options);
|
|
38
|
+
if (poolKey) {
|
|
39
|
+
client.on('end', () => {
|
|
40
|
+
delete POOL_STATE[poolKey];
|
|
50
41
|
});
|
|
51
|
-
}
|
|
42
|
+
}
|
|
43
|
+
await client.connect();
|
|
44
|
+
return client;
|
|
52
45
|
}
|
|
53
46
|
async function setCredential(item) {
|
|
54
47
|
const credential = this.getCredential(item);
|
|
@@ -71,7 +64,7 @@ async function setCredential(item) {
|
|
|
71
64
|
delete item.credential;
|
|
72
65
|
}
|
|
73
66
|
if (!uri) {
|
|
74
|
-
throw (0, types_1.errorMessage)("redis",
|
|
67
|
+
throw (0, types_1.errorMessage)("redis", "Invalid credentials", 'url');
|
|
75
68
|
}
|
|
76
69
|
if (client.socket?.tls) {
|
|
77
70
|
this.readTLSConfig(client.socket);
|
|
@@ -91,7 +84,8 @@ async function setCredential(item) {
|
|
|
91
84
|
username = undefined;
|
|
92
85
|
password = undefined;
|
|
93
86
|
if ((0, types_1.isString)(usePool)) {
|
|
94
|
-
|
|
87
|
+
username = client.username || (0, util_1.parseConnectionString)(uri)?.username;
|
|
88
|
+
if (username) {
|
|
95
89
|
[password, pool] = DbPool.validateKey(POOL_STATE, username, usePool);
|
|
96
90
|
if (pool) {
|
|
97
91
|
pool.add(item, password);
|
|
@@ -106,22 +100,13 @@ async function setCredential(item) {
|
|
|
106
100
|
const config = this.getPoolConfig("redis", password);
|
|
107
101
|
const poolOptions = client.isolationPoolOptions ||= {};
|
|
108
102
|
if (config) {
|
|
109
|
-
const { min, max,
|
|
103
|
+
const { min, max, timeout } = config;
|
|
110
104
|
if (min >= 0) {
|
|
111
105
|
poolOptions.min ??= min;
|
|
112
106
|
}
|
|
113
107
|
if (max > 0) {
|
|
114
108
|
poolOptions.max ??= max;
|
|
115
109
|
}
|
|
116
|
-
if (idle > 0) {
|
|
117
|
-
poolOptions.idleTimeoutMillis ??= idle;
|
|
118
|
-
}
|
|
119
|
-
if (queue_max >= 0) {
|
|
120
|
-
poolOptions.maxWaitingClients ??= queue_max;
|
|
121
|
-
}
|
|
122
|
-
if (queue_idle > 0) {
|
|
123
|
-
poolOptions.softIdleTimeoutMillis ??= queue_idle;
|
|
124
|
-
}
|
|
125
110
|
if (timeout > 0) {
|
|
126
111
|
poolOptions.acquireTimeoutMillis ??= timeout;
|
|
127
112
|
}
|
|
@@ -204,9 +189,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
204
189
|
}
|
|
205
190
|
for (let i = 0; i < length; ++i) {
|
|
206
191
|
const item = batch[i];
|
|
207
|
-
const { source,
|
|
192
|
+
const { source, key, format = 'HASH', search, aggregate, options: clientOptions = {}, ignoreCache } = item;
|
|
208
193
|
let credential = (redisCredential || onceCredential), error;
|
|
209
|
-
if (!credential && !(0, types_1.isPlainObject)(credential = clientOptions.client) && (error = (0, types_1.errorMessage)(source, "Invalid credentials")) || !((0, types_1.isString)(key) || (0, types_1.isArray)(key) || (0, types_1.isPlainObject)(search) && ((0, types_1.isPlainObject)(search.schema) || (0, types_1.isString)(search.query)) || (0, types_1.isPlainObject)(aggregate) && ((0, types_1.isPlainObject)(aggregate.schema) || (0, types_1.isString)(aggregate.query))) && (error = (0, types_1.errorMessage)(source, "Missing database query", uri))) {
|
|
194
|
+
if (!credential && !(0, types_1.isPlainObject)(credential = clientOptions.client) && (error = (0, types_1.errorMessage)(source, "Invalid credentials")) || !((0, types_1.isString)(key) || (0, types_1.isArray)(key) || (0, types_1.isPlainObject)(search) && ((0, types_1.isPlainObject)(search.schema) || (0, types_1.isString)(search.query)) || (0, types_1.isPlainObject)(aggregate) && ((0, types_1.isPlainObject)(aggregate.schema) || (0, types_1.isString)(aggregate.query))) && (error = (0, types_1.errorMessage)(source, "Missing database query", item.uri))) {
|
|
210
195
|
++redisCache;
|
|
211
196
|
if (this.handleFail(error, item, { errorQuery })) {
|
|
212
197
|
if (!parallel) {
|
|
@@ -228,6 +213,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
228
213
|
const uuidKey = credential.uuidKey ||= (onceCredential ? batch[0] : item).credential?.uuidKey;
|
|
229
214
|
const targetObject = typeof checkObject === 'string' ? this.hasCoerce("redis", 'options', uuidKey) && (0, types_1.asFunction)(checkObject) : checkObject;
|
|
230
215
|
const cacheValue = ignoreCache === undefined ? sessionKey : Array.isArray(ignoreCache) ? { sessionKey, exclusiveOf: ignoreCache } : { sessionKey, renewCache: ignoreCache === 0 };
|
|
216
|
+
if (command) {
|
|
217
|
+
command.signal ||= this.signal;
|
|
218
|
+
}
|
|
231
219
|
let queryString = '', rows;
|
|
232
220
|
if (caching && ignoreCache !== true) {
|
|
233
221
|
if ((0, types_1.isObject)(search)) {
|
|
@@ -239,14 +227,15 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
239
227
|
else if (!targetObject) {
|
|
240
228
|
queryString = Db.asString(key, true);
|
|
241
229
|
}
|
|
242
|
-
else if (cacheObjectKey) {
|
|
243
|
-
queryString = Db.asString(key, true) + '_' + targetObject.toString() + cacheObjectKey;
|
|
230
|
+
else if (item.cacheObjectKey) {
|
|
231
|
+
queryString = Db.asString(key, true) + '_' + targetObject.toString() + item.cacheObjectKey;
|
|
244
232
|
}
|
|
245
233
|
if (queryString) {
|
|
246
234
|
queryString += '_' + format;
|
|
247
235
|
}
|
|
248
236
|
if (ignoreCache !== 1) {
|
|
249
|
-
|
|
237
|
+
rows = this.getQueryResult(source, DbPool.sanitize(credential), queryString, cacheValue);
|
|
238
|
+
if (rows) {
|
|
250
239
|
++redisCache;
|
|
251
240
|
if (parallel) {
|
|
252
241
|
tasks[i] = Promise.resolve(rows);
|
|
@@ -278,9 +267,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
278
267
|
const client = redisClient || await getConnection(item, credential);
|
|
279
268
|
const a = (arg) => typeof arg === 'string' || Buffer.isBuffer(arg) || typeof arg === 'number';
|
|
280
269
|
const b = (arg) => typeof arg === 'number' || Buffer.isBuffer(arg) ? arg.toString() : arg;
|
|
281
|
-
if (update) {
|
|
270
|
+
if (item.update) {
|
|
282
271
|
commandType = this.commandType.UPDATE;
|
|
283
|
-
const values = (!Array.isArray(update) ? [update] : update).map(async (target) => {
|
|
272
|
+
const values = (!Array.isArray(item.update) ? [item.update] : item.update).map(async (target) => {
|
|
284
273
|
return new Promise(async (success, failed) => {
|
|
285
274
|
let { key: k, value: v, format: f, NX, XX, options: setOptions = {} } = target;
|
|
286
275
|
f = ((0, types_1.isString)(f) ? f.toUpperCase() : 'HASH');
|
|
@@ -487,17 +476,13 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
487
476
|
failed((0, types_1.errorMessage)(f, "Invalid value", has(EX) ? 'EX: ' + EX : has(PX) ? 'PX: ' + PX : has(EXAT) ? 'EXAT: ' + EX : 'PXAT: ' + PXAT));
|
|
488
477
|
}
|
|
489
478
|
})
|
|
490
|
-
.catch(
|
|
491
|
-
failed(err);
|
|
492
|
-
});
|
|
479
|
+
.catch(failed);
|
|
493
480
|
}
|
|
494
481
|
else {
|
|
495
482
|
success(target);
|
|
496
483
|
}
|
|
497
484
|
})
|
|
498
|
-
.catch(
|
|
499
|
-
failed(err);
|
|
500
|
-
});
|
|
485
|
+
.catch(failed);
|
|
501
486
|
}
|
|
502
487
|
else {
|
|
503
488
|
failValue();
|
|
@@ -538,7 +523,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
538
523
|
}
|
|
539
524
|
}
|
|
540
525
|
catch (err) {
|
|
541
|
-
this.addLog(this.statusType.WARN, err,
|
|
526
|
+
this.addLog(this.statusType.WARN, err, { source: target === search ? 'FT.SEARCH' : 'FT.AGGREGATE' });
|
|
542
527
|
if (err instanceof Error) {
|
|
543
528
|
throw err;
|
|
544
529
|
}
|
|
@@ -587,7 +572,10 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
587
572
|
data = await (clientOptions.get ? client.json.get(...command ? [command, b(key), clientOptions.get] : [b(key), clientOptions.get]) : client.json.get(...command ? [command, b(key)] : [b(key)]));
|
|
588
573
|
break;
|
|
589
574
|
default:
|
|
590
|
-
if (item.field) {
|
|
575
|
+
if (Array.isArray(item.field)) {
|
|
576
|
+
data = await client.hmGet(...command ? [command, key, item.field] : [key, item.field]);
|
|
577
|
+
}
|
|
578
|
+
else if (item.field) {
|
|
591
579
|
data = await client.hGet(...command ? [command, key, item.field] : [key, item.field]);
|
|
592
580
|
}
|
|
593
581
|
else {
|
|
@@ -635,7 +623,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
635
623
|
}
|
|
636
624
|
}
|
|
637
625
|
}
|
|
638
|
-
return this.processRows(batch, tasks, {
|
|
626
|
+
return this.processRows(batch, tasks, clients.length === 0 ? parallel : {
|
|
639
627
|
parallel,
|
|
640
628
|
disconnect() {
|
|
641
629
|
for (const item of clients) {
|
package/client/pool.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const DbPool = require('@e-mc/db/pool');
|
|
3
3
|
const POOL_ACTIVE = new WeakSet();
|
|
4
4
|
class RedisPool extends DbPool {
|
|
5
|
+
static CACHE_IGNORE = ['modules', 'functions', 'scripts'];
|
|
5
6
|
static asString(credential) {
|
|
6
7
|
if (credential.url) {
|
|
7
8
|
return JSON.stringify(credential);
|
|
@@ -9,6 +10,9 @@ class RedisPool extends DbPool {
|
|
|
9
10
|
return super.asString(credential);
|
|
10
11
|
}
|
|
11
12
|
static sanitize(credential) {
|
|
13
|
+
if (!this.canCache(credential)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
12
16
|
if (!POOL_ACTIVE.has(credential) || credential.uuidKey) {
|
|
13
17
|
return credential;
|
|
14
18
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/redis",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Redis client driver for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"types": "client/index.d.ts",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/db": "^0.
|
|
24
|
-
"@e-mc/types": "^0.
|
|
25
|
-
"redis": "^4.7.
|
|
23
|
+
"@e-mc/db": "^0.12.3",
|
|
24
|
+
"@e-mc/types": "^0.12.3",
|
|
25
|
+
"redis": "^4.7.1"
|
|
26
26
|
}
|
|
27
27
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -4,20 +4,19 @@ import type { IdentifierAction } from '@e-mc/types/lib/core';
|
|
|
4
4
|
import type { CascadeAction, ServerAuth } from '@e-mc/types/lib/db';
|
|
5
5
|
import type { AuthValue } from '@e-mc/types/lib/http';
|
|
6
6
|
|
|
7
|
+
import type { RedisJSON } from '@redis/json/dist/commands';
|
|
7
8
|
import type { ClientCommandOptions } from '@redis/client/dist/lib/client';
|
|
8
9
|
import type { RedisCommandArgument } from '@redis/client/dist/lib/commands';
|
|
9
10
|
import type { CommandOptions } from '@redis/client/dist/lib/command-options';
|
|
10
|
-
import type { RedisClientOptions } from '@redis/client';
|
|
11
|
-
import type { RedisJSON } from '@redis/json/dist/commands';
|
|
12
11
|
import type { AggregateOptions } from '@redis/search/dist/commands/AGGREGATE';
|
|
13
|
-
import type { HScanTuple } from '@redis
|
|
12
|
+
import type { HScanTuple } from '@redis/client/dist/lib/commands/HSCAN';
|
|
14
13
|
import type { ScanOptions } from '@redis/client/dist/lib/commands/generic-transformers';
|
|
15
|
-
import type { RediSearchSchema, SearchOptions, SetOptions } from 'redis';
|
|
14
|
+
import type { RediSearchSchema, RedisClientOptions, SearchOptions, SetOptions } from 'redis';
|
|
16
15
|
|
|
17
16
|
export interface RedisDataSource extends DbDataSource<string, PlainObject, RedisSetValue | RedisSetValue[] | RedisJSONValue | RedisJSONValue[], RedisCredential, string>, CascadeAction, AuthValue {
|
|
18
17
|
source: "redis";
|
|
19
18
|
key?: RedisCommandArgument | RedisCommandArgument[];
|
|
20
|
-
field?: RedisCommandArgument;
|
|
19
|
+
field?: RedisCommandArgument | string[];
|
|
21
20
|
path?: string;
|
|
22
21
|
format?: RedisFormat | "HKEYS" | "HVALS" | "HSCAN";
|
|
23
22
|
search?: RedisQuery;
|