@pi-r/mongodb 0.5.1 → 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 +95 -88
- package/package.json +4 -4
- package/types/index.d.ts +4 -2
package/client/index.js
CHANGED
|
@@ -9,14 +9,17 @@ const Db = require("@e-mc/db");
|
|
|
9
9
|
const Request = require("@e-mc/request");
|
|
10
10
|
const DbPool = require('@e-mc/db/pool');
|
|
11
11
|
class MongoDBPool extends DbPool {
|
|
12
|
-
getConnection() {
|
|
12
|
+
async getConnection() {
|
|
13
13
|
return this.client.connect();
|
|
14
14
|
}
|
|
15
|
-
detach(force) {
|
|
15
|
+
async detach(force) {
|
|
16
16
|
this.remove();
|
|
17
|
-
|
|
17
|
+
if (this.closed) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
return this.close(force);
|
|
18
21
|
}
|
|
19
|
-
close(force = false) {
|
|
22
|
+
async close(force = false) {
|
|
20
23
|
return this.client.close(force);
|
|
21
24
|
}
|
|
22
25
|
isEmpty() {
|
|
@@ -69,7 +72,7 @@ function getPoolKey(credential) {
|
|
|
69
72
|
const options = credential.options;
|
|
70
73
|
if (options && credential.uri) {
|
|
71
74
|
const auth = options.auth;
|
|
72
|
-
let result = credential.uri + (auth ? '_' + (auth.username || '') + '@' + (auth.password || '') : '') + '_' + (options.authMechanism || '') + Db.asString(options.authMechanismProperties);
|
|
75
|
+
let result = credential.uri + (auth ? '_' + (auth.username || '') + '@' + (auth.password || '') : '') + '_' + (options.authMechanism || '') + Db.asString(options.authMechanismProperties, true);
|
|
73
76
|
if (options.tls || options.ssl) {
|
|
74
77
|
const { tlsCertificateKeyFile = '', tlsCAFile = '', tlsCRLFile = '', tlsCertificateKeyFilePassword = '', tlsAllowInvalidHostnames, tlsAllowInvalidCertificates, tlsInsecure } = options;
|
|
75
78
|
result += tlsCertificateKeyFile + tlsCAFile + tlsCRLFile + tlsCertificateKeyFilePassword + (tlsAllowInvalidHostnames ? '1' : '0') + (tlsAllowInvalidCertificates ? '1' : '0') + (tlsInsecure ? '1' : '0');
|
|
@@ -107,13 +110,10 @@ function setCredential(item) {
|
|
|
107
110
|
else {
|
|
108
111
|
options.auth || (options.auth = { username, password });
|
|
109
112
|
}
|
|
110
|
-
if (uri.
|
|
111
|
-
|
|
112
|
-
uri += '/';
|
|
113
|
-
}
|
|
114
|
-
uri += '?';
|
|
113
|
+
if (!uri.includes('?')) {
|
|
114
|
+
uri += (uri.endsWith('/') ? '' : '/') + '?';
|
|
115
115
|
}
|
|
116
|
-
uri += (uri
|
|
116
|
+
uri += (uri.endsWith('?') ? '' : '&') + 'authMechanism=' + encodeURIComponent(authMechanism);
|
|
117
117
|
switch (authMechanism) {
|
|
118
118
|
case 'MONGODB-X509': {
|
|
119
119
|
const checkFile = (value) => {
|
|
@@ -175,53 +175,52 @@ function setCredential(item) {
|
|
|
175
175
|
throw (0, types_1.errorMessage)("mongodb" /* STRINGS.MODULE_NAME */, 'Not defined - credentials');
|
|
176
176
|
}
|
|
177
177
|
const usePool = item.usePool;
|
|
178
|
-
if (usePool) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
178
|
+
if (!usePool) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
let username, password, pool;
|
|
182
|
+
if (typeof usePool === 'string' && (username = options.auth?.username || item.uri && (0, util_1.parseConnectionString)(item.uri)?.username)) {
|
|
183
|
+
[password, pool] = DbPool.validateKey(POOL_STATE, username, usePool);
|
|
184
|
+
if (pool) {
|
|
185
|
+
pool.add(item, password);
|
|
186
|
+
return;
|
|
186
187
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (queue_max > 0) {
|
|
203
|
-
options.maxConnecting ?? (options.maxConnecting = queue_max);
|
|
204
|
-
}
|
|
205
|
-
if (queue_idle >= 0) {
|
|
206
|
-
options.waitQueueTimeoutMS ?? (options.waitQueueTimeoutMS = queue_idle);
|
|
207
|
-
}
|
|
208
|
-
if (timeout > 0) {
|
|
209
|
-
options.connectTimeoutMS ?? (options.connectTimeoutMS = timeout);
|
|
210
|
-
}
|
|
211
|
-
if (socket_timeout > 0) {
|
|
212
|
-
options.socketTimeoutMS ?? (options.socketTimeoutMS = socket_timeout);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
new MongoDBPool(new mongodb.MongoClient(item.uri, options), poolKey, username && password ? { username, password } : undefined).add(item).parent = POOL_STATE;
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
pool.add(item);
|
|
219
|
-
}
|
|
188
|
+
}
|
|
189
|
+
const poolKey = getPoolKey(item);
|
|
190
|
+
if (!poolKey) {
|
|
191
|
+
item.usePool = false;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if ((pool = POOL_STATE[poolKey]) && !pool.closed) {
|
|
195
|
+
pool.add(item);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const config = this.getPoolConfig("mongodb" /* STRINGS.MODULE_NAME */, password);
|
|
199
|
+
if (config) {
|
|
200
|
+
const { min, max, idle, queue_max, queue_idle, timeout, socket_timeout } = config;
|
|
201
|
+
if (min >= 0) {
|
|
202
|
+
options.minPoolSize ?? (options.minPoolSize = min);
|
|
220
203
|
}
|
|
221
|
-
|
|
222
|
-
|
|
204
|
+
if (max > 0) {
|
|
205
|
+
options.maxPoolSize ?? (options.maxPoolSize = max);
|
|
206
|
+
}
|
|
207
|
+
if (idle >= 0) {
|
|
208
|
+
options.maxIdleTimeMS ?? (options.maxIdleTimeMS = idle);
|
|
209
|
+
}
|
|
210
|
+
if (queue_max > 0) {
|
|
211
|
+
options.maxConnecting ?? (options.maxConnecting = queue_max);
|
|
212
|
+
}
|
|
213
|
+
if (queue_idle >= 0) {
|
|
214
|
+
options.waitQueueTimeoutMS ?? (options.waitQueueTimeoutMS = queue_idle);
|
|
215
|
+
}
|
|
216
|
+
if (timeout > 0) {
|
|
217
|
+
options.connectTimeoutMS ?? (options.connectTimeoutMS = timeout);
|
|
218
|
+
}
|
|
219
|
+
if (socket_timeout > 0) {
|
|
220
|
+
options.socketTimeoutMS ?? (options.socketTimeoutMS = socket_timeout);
|
|
223
221
|
}
|
|
224
222
|
}
|
|
223
|
+
new MongoDBPool(new mongodb.MongoClient(item.uri, options), poolKey, username && password ? { username, password } : undefined).add(item).parent = POOL_STATE;
|
|
225
224
|
}
|
|
226
225
|
exports.setCredential = setCredential;
|
|
227
226
|
async function executeQuery(item, options) {
|
|
@@ -289,6 +288,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
289
288
|
item.transactionState &= ~64 /* DB_TRANSACTION.AUTH */;
|
|
290
289
|
return client;
|
|
291
290
|
};
|
|
291
|
+
if (this.host?.username) {
|
|
292
|
+
this.applyCommand(...batch);
|
|
293
|
+
}
|
|
292
294
|
for (let i = 0; i < length; ++i) {
|
|
293
295
|
const item = batch[i];
|
|
294
296
|
const { source, name, table, id, aggregate, sort, client, cacheObjectKey, ignoreCache } = item;
|
|
@@ -312,17 +314,18 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
312
314
|
continue;
|
|
313
315
|
}
|
|
314
316
|
item.transactionState = 1 /* DB_TRANSACTION.ACTIVE */;
|
|
315
|
-
const
|
|
317
|
+
const getInstance = (target) => target.db(name, client?.db);
|
|
318
|
+
const getCollection = (target) => getInstance(target).collection(table, client?.collection);
|
|
319
|
+
const runCommand = async (target, document) => getInstance(target).command(document, client?.command);
|
|
316
320
|
const credential = mongoCredential || onceCredential || getCacheObject(item);
|
|
317
|
-
const
|
|
318
|
-
const cacheValue = renewCache ? { sessionKey, renewCache } : sessionKey;
|
|
321
|
+
const cacheValue = ignoreCache === undefined ? sessionKey : Array.isArray(ignoreCache) ? { sessionKey, exclusiveOf: ignoreCache } : { sessionKey, renewCache: ignoreCache === 0 };
|
|
319
322
|
const coercing = this.hasCoerce("mongodb" /* STRINGS.MODULE_NAME */, 'options', credential.uuidKey);
|
|
320
323
|
const targetObject = typeof checkObject === 'string' ? coercing && (0, types_1.asFunction)(checkObject) : checkObject;
|
|
321
324
|
if (typeof streamRow === 'string') {
|
|
322
325
|
streamRow = coercing && (0, types_1.asFunction)(streamRow);
|
|
323
326
|
}
|
|
324
327
|
let queryString = '', rows, pipeline;
|
|
325
|
-
if (
|
|
328
|
+
if (caching && ignoreCache !== true && (!targetObject || typeof cacheObjectKey === 'string') && !streamRow) {
|
|
326
329
|
queryString = (name || '') + '_' + table + '_' + limit + Db.asString(sort, true) + Db.asString(client, true) + (targetObject ? targetObject.toString() + cacheObjectKey : '');
|
|
327
330
|
}
|
|
328
331
|
if (aggregate) {
|
|
@@ -373,11 +376,34 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
373
376
|
tasks[i] = new Promise(async (resolve, reject) => {
|
|
374
377
|
let commandType;
|
|
375
378
|
try {
|
|
379
|
+
const instance = mongoClient || await getConnection(item, credential);
|
|
380
|
+
const command = item.command;
|
|
381
|
+
if (command) {
|
|
382
|
+
await Promise.all((!Array.isArray(command) ? [command] : command).map(async (cmd) => runCommand(instance, cmd)))
|
|
383
|
+
.then(items => items.forEach(output => this.addLog(this.statusType.INFO, output, "mongodb" /* STRINGS.MODULE_NAME */, 'runCommand')));
|
|
384
|
+
}
|
|
385
|
+
const collection = getCollection(instance);
|
|
386
|
+
if (update && coercing) {
|
|
387
|
+
(0, types_1.coerceObject)(update);
|
|
388
|
+
}
|
|
389
|
+
if (Array.isArray(update)) {
|
|
390
|
+
commandType = this.commandType.INSERT;
|
|
391
|
+
const insertOptions = item.execute?.insert;
|
|
392
|
+
if (insertOptions && coercing) {
|
|
393
|
+
(0, types_1.coerceObject)(insertOptions);
|
|
394
|
+
}
|
|
395
|
+
if (update.length === 1) {
|
|
396
|
+
await collection.insertOne(update[0], insertOptions);
|
|
397
|
+
}
|
|
398
|
+
else if (update.length > 1) {
|
|
399
|
+
await collection.insertMany(update, insertOptions);
|
|
400
|
+
}
|
|
401
|
+
update = undefined;
|
|
402
|
+
}
|
|
376
403
|
let cursor;
|
|
377
404
|
if (pipeline || query) {
|
|
378
|
-
const collection = getCollection(mongoClient || await getConnection(item, credential));
|
|
379
405
|
if (pipeline) {
|
|
380
|
-
const aggregateOptions = aggregate
|
|
406
|
+
const aggregateOptions = (0, types_1.isPlainObject)(aggregate) ? aggregate.options : undefined;
|
|
381
407
|
if (coercing) {
|
|
382
408
|
pipeline.forEach(doc => (0, types_1.coerceObject)(doc));
|
|
383
409
|
if (aggregateOptions) {
|
|
@@ -393,41 +419,22 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
393
419
|
}
|
|
394
420
|
}
|
|
395
421
|
else {
|
|
396
|
-
const [filter,
|
|
397
|
-
|
|
398
|
-
(0, types_1.coerceObject)(update);
|
|
399
|
-
}
|
|
400
|
-
if ((0, types_1.isArray)(update)) {
|
|
401
|
-
commandType = this.commandType.INSERT;
|
|
402
|
-
const insertOptions = item.execute?.insert;
|
|
403
|
-
if (insertOptions && coercing) {
|
|
404
|
-
(0, types_1.coerceObject)(insertOptions);
|
|
405
|
-
}
|
|
406
|
-
if (update.length === 1) {
|
|
407
|
-
await collection.insertOne(update[0], insertOptions);
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
await collection.insertMany(update, insertOptions);
|
|
411
|
-
}
|
|
412
|
-
update = undefined;
|
|
413
|
-
}
|
|
414
|
-
else if (item.updateType === 1) {
|
|
415
|
-
update = undefined;
|
|
416
|
-
}
|
|
422
|
+
const [filter, operation] = getFilterValue(query, coercing);
|
|
423
|
+
const updateType = item.updateType;
|
|
417
424
|
if (limit === 1) {
|
|
418
425
|
let document;
|
|
419
426
|
if (update) {
|
|
420
427
|
commandType = this.commandType.UPDATE;
|
|
421
|
-
document = await collection[
|
|
428
|
+
document = await collection[updateType === 2 ? 'findOneAndReplace' : updateType === 3 ? 'findOneAndDelete' : 'findOneAndUpdate'](filter, update, operation);
|
|
422
429
|
}
|
|
423
430
|
else {
|
|
424
431
|
commandType = this.commandType.SELECT;
|
|
425
|
-
document = await collection.findOne(filter,
|
|
432
|
+
document = await collection.findOne(filter, operation);
|
|
426
433
|
}
|
|
427
434
|
rows = document ? [document] : [];
|
|
428
435
|
}
|
|
429
436
|
else {
|
|
430
|
-
if (update) {
|
|
437
|
+
if (update && updateType === 1) {
|
|
431
438
|
commandType = this.commandType.UPDATE;
|
|
432
439
|
const updateOptions = item.execute?.update;
|
|
433
440
|
if (updateOptions && coercing) {
|
|
@@ -435,12 +442,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
435
442
|
}
|
|
436
443
|
await collection.updateMany(filter, update, updateOptions);
|
|
437
444
|
}
|
|
438
|
-
cursor = collection.find(filter,
|
|
445
|
+
cursor = collection.find(filter, operation);
|
|
439
446
|
}
|
|
440
447
|
}
|
|
441
448
|
}
|
|
442
449
|
else if (!aggregate) {
|
|
443
|
-
cursor =
|
|
450
|
+
cursor = collection.find();
|
|
444
451
|
}
|
|
445
452
|
if (cursor) {
|
|
446
453
|
commandType = this.commandType.SELECT;
|
|
@@ -518,12 +525,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
|
|
|
518
525
|
}
|
|
519
526
|
}
|
|
520
527
|
return this.processRows(batch, tasks, {
|
|
521
|
-
disconnect: () => clients.forEach(item => item.close(true)),
|
|
528
|
+
disconnect: () => clients.forEach(async (item) => item.close(true)),
|
|
522
529
|
parallel
|
|
523
530
|
}, outResult);
|
|
524
531
|
}
|
|
525
532
|
exports.executeBatchQuery = executeBatchQuery;
|
|
526
|
-
function checkTimeout(value, limit = 0) {
|
|
533
|
+
async function checkTimeout(value, limit = 0) {
|
|
527
534
|
return DbPool.checkTimeout(POOL_STATE, value, limit);
|
|
528
535
|
}
|
|
529
536
|
exports.checkTimeout = checkTimeout;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/mongodb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "MongoDB client driver for E-mc.",
|
|
5
5
|
"main": "client/index.js",
|
|
6
6
|
"types": "client/index.d.ts",
|
|
@@ -21,9 +21,9 @@
|
|
|
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/request": "^0.
|
|
26
|
-
"@e-mc/types": "^0.
|
|
24
|
+
"@e-mc/db": "^0.8.1",
|
|
25
|
+
"@e-mc/request": "^0.8.1",
|
|
26
|
+
"@e-mc/types": "^0.8.1",
|
|
27
27
|
"mongodb": "^6.3.0"
|
|
28
28
|
}
|
|
29
29
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { DbDataSource } from '@e-mc/types/lib/squared';
|
|
|
2
2
|
|
|
3
3
|
import type { CascadeAction, ServerAuth } from '@e-mc/types/lib/db';
|
|
4
4
|
|
|
5
|
-
import type { AggregateOptions, CollectionOptions, CommandOperationOptions, DbOptions, Document, Filter, MongoClientOptions, OptionalUnlessRequiredId, Sort, SortDirection, UpdateFilter } from 'mongodb';
|
|
5
|
+
import type { AggregateOptions, CollectionOptions, CommandOperationOptions, DbOptions, Document, Filter, MongoClientOptions, OptionalUnlessRequiredId, RunCommandOptions, Sort, SortDirection, UpdateFilter } from 'mongodb';
|
|
6
6
|
|
|
7
7
|
export interface MongoDBDataSource extends DbDataSource<Filter<Document> | MongoDBQueryWithOptions, MongoClientOptions, UpdateFilter<Document> | OptionalUnlessRequiredId<unknown>[], string | MongoDBCredential, string>, MongoDBClientDBOptions, CascadeAction {
|
|
8
8
|
source: "mongodb";
|
|
@@ -26,12 +26,14 @@ export interface MongoDBClientDBOptions {
|
|
|
26
26
|
client?: {
|
|
27
27
|
db?: DbOptions;
|
|
28
28
|
collection?: CollectionOptions;
|
|
29
|
+
command?: RunCommandOptions;
|
|
29
30
|
};
|
|
30
31
|
execute?: {
|
|
31
32
|
insert?: CommandOperationOptions;
|
|
32
33
|
update?: CommandOperationOptions;
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
+
command?: ArrayOf<Document>;
|
|
36
|
+
aggregate?: MongoDBAggregate | Document[];
|
|
35
37
|
sort?: Sort | string | MongoDBSortValue;
|
|
36
38
|
}
|
|
37
39
|
|