@e-mc/db 0.0.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/LICENSE +11 -0
- package/README.md +5 -0
- package/index.d.ts +5 -0
- package/index.js +288 -0
- package/mongodb/index.d.ts +19 -0
- package/mongodb/index.js +679 -0
- package/mssql/index.d.ts +7 -0
- package/mssql/index.js +505 -0
- package/mysql/index.d.ts +10 -0
- package/mysql/index.js +332 -0
- package/oracle/index.d.ts +7 -0
- package/oracle/index.js +358 -0
- package/package.json +26 -0
- package/pool.d.ts +5 -0
- package/pool.js +144 -0
- package/postgres/index.d.ts +7 -0
- package/postgres/index.js +272 -0
- package/redis/index.d.ts +7 -0
- package/redis/index.js +550 -0
- package/types.d.ts +14 -0
- package/util.d.ts +17 -0
- package/util.js +106 -0
package/redis/index.js
ADDED
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DB_SOURCE_TYPE = exports.DB_SOURCE_CLIENT = exports.checkTimeout = exports.executeBatchQuery = exports.executeQuery = exports.setCredential = void 0;
|
|
4
|
+
const util_1 = require("../util");
|
|
5
|
+
const types_1 = require("../../types");
|
|
6
|
+
const index_1 = require("../index");
|
|
7
|
+
const pool_1 = require("../pool");
|
|
8
|
+
const REDIS_V4 = index_1.default.checkSemVer("redis" /* STRINGS.PACKAGE_NAME */, 4);
|
|
9
|
+
class RedisPool extends pool_1.default {
|
|
10
|
+
getConnection() {
|
|
11
|
+
return Promise.resolve(this.client);
|
|
12
|
+
}
|
|
13
|
+
close() {
|
|
14
|
+
return this.client.disconnect();
|
|
15
|
+
}
|
|
16
|
+
isEmpty() {
|
|
17
|
+
return this.closed;
|
|
18
|
+
}
|
|
19
|
+
get closed() {
|
|
20
|
+
return !this.client.isOpen;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const POOL_STATE = {};
|
|
24
|
+
function getClient(db, options, poolKey) {
|
|
25
|
+
const socket = options.socket || (options.socket = {});
|
|
26
|
+
if (!poolKey) {
|
|
27
|
+
socket.keepAlive = false;
|
|
28
|
+
}
|
|
29
|
+
else if (typeof socket.keepAlive !== 'number') {
|
|
30
|
+
socket.keepAlive = undefined;
|
|
31
|
+
}
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
const client = db.createClient(options);
|
|
34
|
+
if (poolKey) {
|
|
35
|
+
client.on('end', () => {
|
|
36
|
+
delete POOL_STATE[poolKey];
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
client.connect().then(() => resolve(client)).catch(err => reject(err));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const removePoolProperties = (options) => {
|
|
43
|
+
if (!options.uuidKey && ('socket' in options || 'isolationPoolOptions' in options)) {
|
|
44
|
+
return { ...options, socket: options.socket?.tls ? { tls: true } : undefined, isolationPoolOptions: undefined };
|
|
45
|
+
}
|
|
46
|
+
return options;
|
|
47
|
+
};
|
|
48
|
+
const getPoolKey = (options) => options.url + '_' + (options.username || '') + '_' + (options.password || '') + '_' + (options.database ?? '') + '_' + (options.socket?.tls ? '1' : '0') + '_' + (options.legacyMode ? '1' : '0');
|
|
49
|
+
async function setCredential(item) {
|
|
50
|
+
if (!REDIS_V4) {
|
|
51
|
+
throw (0, types_1.errorValue)("Upgrade client to latest version" /* ERR_DB.UPGRADE */, "redis" /* STRINGS.PACKAGE_NAME */ + '@' + index_1.default.getPackageVersion("redis" /* STRINGS.PACKAGE_NAME */));
|
|
52
|
+
}
|
|
53
|
+
const credential = this.getCredential(item);
|
|
54
|
+
const options = item.options || (item.options = {});
|
|
55
|
+
const client = (0, types_1.isPlainObject)(options.client) ? options.client : options.client = {};
|
|
56
|
+
let { uri, username, password, database = 0 } = item;
|
|
57
|
+
if (database > 0) {
|
|
58
|
+
client.database = database;
|
|
59
|
+
}
|
|
60
|
+
if (credential) {
|
|
61
|
+
const auth = (0, util_1.parseServerAuth)(credential, 6379 /* VALUES.PORT */);
|
|
62
|
+
if (!client.database) {
|
|
63
|
+
if ('database' in credential) {
|
|
64
|
+
const value = credential.database;
|
|
65
|
+
if (+value > 0) {
|
|
66
|
+
database = +value;
|
|
67
|
+
}
|
|
68
|
+
delete credential.database;
|
|
69
|
+
}
|
|
70
|
+
if (database > 0) {
|
|
71
|
+
client.database = database;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
uri || (uri = (auth.protocol || 'redis:') + '//' + (auth.server || 'localhost:' + (auth.port ? auth.port : 6379 /* VALUES.PORT */)));
|
|
75
|
+
username || (username = auth.username);
|
|
76
|
+
password || (password = auth.password);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
delete item.credential;
|
|
80
|
+
}
|
|
81
|
+
if (!uri) {
|
|
82
|
+
throw (0, types_1.errorMessage)("redis" /* STRINGS.MODULE_NAME */, 'Not defined - uri');
|
|
83
|
+
}
|
|
84
|
+
if (client.socket?.tls) {
|
|
85
|
+
this.readTLSConfig(client.socket);
|
|
86
|
+
}
|
|
87
|
+
client.url = uri;
|
|
88
|
+
if (username) {
|
|
89
|
+
client.username = username;
|
|
90
|
+
}
|
|
91
|
+
if (password) {
|
|
92
|
+
client.password = password;
|
|
93
|
+
}
|
|
94
|
+
const usePool = item.usePool;
|
|
95
|
+
if (usePool) {
|
|
96
|
+
let pool;
|
|
97
|
+
username = undefined;
|
|
98
|
+
password = undefined;
|
|
99
|
+
if (typeof usePool === 'string' && (username = client.username || (0, util_1.parseConnectionString)(uri)?.username)) {
|
|
100
|
+
[password, pool] = pool_1.default.validateKey(POOL_STATE, username, usePool);
|
|
101
|
+
if (pool) {
|
|
102
|
+
pool.add(item, password);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const poolKey = getPoolKey(client);
|
|
107
|
+
if (!(pool = POOL_STATE[poolKey]) || pool.closed) {
|
|
108
|
+
const db = require("redis" /* STRINGS.PACKAGE_NAME */);
|
|
109
|
+
const config = this.getPoolConfig("redis" /* STRINGS.MODULE_NAME */, password);
|
|
110
|
+
const poolOptions = client.isolationPoolOptions || (client.isolationPoolOptions = {});
|
|
111
|
+
if (config) {
|
|
112
|
+
const { min, max, idle, queue_max, queue_idle } = config;
|
|
113
|
+
if (min >= 0) {
|
|
114
|
+
poolOptions.min ?? (poolOptions.min = min);
|
|
115
|
+
}
|
|
116
|
+
if (max > 0) {
|
|
117
|
+
poolOptions.max ?? (poolOptions.max = max);
|
|
118
|
+
}
|
|
119
|
+
if (idle > 0) {
|
|
120
|
+
poolOptions.idleTimeoutMillis ?? (poolOptions.idleTimeoutMillis = idle);
|
|
121
|
+
}
|
|
122
|
+
if (queue_max >= 0) {
|
|
123
|
+
poolOptions.maxWaitingClients ?? (poolOptions.maxWaitingClients = queue_max);
|
|
124
|
+
}
|
|
125
|
+
if (queue_idle > 0) {
|
|
126
|
+
poolOptions.acquireTimeoutMillis ?? (poolOptions.acquireTimeoutMillis = queue_idle);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const redis = new RedisPool(await getClient(db, client, poolKey), poolKey, username && password ? { username, password } : undefined).add(item);
|
|
131
|
+
redis.parent = POOL_STATE;
|
|
132
|
+
redis.success = 1;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
item.usePool = false;
|
|
136
|
+
delete client.isolationPoolOptions;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
pool.add(item);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.setCredential = setCredential;
|
|
145
|
+
async function executeQuery(item, options) {
|
|
146
|
+
return (await executeBatchQuery.call(this, [item], options))[0] || [];
|
|
147
|
+
}
|
|
148
|
+
exports.executeQuery = executeQuery;
|
|
149
|
+
async function executeBatchQuery(batch, options = '', outResult) {
|
|
150
|
+
const length = batch.length;
|
|
151
|
+
if (length === 0) {
|
|
152
|
+
return [];
|
|
153
|
+
}
|
|
154
|
+
const db = require("redis" /* STRINGS.PACKAGE_NAME */);
|
|
155
|
+
let parallel, checkObject, connectOnce, errorQuery, sessionKey, outCacheMiss;
|
|
156
|
+
if ((0, types_1.isPlainObject)(options)) {
|
|
157
|
+
({ parallel, checkObject, connectOnce, errorQuery, sessionKey, outCacheMiss } = options);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
if (typeof options === 'string') {
|
|
161
|
+
sessionKey = options;
|
|
162
|
+
}
|
|
163
|
+
options = undefined;
|
|
164
|
+
}
|
|
165
|
+
if (length === 1) {
|
|
166
|
+
connectOnce = false;
|
|
167
|
+
parallel = false;
|
|
168
|
+
}
|
|
169
|
+
else if (parallel === undefined) {
|
|
170
|
+
parallel = !batch.some(item => item.parallel === false);
|
|
171
|
+
}
|
|
172
|
+
if (!parallel) {
|
|
173
|
+
outResult || (outResult = new Array(length));
|
|
174
|
+
}
|
|
175
|
+
const caching = this.hasCache("redis" /* STRINGS.MODULE_NAME */, sessionKey);
|
|
176
|
+
const tasks = new Array(length);
|
|
177
|
+
const clients = [];
|
|
178
|
+
let redisClient, redisCredential, redisCache = 0, onceCredential = connectOnce ? batch[0].options?.client : undefined;
|
|
179
|
+
const getConnection = async (item, credential) => {
|
|
180
|
+
item.transactionState = 64 /* TRANSACTION.AUTH */;
|
|
181
|
+
let client;
|
|
182
|
+
if (item.usePool) {
|
|
183
|
+
const pool = pool_1.default.findKey(POOL_STATE, item.usePool, getPoolKey(credential), ...connectOnce ? [item, batch[0]] : [item]);
|
|
184
|
+
if (pool) {
|
|
185
|
+
client = pool.client;
|
|
186
|
+
pool.connected = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (!client) {
|
|
190
|
+
if (connectOnce && parallel) {
|
|
191
|
+
const size = length - redisCache;
|
|
192
|
+
if (size > 1) {
|
|
193
|
+
(credential.isolationPoolOptions || (credential.isolationPoolOptions = {})).max = size;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
clients.push(client = await getClient(db, credential));
|
|
197
|
+
}
|
|
198
|
+
if (connectOnce) {
|
|
199
|
+
redisClient = client;
|
|
200
|
+
redisCredential = credential;
|
|
201
|
+
}
|
|
202
|
+
item.transactionState &= ~64 /* TRANSACTION.AUTH */;
|
|
203
|
+
return client;
|
|
204
|
+
};
|
|
205
|
+
for (let i = 0; i < length; ++i) {
|
|
206
|
+
const item = batch[i];
|
|
207
|
+
const { source, uri, key, format = 'HASH', search, update, options: clientOptions = {}, cacheObjectKey, ignoreCache } = item;
|
|
208
|
+
let credential = (redisCredential || onceCredential), error;
|
|
209
|
+
if (!credential && !(0, types_1.isPlainObject)(credential = clientOptions.client) && (error = (0, types_1.errorMessage)(source, "Invalid credentials" /* ERR_DB.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))) && (error = (0, types_1.errorMessage)(source, "Missing database query" /* ERR_DB.QUERY */, uri))) {
|
|
210
|
+
++redisCache;
|
|
211
|
+
if (this.handleFail(error, item, { errorQuery })) {
|
|
212
|
+
if (!parallel) {
|
|
213
|
+
tasks.length = 0;
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
tasks[i] = Promise.reject(error);
|
|
217
|
+
}
|
|
218
|
+
else if (parallel) {
|
|
219
|
+
tasks[i] = Promise.resolve([]);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
outResult[i] = [];
|
|
223
|
+
}
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
item.transactionState = 1 /* TRANSACTION.ACTIVE */;
|
|
227
|
+
const uuidKey = (credential.uuidKey || (credential.uuidKey = (onceCredential ? batch[0] : item).credential?.uuidKey));
|
|
228
|
+
const targetObject = typeof checkObject === 'string' ? this.hasCoerce("redis" /* STRINGS.MODULE_NAME */, 'options', uuidKey) && (0, types_1.asFunction)(checkObject) : checkObject;
|
|
229
|
+
const renewCache = ignoreCache === 0;
|
|
230
|
+
const cacheValue = renewCache ? { sessionKey, renewCache } : sessionKey;
|
|
231
|
+
const command = (0, types_1.isPlainObject)(clientOptions.command) ? db.commandOptions(clientOptions.command) : null;
|
|
232
|
+
let queryString = '', rows;
|
|
233
|
+
if (caching && ignoreCache !== true || ignoreCache === false || ignoreCache === 1 || renewCache) {
|
|
234
|
+
if ((0, types_1.isObject)(search)) {
|
|
235
|
+
queryString = index_1.default.asString(search, true);
|
|
236
|
+
}
|
|
237
|
+
else if (!targetObject) {
|
|
238
|
+
queryString = index_1.default.asString(key);
|
|
239
|
+
}
|
|
240
|
+
else if (cacheObjectKey) {
|
|
241
|
+
queryString = index_1.default.asString(key) + '_' + targetObject.toString() + cacheObjectKey;
|
|
242
|
+
}
|
|
243
|
+
if (queryString) {
|
|
244
|
+
queryString += '_' + format;
|
|
245
|
+
}
|
|
246
|
+
if (ignoreCache !== 1) {
|
|
247
|
+
if (rows = this.getQueryResult(source, removePoolProperties(credential), queryString, cacheValue)) {
|
|
248
|
+
++redisCache;
|
|
249
|
+
if (parallel) {
|
|
250
|
+
tasks[i] = Promise.resolve(rows);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
outResult[i] = rows;
|
|
254
|
+
}
|
|
255
|
+
this.add(item, 4 /* TRANSACTION.COMMIT */ | 128 /* TRANSACTION.CACHE */);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (!ignoreCache && outCacheMiss) {
|
|
259
|
+
outCacheMiss.push(source);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (onceCredential && parallel) {
|
|
264
|
+
try {
|
|
265
|
+
redisClient = await getConnection(item, onceCredential);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
connectOnce = false;
|
|
269
|
+
parallel = false;
|
|
270
|
+
}
|
|
271
|
+
onceCredential = undefined;
|
|
272
|
+
}
|
|
273
|
+
tasks[i] = new Promise(async (resolve, reject) => {
|
|
274
|
+
let commandType;
|
|
275
|
+
try {
|
|
276
|
+
const client = redisClient || await getConnection(item, credential);
|
|
277
|
+
const a = (arg) => typeof arg === 'string' || Buffer.isBuffer(arg) || typeof arg === 'number';
|
|
278
|
+
const b = (arg) => typeof arg === 'number' || Buffer.isBuffer(arg) ? arg.toString() : arg;
|
|
279
|
+
if (update) {
|
|
280
|
+
commandType = this.commandType.UPDATE;
|
|
281
|
+
const values = (!Array.isArray(update) ? [update] : update).map(target => {
|
|
282
|
+
return new Promise(async (success, failed) => {
|
|
283
|
+
let { key: k, value: v, format: f = 'HASH', NX, XX, EX = 0, PX = 0, EXAT = 0, PXAT = 0, options: setOptions = {} } = target;
|
|
284
|
+
if (v === undefined) {
|
|
285
|
+
success(target);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const failKey = () => failed((0, types_1.errorMessage)(f, "Invalid key" /* ERR_DB.KEY */, index_1.default.asString(k) || "Unknown" /* ERR_MESSAGE.UNKNOWN */));
|
|
289
|
+
const failValue = () => failed((0, types_1.errorMessage)(f, "Invalid value" /* ERR_DB.VALUE */, index_1.default.asString(v) || "Unknown" /* ERR_MESSAGE.UNKNOWN */));
|
|
290
|
+
const commandSet = (0, types_1.isPlainObject)(setOptions.command) && db.commandOptions(setOptions.command);
|
|
291
|
+
let pending;
|
|
292
|
+
if ((f = f.toUpperCase()) === 'JSON') {
|
|
293
|
+
if (typeof k !== 'string') {
|
|
294
|
+
failKey();
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const path = target.path || '$';
|
|
298
|
+
if (this.hasCoerce("redis" /* STRINGS.MODULE_NAME */, 'options', uuidKey)) {
|
|
299
|
+
if ((0, types_1.isString)(v) && v.startsWith('new')) {
|
|
300
|
+
({ outV: v } = (0, types_1.coerceObject)({ outV: v }));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
const flags = NX ? { NX } : XX ? { XX } : undefined;
|
|
304
|
+
pending = commandSet ? client.json.set(commandSet, k, path, v, flags) : client.json.set(k, path, v, flags);
|
|
305
|
+
}
|
|
306
|
+
else if (typeof k === 'string' || Buffer.isBuffer(k)) {
|
|
307
|
+
const field = target.field;
|
|
308
|
+
if (field === undefined && field === null) {
|
|
309
|
+
if (a(v)) {
|
|
310
|
+
const flags = setOptions.set;
|
|
311
|
+
if (flags) {
|
|
312
|
+
if ('NX' in flags) {
|
|
313
|
+
NX ?? (NX = !!flags.NX);
|
|
314
|
+
delete flags.NX;
|
|
315
|
+
}
|
|
316
|
+
if ('XX' in flags) {
|
|
317
|
+
XX ?? (XX = !!flags.XX);
|
|
318
|
+
delete flags.XX;
|
|
319
|
+
}
|
|
320
|
+
if ('EX' in flags) {
|
|
321
|
+
EX || (EX = flags.EX);
|
|
322
|
+
delete flags.EX;
|
|
323
|
+
}
|
|
324
|
+
if ('PX' in flags) {
|
|
325
|
+
PX || (PX = flags.PX);
|
|
326
|
+
delete flags.PX;
|
|
327
|
+
}
|
|
328
|
+
if ('EXAT' in flags) {
|
|
329
|
+
EXAT || (EXAT = flags.EXAT);
|
|
330
|
+
delete flags.EXAT;
|
|
331
|
+
}
|
|
332
|
+
if ('PXAT' in flags) {
|
|
333
|
+
PXAT || (PXAT = flags.PXAT);
|
|
334
|
+
delete flags.PXAT;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
pending = (commandSet ? client.set(commandSet, k, v, setOptions.set) : client.set(k, v, setOptions.set));
|
|
338
|
+
}
|
|
339
|
+
else if (typeof v === 'object') {
|
|
340
|
+
let valid = true;
|
|
341
|
+
if (NX || XX) {
|
|
342
|
+
valid = await client.exists(k) === 1;
|
|
343
|
+
if (NX) {
|
|
344
|
+
valid = !valid;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (!valid) {
|
|
348
|
+
success(target);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
pending = commandSet ? client.hSet(commandSet, k, v) : client.hSet(k, v);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else if (NX) {
|
|
355
|
+
if (a(field) && a(v)) {
|
|
356
|
+
pending = commandSet ? client.hSetNX(commandSet, k, b(field), b(v)) : client.hSetNX(k, b(field), b(v));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
let valid = true;
|
|
361
|
+
if (XX) {
|
|
362
|
+
valid = a(k) && a(field) && await client.hExists(b(k), b(field));
|
|
363
|
+
}
|
|
364
|
+
if (a(field) && a(v)) {
|
|
365
|
+
if (!valid) {
|
|
366
|
+
success(target);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
pending = commandSet ? client.hSet(commandSet, k, field, v) : client.hSet(k, field, v);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
failKey();
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (pending) {
|
|
378
|
+
pending.then(code => {
|
|
379
|
+
if (code === 'OK' || typeof code === 'number' || code === true) {
|
|
380
|
+
const has = (n) => typeof n === 'number' && n !== 0;
|
|
381
|
+
if (has(EX) || has(PX) || EXAT > 0 || PXAT > 0) {
|
|
382
|
+
const expire = setOptions.expire;
|
|
383
|
+
let mode;
|
|
384
|
+
if (expire) {
|
|
385
|
+
if (expire.NX) {
|
|
386
|
+
mode = 'NX';
|
|
387
|
+
}
|
|
388
|
+
else if (expire.XX) {
|
|
389
|
+
mode = 'XX';
|
|
390
|
+
}
|
|
391
|
+
else if (expire.GT) {
|
|
392
|
+
mode = 'GT';
|
|
393
|
+
}
|
|
394
|
+
else if (expire.LT) {
|
|
395
|
+
mode = 'LT';
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
(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))
|
|
399
|
+
.then(valid => {
|
|
400
|
+
if (valid) {
|
|
401
|
+
success(target);
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
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));
|
|
405
|
+
}
|
|
406
|
+
})
|
|
407
|
+
.catch(err => failed(err));
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
success(target);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
failValue();
|
|
415
|
+
}
|
|
416
|
+
})
|
|
417
|
+
.catch(err => failed(err));
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
failValue();
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
await Promise.allSettled(values)
|
|
425
|
+
.then(result => {
|
|
426
|
+
for (const cmd of result) {
|
|
427
|
+
if (cmd.status === 'rejected' && this.handleFail(cmd.reason, item, { errorQuery, commandType })) {
|
|
428
|
+
reject(cmd.reason);
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
})
|
|
433
|
+
.catch(err => {
|
|
434
|
+
if (this.handleFail(err, item, { errorQuery, commandType })) {
|
|
435
|
+
reject(err);
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
commandType = this.commandType.SELECT;
|
|
440
|
+
if ((0, types_1.isObject)(search)) {
|
|
441
|
+
const { query = '', schema, index } = search;
|
|
442
|
+
let idx = '';
|
|
443
|
+
if ((0, types_1.isObject)(schema)) {
|
|
444
|
+
idx = index || (0, types_1.generateUUID)();
|
|
445
|
+
await (command ? client.ft.create(command, idx, schema, search.options) : client.ft.create(idx, schema, search.options));
|
|
446
|
+
}
|
|
447
|
+
try {
|
|
448
|
+
const reply = await (command ? client.ft.search(command, index || idx, query) : client.ft.search(index || idx, query));
|
|
449
|
+
rows = reply.documents.map(doc => (doc.value['__id__'] = doc.id) && doc.value);
|
|
450
|
+
}
|
|
451
|
+
catch (err) {
|
|
452
|
+
error = err;
|
|
453
|
+
}
|
|
454
|
+
if (idx && idx !== index) {
|
|
455
|
+
client.ft.dropIndex(idx).catch(err => this.writeFail(['Unable to drop search index', idx], err, { type: 65536 /* LOG_TYPE.DB */, fatal: false }));
|
|
456
|
+
}
|
|
457
|
+
if (error instanceof Error) {
|
|
458
|
+
throw error;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
else if (key) {
|
|
462
|
+
let data;
|
|
463
|
+
if (Array.isArray(key)) {
|
|
464
|
+
switch (format.toUpperCase()) {
|
|
465
|
+
case 'HKEYS':
|
|
466
|
+
data = await Promise.all(key.map(k => client.hKeys(...command ? [command, k] : [k])));
|
|
467
|
+
break;
|
|
468
|
+
case 'HVALS':
|
|
469
|
+
data = await Promise.all(key.map(k => client.hVals(...command ? [command, k] : [k])));
|
|
470
|
+
break;
|
|
471
|
+
case 'JSON':
|
|
472
|
+
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();
|
|
473
|
+
break;
|
|
474
|
+
default:
|
|
475
|
+
data = await client.mGet(...command ? [command, key] : [key]);
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
switch (format.toUpperCase()) {
|
|
481
|
+
case 'HKEYS':
|
|
482
|
+
data = await client.hKeys(...command ? [command, key] : [key]);
|
|
483
|
+
break;
|
|
484
|
+
case 'HVALS':
|
|
485
|
+
data = await client.hVals(...command ? [command, key] : [key]);
|
|
486
|
+
break;
|
|
487
|
+
case 'JSON':
|
|
488
|
+
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)]));
|
|
489
|
+
break;
|
|
490
|
+
default:
|
|
491
|
+
if (item.field) {
|
|
492
|
+
data = client.hGet(...command ? [command, key, item.field] : [key, item.field]);
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
data = await client.hGetAll(...command ? [command, key] : [key]);
|
|
496
|
+
}
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
rows = (targetObject ? targetObject(item, data) : data);
|
|
501
|
+
}
|
|
502
|
+
if (rows === undefined) {
|
|
503
|
+
throw (0, types_1.errorMessage)(source, "Missing database query" /* ERR_DB.QUERY */);
|
|
504
|
+
}
|
|
505
|
+
this.add(item, 4 /* TRANSACTION.COMMIT */);
|
|
506
|
+
resolve(this.setQueryResult(source, removePoolProperties(redisCredential || credential), queryString, rows, cacheValue));
|
|
507
|
+
}
|
|
508
|
+
catch (err) {
|
|
509
|
+
if (err instanceof Error) {
|
|
510
|
+
switch (err.message) {
|
|
511
|
+
case "The client is closed" /* STRINGS.ERR_CLIENT_CLOSE */:
|
|
512
|
+
case "Disconnects client" /* STRINGS.ERR_CLIENT_DISCONNECT */: {
|
|
513
|
+
const pool = item.usePool && pool_1.default.findKey(POOL_STATE, item.usePool, getPoolKey(credential));
|
|
514
|
+
if (pool) {
|
|
515
|
+
await pool.detach(true);
|
|
516
|
+
}
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (this.handleFail(err, item, { errorQuery, commandType })) {
|
|
522
|
+
reject(err);
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
resolve([]);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
if (!parallel) {
|
|
530
|
+
try {
|
|
531
|
+
outResult[i] = await tasks[i];
|
|
532
|
+
}
|
|
533
|
+
catch {
|
|
534
|
+
tasks.length = 0;
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return this.processRows(batch, tasks, {
|
|
540
|
+
disconnect: () => clients.forEach(item => item.disconnect()),
|
|
541
|
+
parallel
|
|
542
|
+
}, outResult);
|
|
543
|
+
}
|
|
544
|
+
exports.executeBatchQuery = executeBatchQuery;
|
|
545
|
+
function checkTimeout(value, limit = 0) {
|
|
546
|
+
return pool_1.default.checkTimeout(POOL_STATE, value, limit);
|
|
547
|
+
}
|
|
548
|
+
exports.checkTimeout = checkTimeout;
|
|
549
|
+
exports.DB_SOURCE_CLIENT = true;
|
|
550
|
+
exports.DB_SOURCE_TYPE = types_1.DB_TYPE.NOSQL | types_1.DB_TYPE.KEYVALUE;
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DbDataSource } from '../types/lib/squared';
|
|
2
|
+
|
|
3
|
+
import type { IDb } from '../types/lib';
|
|
4
|
+
import type { BatchQueryResult, ExecuteBatchQueryOptions, ExecuteQueryOptions, QueryResult } from '../types/lib/db';
|
|
5
|
+
|
|
6
|
+
export interface IDbSourceClient<T extends DbDataSource = DbDataSource> {
|
|
7
|
+
DB_SOURCE_NAME: string;
|
|
8
|
+
DB_SOURCE_CLIENT: boolean;
|
|
9
|
+
DB_SOURCE_TYPE: number;
|
|
10
|
+
setCredential(this: IDb, item: T): Promise<void>;
|
|
11
|
+
executeQuery(this: IDb, item: T, options?: ExecuteQueryOptions | string): Promise<QueryResult>;
|
|
12
|
+
executeBatchQuery(this: IDb, batch: T[], options?: ExecuteBatchQueryOptions | string, outResult?: BatchQueryResult): Promise<BatchQueryResult>;
|
|
13
|
+
checkTimeout?(this: IDbSourceClient, value: number, limit?: number): Promise<number>;
|
|
14
|
+
}
|
package/util.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DbDataSource } from '../types/lib/squared';
|
|
2
|
+
|
|
3
|
+
import type { SQL_COMMAND, DbConnection, ServerAuth } from '../types/lib/db';
|
|
4
|
+
|
|
5
|
+
declare namespace util {
|
|
6
|
+
const SQL_COMMAND: SQL_COMMAND;
|
|
7
|
+
function getBasicAuth(auth: AuthValue): string;
|
|
8
|
+
function getBasicAuth(username: unknown, password?: unknown): string;
|
|
9
|
+
function hasBasicAuth(value: string): boolean;
|
|
10
|
+
function parseConnectionString(value: string, scheme?: string): Null<DbConnection>;
|
|
11
|
+
function parseServerAuth(value: ServerAuth, all: boolean): ServerAuth;
|
|
12
|
+
function parseServerAuth(value: ServerAuth, port?: number, all?: boolean): ServerAuth;
|
|
13
|
+
function checkEmpty(value: unknown): boolean;
|
|
14
|
+
function setUUIDKey(item: DbDataSource, value: unknown): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export = util;
|