@pi-r/mongodb 0.5.1 → 0.6.0

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 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
- return this.closed ? Promise.resolve() : this.close(force);
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.indexOf('?') === -1) {
111
- if (uri[uri.length - 1] !== '/') {
112
- uri += '/';
113
- }
114
- uri += '?';
113
+ if (!uri.includes('?')) {
114
+ uri += (uri.endsWith('/') ? '' : '/') + '?';
115
115
  }
116
- uri += (uri[uri.length - 1] !== '?' ? '&' : '') + 'authMechanism=' + encodeURIComponent(authMechanism);
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
- let username, password, pool;
180
- if (typeof usePool === 'string' && (username = options.auth?.username || item.uri && (0, util_1.parseConnectionString)(item.uri)?.username)) {
181
- [password, pool] = DbPool.validateKey(POOL_STATE, username, usePool);
182
- if (pool) {
183
- pool.add(item, password);
184
- return;
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
- const poolKey = getPoolKey(item);
188
- if (poolKey) {
189
- if (!(pool = POOL_STATE[poolKey]) || pool.closed) {
190
- const config = this.getPoolConfig("mongodb" /* STRINGS.MODULE_NAME */, password);
191
- if (config) {
192
- const { min, max, idle, queue_max, queue_idle, timeout, socket_timeout } = config;
193
- if (min >= 0) {
194
- options.minPoolSize ?? (options.minPoolSize = min);
195
- }
196
- if (max > 0) {
197
- options.maxPoolSize ?? (options.maxPoolSize = max);
198
- }
199
- if (idle >= 0) {
200
- options.maxIdleTimeMS ?? (options.maxIdleTimeMS = idle);
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
- else {
222
- item.usePool = false;
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,7 +314,9 @@ async function executeBatchQuery(batch, options = '', outResult) {
312
314
  continue;
313
315
  }
314
316
  item.transactionState = 1 /* DB_TRANSACTION.ACTIVE */;
315
- const getCollection = (target) => target.db(name, client?.db).collection(table, client?.collection);
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
321
  const renewCache = ignoreCache === 0;
318
322
  const cacheValue = renewCache ? { sessionKey, renewCache } : sessionKey;
@@ -373,11 +377,17 @@ async function executeBatchQuery(batch, options = '', outResult) {
373
377
  tasks[i] = new Promise(async (resolve, reject) => {
374
378
  let commandType;
375
379
  try {
380
+ const instance = mongoClient || await getConnection(item, credential);
381
+ const command = item.command;
382
+ if (command) {
383
+ await Promise.all((!Array.isArray(command) ? [command] : command).map(async (cmd) => runCommand(instance, cmd)))
384
+ .then(items => items.forEach(output => this.addLog(this.statusType.INFO, output, "mongodb" /* STRINGS.MODULE_NAME */, 'runCommand')));
385
+ }
376
386
  let cursor;
377
387
  if (pipeline || query) {
378
- const collection = getCollection(mongoClient || await getConnection(item, credential));
388
+ const collection = getCollection(instance);
379
389
  if (pipeline) {
380
- const aggregateOptions = aggregate?.options;
390
+ const aggregateOptions = (0, types_1.isPlainObject)(aggregate) ? aggregate.options : undefined;
381
391
  if (coercing) {
382
392
  pipeline.forEach(doc => (0, types_1.coerceObject)(doc));
383
393
  if (aggregateOptions) {
@@ -393,7 +403,7 @@ async function executeBatchQuery(batch, options = '', outResult) {
393
403
  }
394
404
  }
395
405
  else {
396
- const [filter, command] = getFilterValue(query, coercing);
406
+ const [filter, operation] = getFilterValue(query, coercing);
397
407
  if (update && coercing) {
398
408
  (0, types_1.coerceObject)(update);
399
409
  }
@@ -418,11 +428,11 @@ async function executeBatchQuery(batch, options = '', outResult) {
418
428
  let document;
419
429
  if (update) {
420
430
  commandType = this.commandType.UPDATE;
421
- document = await collection[item.updateType === 2 ? 'findOneAndReplace' : item.updateType === 3 ? 'findOneAndDelete' : 'findOneAndUpdate'](filter, update, command);
431
+ document = await collection[item.updateType === 2 ? 'findOneAndReplace' : item.updateType === 3 ? 'findOneAndDelete' : 'findOneAndUpdate'](filter, update, operation);
422
432
  }
423
433
  else {
424
434
  commandType = this.commandType.SELECT;
425
- document = await collection.findOne(filter, command);
435
+ document = await collection.findOne(filter, operation);
426
436
  }
427
437
  rows = document ? [document] : [];
428
438
  }
@@ -435,12 +445,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
435
445
  }
436
446
  await collection.updateMany(filter, update, updateOptions);
437
447
  }
438
- cursor = collection.find(filter, command);
448
+ cursor = collection.find(filter, operation);
439
449
  }
440
450
  }
441
451
  }
442
452
  else if (!aggregate) {
443
- cursor = getCollection(mongoClient || await getConnection(item, credential)).find();
453
+ cursor = getCollection(instance).find();
444
454
  }
445
455
  if (cursor) {
446
456
  commandType = this.commandType.SELECT;
@@ -518,12 +528,12 @@ async function executeBatchQuery(batch, options = '', outResult) {
518
528
  }
519
529
  }
520
530
  return this.processRows(batch, tasks, {
521
- disconnect: () => clients.forEach(item => item.close(true)),
531
+ disconnect: () => clients.forEach(async (item) => item.close(true)),
522
532
  parallel
523
533
  }, outResult);
524
534
  }
525
535
  exports.executeBatchQuery = executeBatchQuery;
526
- function checkTimeout(value, limit = 0) {
536
+ async function checkTimeout(value, limit = 0) {
527
537
  return DbPool.checkTimeout(POOL_STATE, value, limit);
528
538
  }
529
539
  exports.checkTimeout = checkTimeout;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/mongodb",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
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.7.0",
25
- "@e-mc/request": "^0.7.0",
26
- "@e-mc/types": "^0.7.0",
24
+ "@e-mc/db": "^0.8.0",
25
+ "@e-mc/request": "^0.8.0",
26
+ "@e-mc/types": "^0.8.0",
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
- aggregate?: MongoDBAggregate;
35
+ command?: ArrayOf<Document>;
36
+ aggregate?: MongoDBAggregate | Document[];
35
37
  sort?: Sort | string | MongoDBSortValue;
36
38
  }
37
39