@pi-r/redis 0.2.2 → 0.2.9
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/LICENSE +1 -1
- package/README.md +4 -2
- package/client/index.d.ts +2 -2
- package/client/index.js +41 -32
- package/package.json +5 -5
- package/types/index.d.ts +13 -8
package/LICENSE
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright
|
|
1
|
+
Copyright 2020-24 Code Geass
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
package/README.md
CHANGED
package/client/index.d.ts
CHANGED
package/client/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const util_1 = require("@e-mc/db/util");
|
|
|
5
5
|
const types_1 = require("@e-mc/types");
|
|
6
6
|
const Db = require("@e-mc/db");
|
|
7
7
|
const DbPool = require('@e-mc/db/pool');
|
|
8
|
-
const REDIS_V4 = Db.checkSemVer("redis"
|
|
8
|
+
const REDIS_V4 = Db.checkSemVer("redis", 4);
|
|
9
9
|
class RedisPool extends DbPool {
|
|
10
10
|
getConnection() {
|
|
11
11
|
return Promise.resolve(this.client);
|
|
@@ -39,16 +39,16 @@ function getClient(db, options, poolKey) {
|
|
|
39
39
|
client.connect().then(() => resolve(client)).catch(err => reject(err));
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
function removePoolProperties(options) {
|
|
43
43
|
if (!options.uuidKey && ('socket' in options || 'isolationPoolOptions' in options)) {
|
|
44
44
|
return { ...options, socket: options.socket?.tls ? { tls: true } : undefined, isolationPoolOptions: undefined };
|
|
45
45
|
}
|
|
46
46
|
return options;
|
|
47
|
-
}
|
|
47
|
+
}
|
|
48
48
|
const getPoolKey = (options) => options.url + '_' + (options.username || '') + '_' + (options.password || '') + '_' + (options.database ?? '') + '_' + (options.socket?.tls ? '1' : '0') + '_' + (options.legacyMode ? '1' : '0');
|
|
49
49
|
async function setCredential(item) {
|
|
50
50
|
if (!REDIS_V4) {
|
|
51
|
-
throw (0, types_1.errorValue)("Upgrade client to latest version"
|
|
51
|
+
throw (0, types_1.errorValue)("Upgrade client to latest version", "redis" + '@' + Db.getPackageVersion("redis"));
|
|
52
52
|
}
|
|
53
53
|
const credential = this.getCredential(item);
|
|
54
54
|
const options = item.options || (item.options = {});
|
|
@@ -58,7 +58,7 @@ async function setCredential(item) {
|
|
|
58
58
|
client.database = database;
|
|
59
59
|
}
|
|
60
60
|
if (credential) {
|
|
61
|
-
const auth = (0, util_1.parseServerAuth)(credential, 6379
|
|
61
|
+
const auth = (0, util_1.parseServerAuth)(credential, 6379);
|
|
62
62
|
if (!client.database) {
|
|
63
63
|
if ('database' in credential) {
|
|
64
64
|
const value = credential.database;
|
|
@@ -71,7 +71,7 @@ async function setCredential(item) {
|
|
|
71
71
|
client.database = database;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
uri || (uri = (auth.protocol || 'redis:') + '//' + (auth.server || 'localhost:' + (auth.port ? auth.port : 6379
|
|
74
|
+
uri || (uri = (auth.protocol || 'redis:') + '//' + (auth.server || 'localhost:' + (auth.port ? auth.port : 6379)));
|
|
75
75
|
username || (username = auth.username);
|
|
76
76
|
password || (password = auth.password);
|
|
77
77
|
}
|
|
@@ -79,7 +79,7 @@ async function setCredential(item) {
|
|
|
79
79
|
delete item.credential;
|
|
80
80
|
}
|
|
81
81
|
if (!uri) {
|
|
82
|
-
throw (0, types_1.errorMessage)("redis"
|
|
82
|
+
throw (0, types_1.errorMessage)("redis", 'Not defined - uri');
|
|
83
83
|
}
|
|
84
84
|
if (client.socket?.tls) {
|
|
85
85
|
this.readTLSConfig(client.socket);
|
|
@@ -105,8 +105,8 @@ async function setCredential(item) {
|
|
|
105
105
|
}
|
|
106
106
|
const poolKey = getPoolKey(client);
|
|
107
107
|
if (!(pool = POOL_STATE[poolKey]) || pool.closed) {
|
|
108
|
-
const db = require("redis"
|
|
109
|
-
const config = this.getPoolConfig("redis"
|
|
108
|
+
const db = require("redis");
|
|
109
|
+
const config = this.getPoolConfig("redis", password);
|
|
110
110
|
const poolOptions = client.isolationPoolOptions || (client.isolationPoolOptions = {});
|
|
111
111
|
if (config) {
|
|
112
112
|
const { min, max, idle, queue_max, queue_idle } = config;
|
|
@@ -151,7 +151,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
151
151
|
if (length === 0) {
|
|
152
152
|
return [];
|
|
153
153
|
}
|
|
154
|
-
const db = require("redis"
|
|
154
|
+
const db = require("redis");
|
|
155
155
|
let parallel, checkObject, connectOnce, errorQuery, sessionKey, outCacheMiss;
|
|
156
156
|
if ((0, types_1.isPlainObject)(options)) {
|
|
157
157
|
({ parallel, checkObject, connectOnce, errorQuery, sessionKey, outCacheMiss } = options);
|
|
@@ -172,12 +172,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
172
172
|
if (!parallel) {
|
|
173
173
|
outResult || (outResult = new Array(length));
|
|
174
174
|
}
|
|
175
|
-
const caching = this.hasCache("redis"
|
|
175
|
+
const caching = this.hasCache("redis", sessionKey);
|
|
176
176
|
const tasks = new Array(length);
|
|
177
177
|
const clients = [];
|
|
178
178
|
let redisClient, redisCredential, redisCache = 0, onceCredential = connectOnce ? batch[0].options?.client : undefined;
|
|
179
179
|
const getConnection = async (item, credential) => {
|
|
180
|
-
item.transactionState = 64
|
|
180
|
+
item.transactionState = 64;
|
|
181
181
|
let client;
|
|
182
182
|
if (item.usePool) {
|
|
183
183
|
const pool = DbPool.findKey(POOL_STATE, item.usePool, getPoolKey(credential), ...connectOnce ? [item, batch[0]] : [item]);
|
|
@@ -199,14 +199,14 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
199
199
|
redisClient = client;
|
|
200
200
|
redisCredential = credential;
|
|
201
201
|
}
|
|
202
|
-
item.transactionState &= ~64
|
|
202
|
+
item.transactionState &= ~64;
|
|
203
203
|
return client;
|
|
204
204
|
};
|
|
205
205
|
for (let i = 0; i < length; ++i) {
|
|
206
206
|
const item = batch[i];
|
|
207
|
-
const { source, uri, key, format = 'HASH', search, update, options: clientOptions = {}, cacheObjectKey, ignoreCache } = item;
|
|
207
|
+
const { source, uri, key, format = 'HASH', search, aggregate, update, options: clientOptions = {}, cacheObjectKey, ignoreCache } = item;
|
|
208
208
|
let credential = (redisCredential || onceCredential), error;
|
|
209
|
-
if (!credential && !(0, types_1.isPlainObject)(credential = clientOptions.client) && (error = (0, types_1.errorMessage)(source, "Invalid credentials"
|
|
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))) {
|
|
210
210
|
++redisCache;
|
|
211
211
|
if (this.handleFail(error, item, { errorQuery })) {
|
|
212
212
|
if (!parallel) {
|
|
@@ -223,9 +223,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
223
223
|
}
|
|
224
224
|
continue;
|
|
225
225
|
}
|
|
226
|
-
item.transactionState = 1
|
|
226
|
+
item.transactionState = 1;
|
|
227
227
|
const uuidKey = (credential.uuidKey || (credential.uuidKey = (onceCredential ? batch[0] : item).credential?.uuidKey));
|
|
228
|
-
const targetObject = typeof checkObject === 'string' ? this.hasCoerce("redis"
|
|
228
|
+
const targetObject = typeof checkObject === 'string' ? this.hasCoerce("redis", 'options', uuidKey) && (0, types_1.asFunction)(checkObject) : checkObject;
|
|
229
229
|
const renewCache = ignoreCache === 0;
|
|
230
230
|
const cacheValue = renewCache ? { sessionKey, renewCache } : sessionKey;
|
|
231
231
|
const command = (0, types_1.isPlainObject)(clientOptions.command) ? db.commandOptions(clientOptions.command) : null;
|
|
@@ -234,6 +234,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
234
234
|
if ((0, types_1.isObject)(search)) {
|
|
235
235
|
queryString = Db.asString(search, true);
|
|
236
236
|
}
|
|
237
|
+
else if ((0, types_1.isObject)(aggregate)) {
|
|
238
|
+
queryString = Db.asString(aggregate, true);
|
|
239
|
+
}
|
|
237
240
|
else if (!targetObject) {
|
|
238
241
|
queryString = Db.asString(key);
|
|
239
242
|
}
|
|
@@ -252,7 +255,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
252
255
|
else {
|
|
253
256
|
outResult[i] = rows;
|
|
254
257
|
}
|
|
255
|
-
this.add(item, 4
|
|
258
|
+
this.add(item, 4 | 128);
|
|
256
259
|
continue;
|
|
257
260
|
}
|
|
258
261
|
if (!ignoreCache && outCacheMiss) {
|
|
@@ -285,8 +288,8 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
285
288
|
success(target);
|
|
286
289
|
return;
|
|
287
290
|
}
|
|
288
|
-
const failKey = () => failed((0, types_1.errorMessage)(f, "Invalid key"
|
|
289
|
-
const failValue = () => failed((0, types_1.errorMessage)(f, "Invalid value"
|
|
291
|
+
const failKey = () => failed((0, types_1.errorMessage)(f, "Invalid key", Db.asString(k) || "Unknown"));
|
|
292
|
+
const failValue = () => failed((0, types_1.errorMessage)(f, "Invalid value", Db.asString(v) || "Unknown"));
|
|
290
293
|
const commandSet = (0, types_1.isPlainObject)(setOptions.command) && db.commandOptions(setOptions.command);
|
|
291
294
|
let pending;
|
|
292
295
|
if ((f = f.toUpperCase()) === 'JSON') {
|
|
@@ -295,7 +298,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
295
298
|
return;
|
|
296
299
|
}
|
|
297
300
|
const path = target.path || '$';
|
|
298
|
-
if (this.hasCoerce("redis"
|
|
301
|
+
if (this.hasCoerce("redis", 'options', uuidKey)) {
|
|
299
302
|
if ((0, types_1.isString)(v) && v.startsWith('new')) {
|
|
300
303
|
({ outV: v } = (0, types_1.coerceObject)({ outV: v }));
|
|
301
304
|
}
|
|
@@ -401,7 +404,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
401
404
|
success(target);
|
|
402
405
|
}
|
|
403
406
|
else {
|
|
404
|
-
failed((0, types_1.errorMessage)(f, "Invalid value"
|
|
407
|
+
failed((0, types_1.errorMessage)(f, "Invalid value", has(EX) ? 'EX: ' + EX : has(PX) ? 'PX: ' + PX : EXAT > 0 ? 'EXAT: ' + EX : 'PXAT: ' + PXAT));
|
|
405
408
|
}
|
|
406
409
|
})
|
|
407
410
|
.catch(err => failed(err));
|
|
@@ -437,22 +440,28 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
437
440
|
});
|
|
438
441
|
}
|
|
439
442
|
commandType = this.commandType.SELECT;
|
|
440
|
-
|
|
441
|
-
|
|
443
|
+
const target = (0, types_1.isObject)(search) ? search : (0, types_1.isObject)(aggregate) ? aggregate : null;
|
|
444
|
+
if (target) {
|
|
445
|
+
const { query = '', schema, index } = target;
|
|
442
446
|
let idx = '';
|
|
443
447
|
if ((0, types_1.isObject)(schema)) {
|
|
444
448
|
idx = index || (0, types_1.generateUUID)();
|
|
445
|
-
await (command ? client.ft.create(command, idx, schema,
|
|
449
|
+
await (command ? client.ft.create(command, idx, schema, target.options) : client.ft.create(idx, schema, target.options));
|
|
446
450
|
}
|
|
447
451
|
try {
|
|
448
|
-
|
|
449
|
-
|
|
452
|
+
if (target === search) {
|
|
453
|
+
const reply = await (command ? client.ft.search(command, index || idx, query, clientOptions.search) : client.ft.search(index || idx, query, clientOptions.search));
|
|
454
|
+
rows = reply.documents.map(doc => (doc.value['__id__'] = doc.id) && doc.value);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
({ results: rows } = await (command ? client.ft.aggregate(command, index || idx, query, clientOptions.aggregate) : client.ft.aggregate(index || idx, query, clientOptions.aggregate)));
|
|
458
|
+
}
|
|
450
459
|
}
|
|
451
460
|
catch (err) {
|
|
452
461
|
error = err;
|
|
453
462
|
}
|
|
454
463
|
if (idx && idx !== index) {
|
|
455
|
-
client.ft.dropIndex(idx).catch(err => this.writeFail([
|
|
464
|
+
client.ft.dropIndex(idx).catch(err => this.writeFail([`Unable to drop ${target === search ? 'search' : 'aggregate'} index`, idx], err, { type: 65536, fatal: false }));
|
|
456
465
|
}
|
|
457
466
|
if (error instanceof Error) {
|
|
458
467
|
throw error;
|
|
@@ -500,16 +509,16 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
500
509
|
rows = (targetObject ? targetObject(item, data) : data);
|
|
501
510
|
}
|
|
502
511
|
if (rows === undefined) {
|
|
503
|
-
throw (0, types_1.errorMessage)(source, "Missing database query"
|
|
512
|
+
throw (0, types_1.errorMessage)(source, "Missing database query");
|
|
504
513
|
}
|
|
505
|
-
this.add(item, 4
|
|
514
|
+
this.add(item, 4);
|
|
506
515
|
resolve(this.setQueryResult(source, removePoolProperties(redisCredential || credential), queryString, rows, cacheValue));
|
|
507
516
|
}
|
|
508
517
|
catch (err) {
|
|
509
518
|
if (err instanceof Error) {
|
|
510
519
|
switch (err.message) {
|
|
511
|
-
case "The client is closed"
|
|
512
|
-
case "Disconnects client"
|
|
520
|
+
case "The client is closed":
|
|
521
|
+
case "Disconnects client": {
|
|
513
522
|
const pool = item.usePool && DbPool.findKey(POOL_STATE, item.usePool, getPoolKey(credential));
|
|
514
523
|
if (pool) {
|
|
515
524
|
await pool.detach(true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/redis",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Redis client driver for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"types": "client/index.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/anpham6/pi-r.git",
|
|
12
|
+
"url": "git+https://github.com/anpham6/pi-r.git",
|
|
13
13
|
"directory": "src/db/redis"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
@@ -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.5.
|
|
25
|
-
"@e-mc/types": "^0.5.
|
|
26
|
-
"redis": "^4.6.
|
|
24
|
+
"@e-mc/db": "^0.5.5",
|
|
25
|
+
"@e-mc/types": "^0.5.5",
|
|
26
|
+
"redis": "^4.6.13"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { ClientCommandOptions } 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 { RediSearchSchema } from 'redis';
|
|
10
|
+
import type { AggregateOptions, RediSearchSchema, SearchOptions } 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";
|
|
@@ -15,16 +15,14 @@ export interface RedisDataSource extends DbDataSource<string, PlainObject, Array
|
|
|
15
15
|
field?: RedisCommandArgument;
|
|
16
16
|
path?: string;
|
|
17
17
|
format?: RedisFormat | "HKEYS" | "HVALS";
|
|
18
|
-
search?:
|
|
19
|
-
|
|
20
|
-
schema?: RediSearchSchema | string;
|
|
21
|
-
query?: string;
|
|
22
|
-
options?: PlainObject;
|
|
23
|
-
};
|
|
18
|
+
search?: RedisQuery;
|
|
19
|
+
aggregate?: RedisQuery;
|
|
24
20
|
options?: {
|
|
25
21
|
client?: RedisClientOptions;
|
|
26
|
-
get?: PlainObject;
|
|
27
22
|
command?: RedisCommandOptions;
|
|
23
|
+
get?: PlainObject;
|
|
24
|
+
search?: SearchOptions;
|
|
25
|
+
aggregate?: AggregateOptions;
|
|
28
26
|
};
|
|
29
27
|
database?: number;
|
|
30
28
|
}
|
|
@@ -53,6 +51,13 @@ export interface RedisJSONValue extends Omit<RedisSetValue<"JSON", string, Redis
|
|
|
53
51
|
path?: string;
|
|
54
52
|
}
|
|
55
53
|
|
|
54
|
+
export interface RedisQuery {
|
|
55
|
+
index?: string;
|
|
56
|
+
schema?: RediSearchSchema | string;
|
|
57
|
+
query?: string;
|
|
58
|
+
options?: PlainObject;
|
|
59
|
+
}
|
|
60
|
+
|
|
56
61
|
export type RedisFormat = "HASH" | "JSON";
|
|
57
62
|
export type RedisExpireCondition = "NX" | "XX" | "GT" | "LT";
|
|
58
63
|
export type RedisCommandValue = RedisCommandArgument | number;
|