@opra/mongodb 0.31.13 → 0.32.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/cjs/adapter-utils/prepare-filter.js +65 -10
- package/cjs/adapter-utils/prepare-patch.js +1 -0
- package/cjs/adapter-utils/prepare-projection.js +40 -40
- package/cjs/index.js +2 -0
- package/cjs/mongo-array-service.js +344 -0
- package/cjs/mongo-collection-service.js +243 -81
- package/cjs/mongo-service.js +119 -13
- package/cjs/mongo-singleton-service.js +61 -48
- package/cjs/types.js +2 -0
- package/esm/adapter-utils/prepare-filter.js +65 -10
- package/esm/adapter-utils/prepare-patch.js +1 -0
- package/esm/adapter-utils/prepare-projection.js +38 -37
- package/esm/index.js +2 -0
- package/esm/mongo-array-service.js +339 -0
- package/esm/mongo-collection-service.js +243 -81
- package/esm/mongo-service.js +119 -13
- package/esm/mongo-singleton-service.js +61 -47
- package/esm/types.js +1 -0
- package/package.json +4 -4
- package/types/adapter-utils/prepare-filter.d.ts +10 -2
- package/types/adapter-utils/prepare-projection.d.ts +7 -3
- package/types/index.d.ts +2 -0
- package/types/mongo-array-service.d.ts +193 -0
- package/types/mongo-collection-service.d.ts +120 -18
- package/types/mongo-service.d.ts +91 -11
- package/types/mongo-singleton-service.d.ts +42 -7
- package/types/types.d.ts +2 -0
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MongoCollectionService = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const lodash_omit_1 = tslib_1.__importDefault(require("lodash.omit"));
|
|
6
|
+
const mongodb_1 = require("mongodb");
|
|
6
7
|
const common_1 = require("@opra/common");
|
|
7
8
|
const mongo_adapter_js_1 = require("./mongo-adapter.js");
|
|
8
9
|
const mongo_service_js_1 = require("./mongo-service.js");
|
|
@@ -13,112 +14,232 @@ const mongo_service_js_1 = require("./mongo-service.js");
|
|
|
13
14
|
class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
14
15
|
constructor(dataType, options) {
|
|
15
16
|
super(dataType, options);
|
|
17
|
+
this._encoders = {};
|
|
16
18
|
this.defaultLimit = options?.defaultLimit || 10;
|
|
17
|
-
this.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
this.collectionKey = options?.collectionKey || '_id';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Checks if document exists. Throws error if not.
|
|
23
|
+
*
|
|
24
|
+
* @param id
|
|
25
|
+
*/
|
|
26
|
+
async assert(id) {
|
|
27
|
+
if (!(await this.exists(id)))
|
|
28
|
+
throw new common_1.ResourceNotFoundError(this.resourceName || this.getCollectionName(), id);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Inserts a single document into MongoDB
|
|
32
|
+
*
|
|
33
|
+
* @param input
|
|
34
|
+
* @param options
|
|
35
|
+
*/
|
|
36
|
+
async create(input, options) {
|
|
37
|
+
const encode = this._getEncoder('create');
|
|
38
|
+
const doc = encode(input);
|
|
39
|
+
doc._id = doc._id || this._generateId();
|
|
40
|
+
const r = await this.__insertOne(doc, options);
|
|
41
|
+
if (r.insertedId)
|
|
42
|
+
return doc;
|
|
27
43
|
/* istanbul ignore next */
|
|
28
44
|
throw new Error('Unknown error while creating document');
|
|
29
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Gets the number of documents matching the filter.
|
|
48
|
+
*
|
|
49
|
+
* @param options
|
|
50
|
+
*/
|
|
30
51
|
async count(options) {
|
|
31
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter)
|
|
32
|
-
return this.
|
|
52
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
53
|
+
return this.__countDocuments(filter, (0, lodash_omit_1.default)(options, 'filter'));
|
|
33
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Delete a document from a collection
|
|
57
|
+
*
|
|
58
|
+
* @param id
|
|
59
|
+
* @param options
|
|
60
|
+
*/
|
|
34
61
|
async delete(id, options) {
|
|
35
|
-
const filter = mongo_adapter_js_1.MongoAdapter.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const r = await this.
|
|
62
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
63
|
+
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
64
|
+
options?.filter
|
|
65
|
+
]);
|
|
66
|
+
const r = await this.__deleteOne(filter, options);
|
|
40
67
|
return r.deletedCount;
|
|
41
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Delete multiple documents from a collection
|
|
71
|
+
*
|
|
72
|
+
* @param options
|
|
73
|
+
*/
|
|
42
74
|
async deleteMany(options) {
|
|
43
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter)
|
|
44
|
-
const r = await this.
|
|
75
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
76
|
+
const r = await this.__deleteMany(filter, (0, lodash_omit_1.default)(options, 'filter'));
|
|
45
77
|
return r.deletedCount;
|
|
46
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Checks if document exists.
|
|
81
|
+
* Returns true if document exists, false otherwise
|
|
82
|
+
*
|
|
83
|
+
* @param id
|
|
84
|
+
*/
|
|
85
|
+
async exists(id) {
|
|
86
|
+
return !!(await this.findById(id, { pick: ['_id'] }));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Fetches the first document matches by id.
|
|
90
|
+
*
|
|
91
|
+
* @param id
|
|
92
|
+
* @param options
|
|
93
|
+
*/
|
|
94
|
+
async findById(id, options) {
|
|
95
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
96
|
+
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
97
|
+
options?.filter
|
|
98
|
+
]);
|
|
99
|
+
return await this.findOne({ ...options, filter });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Fetches the first document that matches the filter.
|
|
103
|
+
* Returns undefined if not found.
|
|
104
|
+
*
|
|
105
|
+
* @param options
|
|
106
|
+
*/
|
|
107
|
+
async findOne(options) {
|
|
108
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
109
|
+
const mongoOptions = {
|
|
110
|
+
...options,
|
|
111
|
+
sort: options?.sort ? mongo_adapter_js_1.MongoAdapter.prepareSort(options.sort) : undefined,
|
|
112
|
+
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
113
|
+
limit: undefined
|
|
114
|
+
};
|
|
115
|
+
const out = await this.__findOne(filter, mongoOptions);
|
|
116
|
+
return out || undefined;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Fetches all document that matches the filter
|
|
120
|
+
*
|
|
121
|
+
* @param options
|
|
122
|
+
*/
|
|
123
|
+
async findMany(options) {
|
|
124
|
+
const mongoOptions = {
|
|
125
|
+
...(0, lodash_omit_1.default)(options, ['pick', 'include', 'omit', 'sort', 'skip', 'limit', 'filter', 'count'])
|
|
126
|
+
};
|
|
127
|
+
const limit = options?.limit || this.defaultLimit;
|
|
128
|
+
const stages = [];
|
|
129
|
+
let dataStages = stages;
|
|
130
|
+
if (options?.count) {
|
|
131
|
+
dataStages = [];
|
|
132
|
+
stages.push({
|
|
133
|
+
$facet: {
|
|
134
|
+
data: dataStages,
|
|
135
|
+
count: [{ $count: 'totalMatches' }]
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
if (options?.filter) {
|
|
140
|
+
const optionsFilter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
141
|
+
dataStages.push({ $match: optionsFilter });
|
|
142
|
+
}
|
|
143
|
+
if (options?.skip)
|
|
144
|
+
dataStages.push({ $skip: options.skip });
|
|
145
|
+
if (options?.sort) {
|
|
146
|
+
const sort = mongo_adapter_js_1.MongoAdapter.prepareSort(options.sort);
|
|
147
|
+
if (sort)
|
|
148
|
+
dataStages.push({ $sort: sort });
|
|
149
|
+
}
|
|
150
|
+
dataStages.push({ $limit: limit });
|
|
151
|
+
const dataType = this.getDataType();
|
|
152
|
+
const projection = mongo_adapter_js_1.MongoAdapter.prepareProjection(dataType, options);
|
|
153
|
+
if (projection)
|
|
154
|
+
dataStages.push({ $project: projection });
|
|
155
|
+
const cursor = await this.__aggregate(stages, {
|
|
156
|
+
...mongoOptions
|
|
157
|
+
});
|
|
158
|
+
try {
|
|
159
|
+
if (options?.count) {
|
|
160
|
+
const facetResult = await cursor.toArray();
|
|
161
|
+
this.context.response.totalMatches = facetResult[0].count[0].totalMatches || 0;
|
|
162
|
+
return facetResult[0].data;
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
return await cursor.toArray();
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
if (!cursor.closed)
|
|
169
|
+
await cursor.close();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Fetches the first Document that matches the id. Throws error undefined if not found.
|
|
174
|
+
*
|
|
175
|
+
* @param id
|
|
176
|
+
* @param options
|
|
177
|
+
*/
|
|
47
178
|
async get(id, options) {
|
|
48
|
-
const
|
|
49
|
-
const optionsFilter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
50
|
-
if (optionsFilter)
|
|
51
|
-
filter.$and = [...(Array.isArray(optionsFilter) ? optionsFilter : [optionsFilter])];
|
|
52
|
-
const out = await this.findOne({ ...options, filter });
|
|
179
|
+
const out = await this.findById(id, options);
|
|
53
180
|
if (!out)
|
|
54
181
|
throw new common_1.ResourceNotFoundError(this.resourceName || this.getCollectionName(), id);
|
|
55
182
|
return out;
|
|
56
183
|
}
|
|
57
|
-
|
|
58
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Updates a single document.
|
|
186
|
+
* Returns updated document
|
|
187
|
+
*
|
|
188
|
+
* @param id
|
|
189
|
+
* @param input
|
|
190
|
+
* @param options
|
|
191
|
+
*/
|
|
192
|
+
async update(id, input, options) {
|
|
193
|
+
const encode = this._getEncoder('update');
|
|
194
|
+
const doc = encode(input);
|
|
195
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
196
|
+
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
197
|
+
options?.filter
|
|
198
|
+
]);
|
|
199
|
+
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
59
200
|
const mongoOptions = {
|
|
60
|
-
...
|
|
201
|
+
...options,
|
|
202
|
+
includeResultMetadata: false,
|
|
203
|
+
upsert: undefined,
|
|
61
204
|
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
62
205
|
};
|
|
63
|
-
const out = await this.
|
|
64
|
-
|
|
65
|
-
if (this.transformData)
|
|
66
|
-
return this.transformData(out);
|
|
67
|
-
return out;
|
|
68
|
-
}
|
|
206
|
+
const out = await this.__findOneAndUpdate(filter, patch, mongoOptions);
|
|
207
|
+
return out || undefined;
|
|
69
208
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
let obj;
|
|
83
|
-
while (out.length < this.defaultLimit && (obj = await cursor.next())) {
|
|
84
|
-
const v = this.transformData ? this.transformData(obj) : obj;
|
|
85
|
-
if (v)
|
|
86
|
-
out.push(obj);
|
|
87
|
-
}
|
|
88
|
-
return out;
|
|
89
|
-
}
|
|
90
|
-
finally {
|
|
91
|
-
await cursor.close();
|
|
92
|
-
}
|
|
93
|
-
}),
|
|
94
|
-
// Promise that returns count
|
|
95
|
-
(options?.count ? this.count(options) : Promise.resolve()),
|
|
209
|
+
/**
|
|
210
|
+
* Updates a single document
|
|
211
|
+
* Returns number of updated documents
|
|
212
|
+
*
|
|
213
|
+
* @param id
|
|
214
|
+
* @param input
|
|
215
|
+
* @param options
|
|
216
|
+
*/
|
|
217
|
+
async updateOnly(id, input, options) {
|
|
218
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
219
|
+
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
220
|
+
options?.filter
|
|
96
221
|
]);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return items;
|
|
100
|
-
}
|
|
101
|
-
async update(id, doc, options) {
|
|
102
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, this.keyFields);
|
|
103
|
-
const optionsFilter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
104
|
-
if (optionsFilter)
|
|
105
|
-
filter.$and = [...(Array.isArray(optionsFilter) ? optionsFilter : [optionsFilter])];
|
|
106
|
-
// Prevent updating _id field
|
|
107
|
-
delete doc._id;
|
|
222
|
+
const encode = this._getEncoder('update');
|
|
223
|
+
const doc = encode(input);
|
|
108
224
|
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
109
|
-
patch.$set = patch.$set || {};
|
|
110
225
|
const mongoOptions = {
|
|
111
226
|
...options,
|
|
112
|
-
|
|
227
|
+
includeResultMetadata: false,
|
|
228
|
+
upsert: undefined,
|
|
229
|
+
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
113
230
|
};
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
231
|
+
const out = await this.__updateOne(filter, patch, mongoOptions);
|
|
232
|
+
return out.modifiedCount;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Update multiple documents in a collection
|
|
236
|
+
*
|
|
237
|
+
* @param input
|
|
238
|
+
* @param options
|
|
239
|
+
*/
|
|
240
|
+
async updateMany(input, options) {
|
|
241
|
+
const encode = this._getEncoder('update');
|
|
242
|
+
const doc = encode(input);
|
|
122
243
|
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
123
244
|
patch.$set = patch.$set || {};
|
|
124
245
|
const mongoOptions = {
|
|
@@ -126,8 +247,49 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
126
247
|
upsert: undefined
|
|
127
248
|
};
|
|
128
249
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter) || {};
|
|
129
|
-
const r = await this.
|
|
250
|
+
const r = await this.__updateMany(filter, patch, mongoOptions);
|
|
130
251
|
return r.matchedCount;
|
|
131
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Generates Id value
|
|
255
|
+
*
|
|
256
|
+
* @protected
|
|
257
|
+
*/
|
|
258
|
+
_generateId() {
|
|
259
|
+
return new mongodb_1.ObjectId();
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Generates a new Validator for encoding or returns from cache if already generated before
|
|
263
|
+
* @param operation
|
|
264
|
+
* @protected
|
|
265
|
+
*/
|
|
266
|
+
_getEncoder(operation) {
|
|
267
|
+
let encoder = this._encoders[operation];
|
|
268
|
+
if (encoder)
|
|
269
|
+
return encoder;
|
|
270
|
+
encoder = this._generateEncoder(operation);
|
|
271
|
+
this._encoders[operation] = encoder;
|
|
272
|
+
return encoder;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Generates a new Valgen Validator for encode operation
|
|
276
|
+
*
|
|
277
|
+
* @param operation
|
|
278
|
+
* @protected
|
|
279
|
+
*/
|
|
280
|
+
_generateEncoder(operation) {
|
|
281
|
+
let encoder = this._encoders[operation];
|
|
282
|
+
if (encoder)
|
|
283
|
+
return encoder;
|
|
284
|
+
const dataType = this.getDataType();
|
|
285
|
+
const options = {};
|
|
286
|
+
if (operation === 'update') {
|
|
287
|
+
options.omit = ['_id'];
|
|
288
|
+
options.partial = true;
|
|
289
|
+
}
|
|
290
|
+
encoder = dataType.generateCodec('encode', options);
|
|
291
|
+
this._encoders[operation] = encoder;
|
|
292
|
+
return encoder;
|
|
293
|
+
}
|
|
132
294
|
}
|
|
133
295
|
exports.MongoCollectionService = MongoCollectionService;
|
package/cjs/mongo-service.js
CHANGED
|
@@ -20,10 +20,22 @@ class MongoService extends core_1.ApiService {
|
|
|
20
20
|
}
|
|
21
21
|
this.resourceName = options?.resourceName || this.collectionName;
|
|
22
22
|
}
|
|
23
|
+
getDataType() {
|
|
24
|
+
return this.context.api.getComplexType(this._dataType);
|
|
25
|
+
}
|
|
23
26
|
forContext(arg0, attributes) {
|
|
24
27
|
return super.forContext(arg0, attributes);
|
|
25
28
|
}
|
|
26
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Inserts a single document into MongoDB. If documents passed in do not contain the **_id** field,
|
|
31
|
+
* one will be added to each of the documents missing it by the driver, mutating the document. This behavior
|
|
32
|
+
* can be overridden by setting the **forceServerObjectId** flag.
|
|
33
|
+
*
|
|
34
|
+
* @param doc
|
|
35
|
+
* @param options
|
|
36
|
+
* @protected
|
|
37
|
+
*/
|
|
38
|
+
async __insertOne(doc, options) {
|
|
27
39
|
const db = await this.getDatabase();
|
|
28
40
|
const collection = await this.getCollection(db);
|
|
29
41
|
options = {
|
|
@@ -38,7 +50,14 @@ class MongoService extends core_1.ApiService {
|
|
|
38
50
|
throw e;
|
|
39
51
|
}
|
|
40
52
|
}
|
|
41
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Gets the number of documents matching the filter.
|
|
55
|
+
*
|
|
56
|
+
* @param filter
|
|
57
|
+
* @param options
|
|
58
|
+
* @protected
|
|
59
|
+
*/
|
|
60
|
+
async __countDocuments(filter, options) {
|
|
42
61
|
const db = await this.getDatabase();
|
|
43
62
|
const collection = await this.getCollection(db);
|
|
44
63
|
options = {
|
|
@@ -54,7 +73,13 @@ class MongoService extends core_1.ApiService {
|
|
|
54
73
|
throw e;
|
|
55
74
|
}
|
|
56
75
|
}
|
|
57
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Delete a document from a collection
|
|
78
|
+
*
|
|
79
|
+
* @param filter - The filter used to select the document to remove
|
|
80
|
+
* @param options - Optional settings for the command
|
|
81
|
+
*/
|
|
82
|
+
async __deleteOne(filter, options) {
|
|
58
83
|
const db = await this.getDatabase();
|
|
59
84
|
const collection = await this.getCollection(db);
|
|
60
85
|
options = {
|
|
@@ -69,7 +94,14 @@ class MongoService extends core_1.ApiService {
|
|
|
69
94
|
throw e;
|
|
70
95
|
}
|
|
71
96
|
}
|
|
72
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Delete multiple documents from a collection
|
|
99
|
+
*
|
|
100
|
+
* @param filter
|
|
101
|
+
* @param options
|
|
102
|
+
* @protected
|
|
103
|
+
*/
|
|
104
|
+
async __deleteMany(filter, options) {
|
|
73
105
|
const db = await this.getDatabase();
|
|
74
106
|
const collection = await this.getCollection(db);
|
|
75
107
|
options = {
|
|
@@ -84,7 +116,36 @@ class MongoService extends core_1.ApiService {
|
|
|
84
116
|
throw e;
|
|
85
117
|
}
|
|
86
118
|
}
|
|
87
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Create a new Change Stream, watching for new changes (insertions, updates, replacements, deletions, and invalidations) in this collection.
|
|
121
|
+
*
|
|
122
|
+
* @param pipeline
|
|
123
|
+
* @param options
|
|
124
|
+
* @protected
|
|
125
|
+
*/
|
|
126
|
+
async __aggregate(pipeline, options) {
|
|
127
|
+
const db = await this.getDatabase();
|
|
128
|
+
const collection = await this.getCollection(db);
|
|
129
|
+
options = {
|
|
130
|
+
...options,
|
|
131
|
+
session: options?.session || this.session
|
|
132
|
+
};
|
|
133
|
+
try {
|
|
134
|
+
return await collection.aggregate(pipeline, options);
|
|
135
|
+
}
|
|
136
|
+
catch (e) {
|
|
137
|
+
await this._onError(e);
|
|
138
|
+
throw e;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Fetches the first document that matches the filter
|
|
143
|
+
*
|
|
144
|
+
* @param filter
|
|
145
|
+
* @param options
|
|
146
|
+
* @protected
|
|
147
|
+
*/
|
|
148
|
+
async __findOne(filter, options) {
|
|
88
149
|
const db = await this.getDatabase();
|
|
89
150
|
const collection = await this.getCollection(db);
|
|
90
151
|
options = {
|
|
@@ -99,7 +160,14 @@ class MongoService extends core_1.ApiService {
|
|
|
99
160
|
throw e;
|
|
100
161
|
}
|
|
101
162
|
}
|
|
102
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Creates a cursor for a filter that can be used to iterate over results from MongoDB
|
|
165
|
+
*
|
|
166
|
+
* @param filter
|
|
167
|
+
* @param options
|
|
168
|
+
* @protected
|
|
169
|
+
*/
|
|
170
|
+
async __find(filter, options) {
|
|
103
171
|
const db = await this.getDatabase();
|
|
104
172
|
const collection = await this.getCollection(db);
|
|
105
173
|
options = {
|
|
@@ -114,22 +182,63 @@ class MongoService extends core_1.ApiService {
|
|
|
114
182
|
throw e;
|
|
115
183
|
}
|
|
116
184
|
}
|
|
117
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Update a single document in a collection
|
|
187
|
+
*
|
|
188
|
+
* @param filter
|
|
189
|
+
* @param update
|
|
190
|
+
* @param options
|
|
191
|
+
* @protected
|
|
192
|
+
*/
|
|
193
|
+
async __updateOne(filter, update, options) {
|
|
118
194
|
const db = await this.getDatabase();
|
|
119
195
|
const collection = await this.getCollection(db);
|
|
120
196
|
options = {
|
|
197
|
+
session: this.session,
|
|
198
|
+
...options
|
|
199
|
+
};
|
|
200
|
+
try {
|
|
201
|
+
return collection.updateOne(filter, update, options);
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
await this._onError(e);
|
|
205
|
+
throw e;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Find a document and update it in one atomic operation. Requires a write lock for the duration of the operation.
|
|
210
|
+
*
|
|
211
|
+
* @param filter
|
|
212
|
+
* @param doc
|
|
213
|
+
* @param options
|
|
214
|
+
* @protected
|
|
215
|
+
*/
|
|
216
|
+
async __findOneAndUpdate(filter, doc, options) {
|
|
217
|
+
const db = await this.getDatabase();
|
|
218
|
+
const collection = await this.getCollection(db);
|
|
219
|
+
const opts = {
|
|
220
|
+
returnDocument: 'after',
|
|
221
|
+
session: this.session,
|
|
222
|
+
includeResultMetadata: false,
|
|
121
223
|
...options,
|
|
122
|
-
session: options?.session || this.session
|
|
123
224
|
};
|
|
124
225
|
try {
|
|
125
|
-
return await collection.
|
|
226
|
+
return await collection.findOneAndUpdate(filter, doc, opts);
|
|
126
227
|
}
|
|
127
228
|
catch (e) {
|
|
128
229
|
await this._onError(e);
|
|
129
230
|
throw e;
|
|
130
231
|
}
|
|
131
232
|
}
|
|
132
|
-
|
|
233
|
+
/**
|
|
234
|
+
* Update multiple documents in a collection
|
|
235
|
+
*
|
|
236
|
+
* @param filter
|
|
237
|
+
* @param doc
|
|
238
|
+
* @param options
|
|
239
|
+
* @protected
|
|
240
|
+
*/
|
|
241
|
+
async __updateMany(filter, doc, options) {
|
|
133
242
|
const db = await this.getDatabase();
|
|
134
243
|
const collection = await this.getCollection(db);
|
|
135
244
|
options = {
|
|
@@ -156,9 +265,6 @@ class MongoService extends core_1.ApiService {
|
|
|
156
265
|
throw new Error(`Database not set!`);
|
|
157
266
|
return this.db;
|
|
158
267
|
}
|
|
159
|
-
getDataType() {
|
|
160
|
-
return this.context.api.getComplexType(this._dataType);
|
|
161
|
-
}
|
|
162
268
|
async getCollection(db) {
|
|
163
269
|
return db.collection(this.getCollectionName());
|
|
164
270
|
}
|