@opra/mongodb 1.0.0-alpha.16 → 1.0.0-alpha.18
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/cjs/adapter-utils/prepare-filter.js +1 -1
- package/cjs/adapter-utils/prepare-key-values.js +1 -1
- package/cjs/adapter-utils/prepare-patch.js +1 -1
- package/cjs/adapter-utils/prepare-projection.js +2 -3
- package/cjs/adapter-utils/prepare-sort.js +1 -1
- package/cjs/mongo-collection-service.js +111 -94
- package/cjs/mongo-entity-service.js +86 -69
- package/cjs/mongo-nested-service.js +236 -120
- package/cjs/mongo-service.js +31 -22
- package/cjs/mongo-singleton-service.js +61 -41
- package/esm/mongo-collection-service.js +111 -94
- package/esm/mongo-entity-service.js +86 -69
- package/esm/mongo-nested-service.js +236 -120
- package/esm/mongo-service.js +31 -22
- package/esm/mongo-singleton-service.js +61 -41
- package/package.json +5 -4
- package/types/mongo-collection-service.d.ts +32 -62
- package/types/mongo-entity-service.d.ts +73 -47
- package/types/mongo-nested-service.d.ts +55 -20
- package/types/mongo-service.d.ts +28 -26
- package/types/mongo-singleton-service.d.ts +19 -29
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ComplexType, NotAcceptableError, ResourceNotAvailableError } from '@opra/common';
|
|
2
2
|
import omit from 'lodash.omit';
|
|
3
|
+
import { isNotNullish } from 'valgen';
|
|
3
4
|
import { MongoAdapter } from './mongo-adapter.js';
|
|
4
5
|
import { MongoService } from './mongo-service.js';
|
|
5
6
|
/**
|
|
@@ -21,7 +22,7 @@ export class MongoNestedService extends MongoService {
|
|
|
21
22
|
this.fieldName = fieldName;
|
|
22
23
|
this.nestedKey = options?.nestedKey || '_id';
|
|
23
24
|
this.defaultLimit = options?.defaultLimit || 10;
|
|
24
|
-
this
|
|
25
|
+
this.nestedFilter = options?.nestedFilter;
|
|
25
26
|
}
|
|
26
27
|
/**
|
|
27
28
|
* Retrieves the data type of the array field
|
|
@@ -60,24 +61,21 @@ export class MongoNestedService extends MongoService {
|
|
|
60
61
|
* @throws {ResourceNotAvailableError} - If the parent document is not found.
|
|
61
62
|
*/
|
|
62
63
|
async create(documentId, input, options) {
|
|
63
|
-
const
|
|
64
|
-
if (id != null)
|
|
65
|
-
input._id = id;
|
|
66
|
-
const info = {
|
|
64
|
+
const command = {
|
|
67
65
|
crud: 'create',
|
|
68
66
|
method: 'create',
|
|
69
67
|
byId: false,
|
|
70
68
|
documentId,
|
|
71
|
-
nestedId: id,
|
|
72
69
|
input,
|
|
73
70
|
options,
|
|
74
71
|
};
|
|
75
|
-
return this.
|
|
72
|
+
return this._executeCommand(command, () => this._create(command));
|
|
76
73
|
}
|
|
77
|
-
async _create(
|
|
74
|
+
async _create(command) {
|
|
78
75
|
const inputCodec = this.getInputCodec('create');
|
|
79
|
-
const
|
|
80
|
-
doc
|
|
76
|
+
const { documentId, options } = command;
|
|
77
|
+
const doc = inputCodec(command.input);
|
|
78
|
+
doc._id = doc._id || this._generateId(command);
|
|
81
79
|
const docFilter = MongoAdapter.prepareKeyValues(documentId, ['_id']);
|
|
82
80
|
const r = await this._dbUpdateOne(docFilter, {
|
|
83
81
|
$push: { [this.fieldName]: doc },
|
|
@@ -85,12 +83,20 @@ export class MongoNestedService extends MongoService {
|
|
|
85
83
|
if (r.matchedCount) {
|
|
86
84
|
if (!options)
|
|
87
85
|
return doc;
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
const findCommand = {
|
|
87
|
+
crud: 'read',
|
|
88
|
+
method: 'findById',
|
|
89
|
+
byId: true,
|
|
90
|
+
documentId,
|
|
91
|
+
nestedId: doc[this.nestedKey],
|
|
92
|
+
options: {
|
|
93
|
+
...options,
|
|
94
|
+
sort: undefined,
|
|
95
|
+
filter: undefined,
|
|
96
|
+
skip: undefined,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
const out = await this._findById(findCommand);
|
|
94
100
|
if (out)
|
|
95
101
|
return out;
|
|
96
102
|
}
|
|
@@ -104,20 +110,22 @@ export class MongoNestedService extends MongoService {
|
|
|
104
110
|
* @returns {Promise<number>} - A promise that resolves to the count of documents.
|
|
105
111
|
*/
|
|
106
112
|
async count(documentId, options) {
|
|
107
|
-
const
|
|
113
|
+
const command = {
|
|
108
114
|
crud: 'read',
|
|
109
115
|
method: 'count',
|
|
110
116
|
byId: false,
|
|
111
117
|
documentId,
|
|
112
118
|
options,
|
|
113
119
|
};
|
|
114
|
-
return this.
|
|
115
|
-
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
116
|
-
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
return this._executeCommand(command, async () => {
|
|
121
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
122
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
123
|
+
command.options = { ...command.options, filter, documentFilter };
|
|
124
|
+
return this._count(command);
|
|
125
|
+
});
|
|
119
126
|
}
|
|
120
|
-
async _count(
|
|
127
|
+
async _count(command) {
|
|
128
|
+
const { documentId, options } = command;
|
|
121
129
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
122
130
|
MongoAdapter.prepareKeyValues(documentId, ['_id']),
|
|
123
131
|
options?.documentFilter,
|
|
@@ -150,7 +158,7 @@ export class MongoNestedService extends MongoService {
|
|
|
150
158
|
* @return {Promise<number>} - A Promise that resolves to the number of elements deleted (1 if successful, 0 if not).
|
|
151
159
|
*/
|
|
152
160
|
async delete(documentId, nestedId, options) {
|
|
153
|
-
const
|
|
161
|
+
const command = {
|
|
154
162
|
crud: 'delete',
|
|
155
163
|
method: 'delete',
|
|
156
164
|
byId: true,
|
|
@@ -158,13 +166,17 @@ export class MongoNestedService extends MongoService {
|
|
|
158
166
|
nestedId,
|
|
159
167
|
options,
|
|
160
168
|
};
|
|
161
|
-
return this.
|
|
162
|
-
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
163
|
-
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(
|
|
164
|
-
|
|
165
|
-
|
|
169
|
+
return this._executeCommand(command, async () => {
|
|
170
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
171
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
172
|
+
command.options = { ...command.options, filter, documentFilter };
|
|
173
|
+
return this._delete(command);
|
|
174
|
+
});
|
|
166
175
|
}
|
|
167
|
-
async _delete(
|
|
176
|
+
async _delete(command) {
|
|
177
|
+
const { documentId, nestedId, options } = command;
|
|
178
|
+
isNotNullish(documentId, { label: 'documentId' });
|
|
179
|
+
isNotNullish(documentId, { label: 'nestedId' });
|
|
168
180
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
169
181
|
MongoAdapter.prepareKeyValues(documentId, ['_id']),
|
|
170
182
|
options?.documentFilter,
|
|
@@ -183,20 +195,22 @@ export class MongoNestedService extends MongoService {
|
|
|
183
195
|
* @returns {Promise<number>} - A Promise that resolves to the number of items deleted.
|
|
184
196
|
*/
|
|
185
197
|
async deleteMany(documentId, options) {
|
|
186
|
-
const
|
|
198
|
+
const command = {
|
|
187
199
|
crud: 'delete',
|
|
188
200
|
method: 'deleteMany',
|
|
189
201
|
byId: false,
|
|
190
202
|
documentId,
|
|
191
203
|
options,
|
|
192
204
|
};
|
|
193
|
-
return this.
|
|
194
|
-
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
195
|
-
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(
|
|
196
|
-
|
|
197
|
-
|
|
205
|
+
return this._executeCommand(command, async () => {
|
|
206
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
207
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
208
|
+
command.options = { ...command.options, filter, documentFilter };
|
|
209
|
+
return this._deleteMany(command);
|
|
210
|
+
});
|
|
198
211
|
}
|
|
199
|
-
async _deleteMany(
|
|
212
|
+
async _deleteMany(command) {
|
|
213
|
+
const { documentId, options } = command;
|
|
200
214
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
201
215
|
MongoAdapter.prepareKeyValues(documentId, ['_id']),
|
|
202
216
|
options?.documentFilter,
|
|
@@ -220,7 +234,24 @@ export class MongoNestedService extends MongoService {
|
|
|
220
234
|
* @returns {Promise<boolean>} - A promise that resolves to a boolean indicating if the record exists or not.
|
|
221
235
|
*/
|
|
222
236
|
async exists(documentId, nestedId, options) {
|
|
223
|
-
|
|
237
|
+
const command = {
|
|
238
|
+
crud: 'read',
|
|
239
|
+
method: 'exists',
|
|
240
|
+
byId: true,
|
|
241
|
+
documentId,
|
|
242
|
+
nestedId,
|
|
243
|
+
options,
|
|
244
|
+
};
|
|
245
|
+
return this._executeCommand(command, async () => {
|
|
246
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
247
|
+
const filter = MongoAdapter.prepareFilter([
|
|
248
|
+
await this._getNestedFilter(command),
|
|
249
|
+
documentFilter,
|
|
250
|
+
command.options?.filter,
|
|
251
|
+
]);
|
|
252
|
+
command.options = { ...command.options, filter };
|
|
253
|
+
return !!(await this._findById(command));
|
|
254
|
+
});
|
|
224
255
|
}
|
|
225
256
|
/**
|
|
226
257
|
* Checks if an object with the given arguments exists.
|
|
@@ -230,7 +261,20 @@ export class MongoNestedService extends MongoService {
|
|
|
230
261
|
* @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the object exists or not.
|
|
231
262
|
*/
|
|
232
263
|
async existsOne(documentId, options) {
|
|
233
|
-
|
|
264
|
+
const command = {
|
|
265
|
+
crud: 'read',
|
|
266
|
+
method: 'exists',
|
|
267
|
+
byId: false,
|
|
268
|
+
documentId,
|
|
269
|
+
options,
|
|
270
|
+
};
|
|
271
|
+
return this._executeCommand(command, async () => {
|
|
272
|
+
const documentFilter = await this._getDocumentFilter(command);
|
|
273
|
+
const filter = MongoAdapter.prepareFilter([documentFilter, command.options?.filter]);
|
|
274
|
+
const findCommand = command;
|
|
275
|
+
findCommand.options = { ...command.options, filter, documentFilter, projection: ['_id'] };
|
|
276
|
+
return !!(await this._findOne(findCommand));
|
|
277
|
+
});
|
|
234
278
|
}
|
|
235
279
|
/**
|
|
236
280
|
* Finds an element in array field by its parent ID and ID.
|
|
@@ -241,7 +285,7 @@ export class MongoNestedService extends MongoService {
|
|
|
241
285
|
* @returns {Promise<PartialDTO<T> | undefined>} - A promise that resolves to the found document or undefined if not found.
|
|
242
286
|
*/
|
|
243
287
|
async findById(documentId, nestedId, options) {
|
|
244
|
-
const
|
|
288
|
+
const command = {
|
|
245
289
|
crud: 'read',
|
|
246
290
|
method: 'findById',
|
|
247
291
|
byId: true,
|
|
@@ -249,24 +293,32 @@ export class MongoNestedService extends MongoService {
|
|
|
249
293
|
nestedId,
|
|
250
294
|
options,
|
|
251
295
|
};
|
|
252
|
-
return this.
|
|
253
|
-
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
254
|
-
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(
|
|
255
|
-
|
|
256
|
-
|
|
296
|
+
return this._executeCommand(command, async () => {
|
|
297
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
298
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
299
|
+
command.options = { ...command.options, filter, documentFilter };
|
|
300
|
+
return this._findById(command);
|
|
301
|
+
});
|
|
257
302
|
}
|
|
258
|
-
async _findById(
|
|
303
|
+
async _findById(command) {
|
|
304
|
+
const { documentId, nestedId, options } = command;
|
|
305
|
+
isNotNullish(documentId, { label: 'documentId' });
|
|
306
|
+
isNotNullish(nestedId, { label: 'nestedId' });
|
|
259
307
|
const filter = MongoAdapter.prepareFilter([
|
|
260
308
|
MongoAdapter.prepareKeyValues(nestedId, [this.nestedKey]),
|
|
261
309
|
options?.filter,
|
|
262
310
|
]);
|
|
263
|
-
const
|
|
264
|
-
...
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
311
|
+
const findManyCommand = {
|
|
312
|
+
...command,
|
|
313
|
+
options: {
|
|
314
|
+
...options,
|
|
315
|
+
filter,
|
|
316
|
+
limit: 1,
|
|
317
|
+
skip: undefined,
|
|
318
|
+
sort: undefined,
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
const rows = await this._findMany(findManyCommand);
|
|
270
322
|
return rows?.[0];
|
|
271
323
|
}
|
|
272
324
|
/**
|
|
@@ -277,24 +329,31 @@ export class MongoNestedService extends MongoService {
|
|
|
277
329
|
* @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the first matching document, or `undefined` if no match is found.
|
|
278
330
|
*/
|
|
279
331
|
async findOne(documentId, options) {
|
|
280
|
-
const
|
|
332
|
+
const command = {
|
|
281
333
|
crud: 'read',
|
|
282
334
|
method: 'findOne',
|
|
283
335
|
byId: false,
|
|
284
336
|
documentId,
|
|
285
337
|
options,
|
|
286
338
|
};
|
|
287
|
-
return this.
|
|
288
|
-
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
289
|
-
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
async _findOne(documentId, options) {
|
|
294
|
-
const rows = await this._findMany(documentId, {
|
|
295
|
-
...options,
|
|
296
|
-
limit: 1,
|
|
339
|
+
return this._executeCommand(command, async () => {
|
|
340
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
341
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
342
|
+
command.options = { ...command.options, filter, documentFilter };
|
|
343
|
+
return this._findOne(command);
|
|
297
344
|
});
|
|
345
|
+
}
|
|
346
|
+
async _findOne(command) {
|
|
347
|
+
const { documentId, options } = command;
|
|
348
|
+
isNotNullish(documentId, { label: 'documentId' });
|
|
349
|
+
const findManyCommand = {
|
|
350
|
+
...command,
|
|
351
|
+
options: {
|
|
352
|
+
...options,
|
|
353
|
+
limit: 1,
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
const rows = await this._findMany(findManyCommand);
|
|
298
357
|
return rows?.[0];
|
|
299
358
|
}
|
|
300
359
|
/**
|
|
@@ -305,28 +364,31 @@ export class MongoNestedService extends MongoService {
|
|
|
305
364
|
* @returns {Promise<PartialDTO<T>[]>} - The found documents.
|
|
306
365
|
*/
|
|
307
366
|
async findMany(documentId, options) {
|
|
308
|
-
const
|
|
367
|
+
const command = {
|
|
309
368
|
crud: 'read',
|
|
310
369
|
method: 'findMany',
|
|
311
370
|
byId: false,
|
|
312
371
|
documentId,
|
|
313
372
|
options,
|
|
314
373
|
};
|
|
315
|
-
return this.
|
|
316
|
-
const documentFilter = await this._getDocumentFilter(
|
|
317
|
-
const nestedFilter = await this._getNestedFilter(
|
|
318
|
-
|
|
319
|
-
...options,
|
|
320
|
-
documentFilter,
|
|
374
|
+
return this._executeCommand(command, async () => {
|
|
375
|
+
const documentFilter = await this._getDocumentFilter(command);
|
|
376
|
+
const nestedFilter = await this._getNestedFilter(command);
|
|
377
|
+
command.options = {
|
|
378
|
+
...command.options,
|
|
321
379
|
nestedFilter,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
380
|
+
documentFilter,
|
|
381
|
+
limit: command.options?.limit || this.defaultLimit,
|
|
382
|
+
};
|
|
383
|
+
return this._findMany(command);
|
|
384
|
+
});
|
|
325
385
|
}
|
|
326
|
-
async _findMany(
|
|
386
|
+
async _findMany(command) {
|
|
387
|
+
const { documentId, options } = command;
|
|
388
|
+
isNotNullish(documentId, { label: 'documentId' });
|
|
327
389
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
328
390
|
MongoAdapter.prepareKeyValues(documentId, ['_id']),
|
|
329
|
-
options
|
|
391
|
+
options?.documentFilter,
|
|
330
392
|
]);
|
|
331
393
|
const mongoOptions = {
|
|
332
394
|
...omit(options, ['documentFilter', 'nestedFilter', 'projection', 'sort', 'skip', 'limit', 'filter', 'count']),
|
|
@@ -337,7 +399,7 @@ export class MongoNestedService extends MongoService {
|
|
|
337
399
|
{ $unwind: { path: '$' + this.fieldName } },
|
|
338
400
|
{ $replaceRoot: { newRoot: '$' + this.fieldName } },
|
|
339
401
|
];
|
|
340
|
-
if (options?.filter || options
|
|
402
|
+
if (options?.filter || options?.nestedFilter) {
|
|
341
403
|
const optionsFilter = MongoAdapter.prepareFilter([options?.filter, options.nestedFilter]);
|
|
342
404
|
stages.push({ $match: optionsFilter });
|
|
343
405
|
}
|
|
@@ -372,28 +434,31 @@ export class MongoNestedService extends MongoService {
|
|
|
372
434
|
* @returns {Promise<PartialDTO<T>[]>} - The found documents.
|
|
373
435
|
*/
|
|
374
436
|
async findManyWithCount(documentId, options) {
|
|
375
|
-
const
|
|
437
|
+
const command = {
|
|
376
438
|
crud: 'read',
|
|
377
439
|
method: 'findMany',
|
|
378
440
|
byId: false,
|
|
379
441
|
documentId,
|
|
380
442
|
options,
|
|
381
443
|
};
|
|
382
|
-
return this.
|
|
383
|
-
const documentFilter = await this._getDocumentFilter(
|
|
384
|
-
const nestedFilter = await this._getNestedFilter(
|
|
385
|
-
|
|
386
|
-
...options,
|
|
387
|
-
documentFilter,
|
|
444
|
+
return this._executeCommand(command, async () => {
|
|
445
|
+
const documentFilter = await this._getDocumentFilter(command);
|
|
446
|
+
const nestedFilter = await this._getNestedFilter(command);
|
|
447
|
+
command.options = {
|
|
448
|
+
...command.options,
|
|
388
449
|
nestedFilter,
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
450
|
+
documentFilter,
|
|
451
|
+
limit: command.options?.limit || this.defaultLimit,
|
|
452
|
+
};
|
|
453
|
+
return this._findManyWithCount(command);
|
|
454
|
+
});
|
|
392
455
|
}
|
|
393
|
-
async _findManyWithCount(
|
|
456
|
+
async _findManyWithCount(command) {
|
|
457
|
+
const { documentId, options } = command;
|
|
458
|
+
isNotNullish(documentId, { label: 'documentId' });
|
|
394
459
|
const matchFilter = MongoAdapter.prepareFilter([
|
|
395
460
|
MongoAdapter.prepareKeyValues(documentId, ['_id']),
|
|
396
|
-
options
|
|
461
|
+
options?.documentFilter,
|
|
397
462
|
]);
|
|
398
463
|
const mongoOptions = {
|
|
399
464
|
...omit(options, ['pick', 'include', 'omit', 'sort', 'skip', 'limit', 'filter', 'count']),
|
|
@@ -411,8 +476,8 @@ export class MongoNestedService extends MongoService {
|
|
|
411
476
|
},
|
|
412
477
|
},
|
|
413
478
|
];
|
|
414
|
-
if (options?.filter || options
|
|
415
|
-
const optionsFilter = MongoAdapter.prepareFilter([options?.filter, options
|
|
479
|
+
if (options?.filter || options?.nestedFilter) {
|
|
480
|
+
const optionsFilter = MongoAdapter.prepareFilter([options?.filter, options?.nestedFilter]);
|
|
416
481
|
dataStages.push({ $match: optionsFilter });
|
|
417
482
|
}
|
|
418
483
|
if (options?.skip)
|
|
@@ -465,21 +530,44 @@ export class MongoNestedService extends MongoService {
|
|
|
465
530
|
* @param {AnyId} documentId - The ID of the document to update.
|
|
466
531
|
* @param {AnyId} nestedId - The ID of the item to update within the document.
|
|
467
532
|
* @param {PatchDTO<T>} input - The new data to update the item with.
|
|
468
|
-
* @param {MongoNestedService.
|
|
533
|
+
* @param {MongoNestedService.UpdateOneOptions<T>} [options] - Additional update options.
|
|
469
534
|
* @returns {Promise<PartialDTO<T> | undefined>} The updated item or undefined if it does not exist.
|
|
470
535
|
* @throws {Error} If an error occurs while updating the item.
|
|
471
536
|
*/
|
|
472
537
|
async update(documentId, nestedId, input, options) {
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
538
|
+
const command = {
|
|
539
|
+
crud: 'update',
|
|
540
|
+
method: 'update',
|
|
541
|
+
byId: true,
|
|
542
|
+
documentId,
|
|
543
|
+
nestedId,
|
|
544
|
+
input,
|
|
545
|
+
options,
|
|
546
|
+
};
|
|
547
|
+
return this._executeCommand(command, async () => {
|
|
548
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
549
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
550
|
+
command.options = {
|
|
551
|
+
...command.options,
|
|
552
|
+
filter,
|
|
553
|
+
documentFilter,
|
|
554
|
+
};
|
|
555
|
+
const r = await this._updateOnly(command);
|
|
556
|
+
if (r) {
|
|
557
|
+
const findCommand = {
|
|
558
|
+
crud: 'read',
|
|
559
|
+
method: 'findById',
|
|
560
|
+
byId: true,
|
|
561
|
+
documentId,
|
|
562
|
+
nestedId,
|
|
563
|
+
options: { ...options, sort: undefined },
|
|
564
|
+
};
|
|
565
|
+
const out = this._findById(findCommand);
|
|
566
|
+
if (out)
|
|
567
|
+
return out;
|
|
568
|
+
}
|
|
569
|
+
throw new ResourceNotAvailableError(this.getResourceName() + '.' + this.nestedKey, documentId + '/' + nestedId);
|
|
479
570
|
});
|
|
480
|
-
if (out)
|
|
481
|
-
return out;
|
|
482
|
-
throw new ResourceNotAvailableError(this.getResourceName() + '.' + this.nestedKey, documentId + '/' + nestedId);
|
|
483
571
|
}
|
|
484
572
|
/**
|
|
485
573
|
* Update an array element with new data. Returns 1 if document updated 0 otherwise.
|
|
@@ -487,29 +575,45 @@ export class MongoNestedService extends MongoService {
|
|
|
487
575
|
* @param {MongoAdapter.AnyId} documentId - The ID of the parent document.
|
|
488
576
|
* @param {MongoAdapter.AnyId} nestedId - The ID of the document to update.
|
|
489
577
|
* @param {PatchDTO<T>} input - The partial input object containing the fields to update.
|
|
490
|
-
* @param {MongoNestedService.
|
|
578
|
+
* @param {MongoNestedService.UpdateOneOptions<T>} [options] - Optional update options.
|
|
491
579
|
* @returns {Promise<number>} - A promise that resolves to the number of elements updated.
|
|
492
580
|
*/
|
|
493
581
|
async updateOnly(documentId, nestedId, input, options) {
|
|
494
|
-
const
|
|
582
|
+
const command = {
|
|
495
583
|
crud: 'update',
|
|
496
584
|
method: 'update',
|
|
497
585
|
byId: true,
|
|
498
586
|
documentId,
|
|
499
587
|
nestedId,
|
|
588
|
+
input,
|
|
500
589
|
options,
|
|
501
590
|
};
|
|
502
|
-
return this.
|
|
503
|
-
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
504
|
-
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(
|
|
505
|
-
|
|
506
|
-
|
|
591
|
+
return this._executeCommand(command, async () => {
|
|
592
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
593
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
594
|
+
command.options = {
|
|
595
|
+
...command.options,
|
|
596
|
+
filter,
|
|
597
|
+
documentFilter,
|
|
598
|
+
};
|
|
599
|
+
return await this._updateOnly(command);
|
|
600
|
+
});
|
|
507
601
|
}
|
|
508
|
-
async _updateOnly(
|
|
602
|
+
async _updateOnly(command) {
|
|
603
|
+
const { documentId, nestedId, options } = command;
|
|
604
|
+
isNotNullish(documentId, { label: 'documentId' });
|
|
605
|
+
isNotNullish(nestedId, { label: 'nestedId' });
|
|
509
606
|
let filter = MongoAdapter.prepareKeyValues(nestedId, [this.nestedKey]);
|
|
510
607
|
if (options?.filter)
|
|
511
608
|
filter = MongoAdapter.prepareFilter([filter, options?.filter]);
|
|
512
|
-
|
|
609
|
+
const updateManyCommand = {
|
|
610
|
+
...command,
|
|
611
|
+
options: {
|
|
612
|
+
...command.options,
|
|
613
|
+
filter,
|
|
614
|
+
},
|
|
615
|
+
};
|
|
616
|
+
return await this._updateMany(updateManyCommand);
|
|
513
617
|
}
|
|
514
618
|
/**
|
|
515
619
|
* Updates multiple array elements in document
|
|
@@ -520,7 +624,7 @@ export class MongoNestedService extends MongoService {
|
|
|
520
624
|
* @returns {Promise<number>} - A promise that resolves to the number of documents updated.
|
|
521
625
|
*/
|
|
522
626
|
async updateMany(documentId, input, options) {
|
|
523
|
-
const
|
|
627
|
+
const command = {
|
|
524
628
|
crud: 'update',
|
|
525
629
|
method: 'updateMany',
|
|
526
630
|
documentId,
|
|
@@ -528,13 +632,17 @@ export class MongoNestedService extends MongoService {
|
|
|
528
632
|
input,
|
|
529
633
|
options,
|
|
530
634
|
};
|
|
531
|
-
return this.
|
|
532
|
-
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(
|
|
533
|
-
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(
|
|
534
|
-
|
|
535
|
-
|
|
635
|
+
return this._executeCommand(command, async () => {
|
|
636
|
+
const documentFilter = MongoAdapter.prepareFilter([await this._getDocumentFilter(command)]);
|
|
637
|
+
const filter = MongoAdapter.prepareFilter([await this._getNestedFilter(command), command.options?.filter]);
|
|
638
|
+
command.options = { ...command.options, filter, documentFilter };
|
|
639
|
+
return this._updateMany(command);
|
|
640
|
+
});
|
|
536
641
|
}
|
|
537
|
-
async _updateMany(
|
|
642
|
+
async _updateMany(command) {
|
|
643
|
+
const { documentId, input } = command;
|
|
644
|
+
isNotNullish(documentId, { label: 'documentId' });
|
|
645
|
+
let options = command.options;
|
|
538
646
|
const inputCodec = this.getInputCodec('update');
|
|
539
647
|
const doc = inputCodec(input);
|
|
540
648
|
if (!Object.keys(doc).length)
|
|
@@ -553,8 +661,16 @@ export class MongoNestedService extends MongoService {
|
|
|
553
661
|
fieldPrefix: this.fieldName + (options?.filter ? '.$[elem].' : '.$[].'),
|
|
554
662
|
});
|
|
555
663
|
const r = await this._dbUpdateOne(matchFilter, update, options);
|
|
556
|
-
if (options?.count)
|
|
557
|
-
|
|
664
|
+
if (options?.count) {
|
|
665
|
+
const countCommand = {
|
|
666
|
+
crud: 'read',
|
|
667
|
+
method: 'count',
|
|
668
|
+
byId: false,
|
|
669
|
+
documentId,
|
|
670
|
+
options,
|
|
671
|
+
};
|
|
672
|
+
return await this._count(countCommand);
|
|
673
|
+
}
|
|
558
674
|
return r.modifiedCount || 0;
|
|
559
675
|
}
|
|
560
676
|
/**
|
|
@@ -566,6 +682,6 @@ export class MongoNestedService extends MongoService {
|
|
|
566
682
|
* that resolves to the common filter, or undefined if not available.
|
|
567
683
|
*/
|
|
568
684
|
_getNestedFilter(args) {
|
|
569
|
-
return typeof this
|
|
685
|
+
return typeof this.nestedFilter === 'function' ? this.nestedFilter(args, this) : this.nestedFilter;
|
|
570
686
|
}
|
|
571
687
|
}
|