@restorecommerce/resource-base-interface 0.1.1 → 0.2.3
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/CHANGELOG.md +22 -0
- package/lib/core/GraphResourcesServiceBase.js +121 -101
- package/lib/core/GraphResourcesServiceBase.js.map +1 -1
- package/lib/core/ResourcesAPI.d.ts +3 -2
- package/lib/core/ResourcesAPI.js +279 -228
- package/lib/core/ResourcesAPI.js.map +1 -1
- package/lib/core/ServiceBase.d.ts +2 -0
- package/lib/core/ServiceBase.js +345 -165
- package/lib/core/ServiceBase.js.map +1 -1
- package/lib/core/interfaces.d.ts +66 -1
- package/lib/core/interfaces.js +36 -0
- package/lib/core/interfaces.js.map +1 -1
- package/lib/index.d.ts +9 -2
- package/lib/index.js +187 -64
- package/lib/index.js.map +1 -1
- package/package.json +21 -20
- package/tsconfig.json +12 -4
package/lib/core/ResourcesAPI.js
CHANGED
|
@@ -1,21 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
23
|
};
|
|
11
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
25
|
exports.ResourcesAPIBase = void 0;
|
|
13
|
-
const _ = require("lodash");
|
|
14
|
-
const
|
|
26
|
+
const _ = __importStar(require("lodash"));
|
|
27
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
15
28
|
const chassis_srv_1 = require("@restorecommerce/chassis-srv");
|
|
16
|
-
const uuid = require("uuid");
|
|
17
|
-
const redis = require("redis");
|
|
18
|
-
|
|
29
|
+
const uuid = __importStar(require("uuid"));
|
|
30
|
+
const redis = __importStar(require("redis"));
|
|
31
|
+
bluebird_1.default.promisifyAll(redis.RedisClient.prototype);
|
|
19
32
|
let redisClient;
|
|
20
33
|
const Strategies = {
|
|
21
34
|
INCREMENT: 'increment',
|
|
@@ -29,22 +42,22 @@ const uuidGen = () => {
|
|
|
29
42
|
const isEmptyObject = (obj) => {
|
|
30
43
|
return !Object.keys(obj).length;
|
|
31
44
|
};
|
|
32
|
-
const setDefaults = (obj, collectionName) =>
|
|
45
|
+
const setDefaults = async (obj, collectionName) => {
|
|
33
46
|
const o = obj;
|
|
34
47
|
if (_.isEmpty(o.meta)) {
|
|
35
48
|
throw new chassis_srv_1.errors.InvalidArgument('Object does not contain ownership information');
|
|
36
49
|
}
|
|
37
50
|
const now = Date.now();
|
|
38
51
|
if (redisClient) {
|
|
39
|
-
const values =
|
|
52
|
+
const values = await redisClient.hgetallAsync(collectionName);
|
|
40
53
|
if (values) {
|
|
41
54
|
for (let field in values) {
|
|
42
55
|
const strategy = values[field];
|
|
43
56
|
switch (strategy) {
|
|
44
57
|
case Strategies.INCREMENT:
|
|
45
58
|
const key = collectionName + ':' + field;
|
|
46
|
-
o[field] =
|
|
47
|
-
|
|
59
|
+
o[field] = await redisClient.getAsync(key);
|
|
60
|
+
await redisClient.incrAsync(key);
|
|
48
61
|
break;
|
|
49
62
|
case Strategies.UUID:
|
|
50
63
|
o[field] = uuidGen();
|
|
@@ -53,7 +66,7 @@ const setDefaults = (obj, collectionName) => __awaiter(void 0, void 0, void 0, f
|
|
|
53
66
|
o[field] = uuidGen();
|
|
54
67
|
break;
|
|
55
68
|
case Strategies.TIMESTAMP:
|
|
56
|
-
o[field] =
|
|
69
|
+
o[field] = await redisClient.timeAsync()[0];
|
|
57
70
|
break;
|
|
58
71
|
}
|
|
59
72
|
}
|
|
@@ -67,7 +80,7 @@ const setDefaults = (obj, collectionName) => __awaiter(void 0, void 0, void 0, f
|
|
|
67
80
|
o.id = uuidGen();
|
|
68
81
|
}
|
|
69
82
|
return o;
|
|
70
|
-
}
|
|
83
|
+
};
|
|
71
84
|
const updateMetadata = (docMeta, newDoc) => {
|
|
72
85
|
if (_.isEmpty(newDoc.meta)) {
|
|
73
86
|
// docMeta.owner = newDoc.owner;
|
|
@@ -113,7 +126,7 @@ class ResourcesAPIBase {
|
|
|
113
126
|
* @param {string} collectionName Name of database collection.
|
|
114
127
|
* @param {any} fieldHandlerConf The collection's field generators configuration.
|
|
115
128
|
*/
|
|
116
|
-
constructor(db, collectionName, fieldHandlerConf, edgeCfg, graphName) {
|
|
129
|
+
constructor(db, collectionName, fieldHandlerConf, edgeCfg, graphName, logger) {
|
|
117
130
|
this.db = db;
|
|
118
131
|
this.collectionName = collectionName;
|
|
119
132
|
this.edgeCfg = edgeCfg;
|
|
@@ -188,56 +201,57 @@ class ResourcesAPIBase {
|
|
|
188
201
|
* @param {object} field key value, key=field value: 0=exclude, 1=include
|
|
189
202
|
* @returns {an Object that contains an items field}
|
|
190
203
|
*/
|
|
191
|
-
read(filter = {}, limit = 1000, offset = 0, sort = {}, field = {}, customQueries = [], customArgs = {}) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return entities;
|
|
212
|
-
});
|
|
204
|
+
async read(filter = {}, limit = 1000, offset = 0, sort = {}, field = {}, customQueries = [], customArgs = {}) {
|
|
205
|
+
const options = {
|
|
206
|
+
limit: Math.min(limit, 1000),
|
|
207
|
+
offset,
|
|
208
|
+
sort,
|
|
209
|
+
fields: field,
|
|
210
|
+
customQueries,
|
|
211
|
+
customArguments: customArgs.value ? JSON.parse(customArgs.value.toString()) : {}
|
|
212
|
+
};
|
|
213
|
+
const entities = await this.db.find(this.collectionName, filter, options);
|
|
214
|
+
if (this.bufferField) {
|
|
215
|
+
// encode the msg obj back to buffer obj and send it back
|
|
216
|
+
entities.forEach(element => {
|
|
217
|
+
if (element[this.bufferField]) {
|
|
218
|
+
element = encodeMsgObj(element, this.bufferField);
|
|
219
|
+
return element;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return entities;
|
|
213
224
|
}
|
|
214
225
|
/**
|
|
215
226
|
* Inserts documents to the database.
|
|
216
227
|
*
|
|
217
228
|
* @param {array.object} documents
|
|
218
229
|
*/
|
|
219
|
-
create(documents) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
230
|
+
async create(documents) {
|
|
231
|
+
const collection = this.collectionName;
|
|
232
|
+
const toInsert = [];
|
|
233
|
+
let result = [];
|
|
234
|
+
try {
|
|
235
|
+
let result = [];
|
|
236
|
+
// check if all the required fields are present
|
|
237
|
+
if (this.requiredFields && this.requiredFields[this.resourceName]) {
|
|
238
|
+
const requiredFieldsResult = this.checkRequiredFields(this.requiredFields[this.resourceName], documents, result);
|
|
239
|
+
documents = requiredFieldsResult.documents;
|
|
240
|
+
result = requiredFieldsResult.result;
|
|
241
|
+
}
|
|
242
|
+
for (let i = 0; i < documents.length; i += 1) {
|
|
243
|
+
documents[i] = await setDefaults(documents[i], collection);
|
|
244
|
+
// decode the buffer and store it to DB
|
|
245
|
+
if (this.bufferField) {
|
|
246
|
+
toInsert.push(decodeBufferObj(_.cloneDeep(documents[i]), this.bufferField));
|
|
234
247
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
248
|
+
}
|
|
249
|
+
if (this.isGraphDB(this.db)) {
|
|
250
|
+
await this.db.createGraphDB(this.graphName);
|
|
251
|
+
await this.db.addVertexCollection(collection);
|
|
252
|
+
let createVertexResp = await this.db.createVertex(collection, this.bufferField ? toInsert : documents);
|
|
253
|
+
for (let document of documents) {
|
|
254
|
+
if (this.edgeCfg && _.isArray(this.edgeCfg) && this.edgeCfg.length > 0) {
|
|
241
255
|
for (let eachEdgeCfg of this.edgeCfg) {
|
|
242
256
|
const fromIDkey = eachEdgeCfg.from;
|
|
243
257
|
const from_id = document[fromIDkey];
|
|
@@ -251,35 +265,52 @@ class ResourcesAPIBase {
|
|
|
251
265
|
fromVerticeName = eachEdgeCfg.fromVerticeName;
|
|
252
266
|
toVerticeName = collection;
|
|
253
267
|
}
|
|
254
|
-
if (fromVerticeName && toVerticeName) {
|
|
255
|
-
yield this.db.addEdgeDefinition(eachEdgeCfg.edgeName, [fromVerticeName], [toVerticeName]);
|
|
256
|
-
}
|
|
257
268
|
if (from_id && to_id) {
|
|
258
269
|
if (_.isArray(to_id)) {
|
|
259
270
|
for (let toID of to_id) {
|
|
260
|
-
|
|
271
|
+
await this.db.createEdge(eachEdgeCfg.edgeName, null, `${fromVerticeName}/${from_id}`, `${toVerticeName}/${toID}`);
|
|
261
272
|
}
|
|
262
|
-
continue;
|
|
263
273
|
}
|
|
264
|
-
|
|
274
|
+
else {
|
|
275
|
+
await this.db.createEdge(eachEdgeCfg.edgeName, null, `${fromVerticeName}/${from_id}`, `${toVerticeName}/${to_id}`);
|
|
276
|
+
}
|
|
265
277
|
}
|
|
266
278
|
}
|
|
267
279
|
}
|
|
268
|
-
|
|
269
|
-
|
|
280
|
+
}
|
|
281
|
+
if (_.isArray(createVertexResp)) {
|
|
282
|
+
for (let eachVertexResp of createVertexResp) {
|
|
283
|
+
result.push(eachVertexResp);
|
|
284
|
+
}
|
|
270
285
|
}
|
|
271
286
|
else {
|
|
272
|
-
|
|
287
|
+
result.push(createVertexResp);
|
|
273
288
|
}
|
|
289
|
+
return result;
|
|
274
290
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
291
|
+
else {
|
|
292
|
+
let checkReqFieldResult = [];
|
|
293
|
+
if (!_.isEmpty(result)) {
|
|
294
|
+
checkReqFieldResult = result;
|
|
279
295
|
}
|
|
280
|
-
|
|
296
|
+
result = await this.db.insert(collection, this.bufferField ? toInsert : documents);
|
|
297
|
+
if (!_.isEmpty(checkReqFieldResult)) {
|
|
298
|
+
for (let reqFieldResult of checkReqFieldResult) {
|
|
299
|
+
result.push(reqFieldResult);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return result;
|
|
281
303
|
}
|
|
282
|
-
}
|
|
304
|
+
}
|
|
305
|
+
catch (e) {
|
|
306
|
+
this.logger.error('Error creating documents', { error: e.message });
|
|
307
|
+
result.push({
|
|
308
|
+
error: true,
|
|
309
|
+
errorNum: e.code,
|
|
310
|
+
errorMessage: e.details ? e.details : e.message
|
|
311
|
+
});
|
|
312
|
+
return result;
|
|
313
|
+
}
|
|
283
314
|
}
|
|
284
315
|
isGraphDB(db) {
|
|
285
316
|
return !!this.edgeCfg;
|
|
@@ -289,123 +320,137 @@ class ResourcesAPIBase {
|
|
|
289
320
|
* @param requiredFields
|
|
290
321
|
* @param documents
|
|
291
322
|
*/
|
|
292
|
-
checkRequiredFields(requiredFields, documents) {
|
|
323
|
+
checkRequiredFields(requiredFields, documents, result) {
|
|
293
324
|
for (let document of documents) {
|
|
294
325
|
for (let eachField of requiredFields) {
|
|
295
326
|
const isArray = _.isArray(eachField);
|
|
296
327
|
if (!document[eachField]) {
|
|
297
|
-
|
|
298
|
-
|
|
328
|
+
result.push({
|
|
329
|
+
error: true,
|
|
330
|
+
errorNum: 400,
|
|
331
|
+
errorMessage: `Field ${eachField} is necessary for ${this.resourceName} for documentID ${document.id}`
|
|
332
|
+
});
|
|
333
|
+
documents = documents.filter(doc => doc.id != document.id);
|
|
299
334
|
}
|
|
300
335
|
if ((isArray && document[eachField].length == 0)) {
|
|
301
|
-
|
|
302
|
-
|
|
336
|
+
result.push({
|
|
337
|
+
error: true,
|
|
338
|
+
errorNum: 400,
|
|
339
|
+
errorMessage: `Field ${eachField} is necessary for ${this.resourceName} for documentID ${document.id}`
|
|
340
|
+
});
|
|
341
|
+
documents = documents.filter(doc => doc.id != document.id);
|
|
303
342
|
}
|
|
304
343
|
}
|
|
305
344
|
}
|
|
345
|
+
return { documents, result };
|
|
306
346
|
}
|
|
307
347
|
/**
|
|
308
348
|
* Removes documents found by id.
|
|
309
349
|
*
|
|
310
350
|
* @param [array.string] ids List of document IDs.
|
|
311
351
|
*/
|
|
312
|
-
delete(ids) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
318
|
-
};
|
|
319
|
-
try {
|
|
320
|
-
if (this.isGraphDB(this.db)) {
|
|
321
|
-
// Modify the Ids to include documentHandle
|
|
322
|
-
if (ids.length > 0) {
|
|
323
|
-
ids = _.map(ids, (id) => {
|
|
324
|
-
return `${this.collectionName}/${id}`;
|
|
325
|
-
});
|
|
326
|
-
return yield this.db.removeVertex(this.collectionName, ids);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
yield this.db.delete(this.collectionName, filter);
|
|
352
|
+
async delete(ids) {
|
|
353
|
+
let deleteResponse = [];
|
|
354
|
+
try {
|
|
355
|
+
if (!_.isArray(ids)) {
|
|
356
|
+
ids = [ids];
|
|
330
357
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
358
|
+
if (this.isGraphDB(this.db)) {
|
|
359
|
+
// Modify the Ids to include documentHandle
|
|
360
|
+
if (ids.length > 0) {
|
|
361
|
+
ids = _.map(ids, (id) => {
|
|
362
|
+
return `${this.collectionName}/${id}`;
|
|
363
|
+
});
|
|
364
|
+
deleteResponse = await this.db.removeVertex(this.collectionName, ids);
|
|
365
|
+
return deleteResponse;
|
|
335
366
|
}
|
|
336
367
|
}
|
|
337
|
-
|
|
368
|
+
deleteResponse = await this.db.delete(this.collectionName, ids);
|
|
369
|
+
return deleteResponse;
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
this.logger.error('Error deleting documents', { error: err.message });
|
|
373
|
+
deleteResponse.push({
|
|
374
|
+
error: true,
|
|
375
|
+
errorNum: err.code,
|
|
376
|
+
errorMessage: err.details ? err.details : err.message
|
|
377
|
+
});
|
|
378
|
+
return deleteResponse;
|
|
379
|
+
}
|
|
338
380
|
}
|
|
339
381
|
/**
|
|
340
382
|
* Delete all documents in the collection.
|
|
341
383
|
*/
|
|
342
|
-
deleteCollection() {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
});
|
|
384
|
+
async deleteCollection() {
|
|
385
|
+
if (this.isGraphDB(this.db)) {
|
|
386
|
+
// graph edges are only deleted automatically when a specific vertex is deleted
|
|
387
|
+
// (`truncate` does not work in this case)
|
|
388
|
+
const ids = await this.db.find(this.collectionName, {}, {
|
|
389
|
+
fields: {
|
|
390
|
+
id: 1
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
await this.delete(_.map(ids, (doc) => {
|
|
394
|
+
return doc.id;
|
|
395
|
+
}));
|
|
396
|
+
return ids;
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
const entities = await this.db.find(this.collectionName, {}, { fields: { id: 1 } });
|
|
400
|
+
await this.db.truncate(this.collectionName);
|
|
401
|
+
return entities;
|
|
402
|
+
}
|
|
363
403
|
}
|
|
364
404
|
/**
|
|
365
405
|
* Upserts documents.
|
|
366
406
|
*
|
|
367
407
|
* @param [array.object] documents
|
|
368
408
|
*/
|
|
369
|
-
upsert(documents, events, resourceName) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
409
|
+
async upsert(documents, events, resourceName) {
|
|
410
|
+
let result = [];
|
|
411
|
+
try {
|
|
412
|
+
const dispatch = []; // CRUD events to be dispatched
|
|
413
|
+
for (let i = 0; i < documents.length; i += 1) {
|
|
414
|
+
let doc = documents[i];
|
|
415
|
+
decodeBufferObj(doc, this.bufferField);
|
|
416
|
+
let foundDocs;
|
|
417
|
+
if (doc && doc.id) {
|
|
418
|
+
foundDocs = await this.db.find(this.collectionName, { id: doc.id }, {
|
|
377
419
|
fields: {
|
|
378
420
|
meta: 1
|
|
379
421
|
}
|
|
380
422
|
});
|
|
381
|
-
let eventName;
|
|
382
|
-
if (_.isEmpty(foundDocs)) {
|
|
383
|
-
// insert
|
|
384
|
-
setDefaults(doc, this.collectionName);
|
|
385
|
-
eventName = 'Created';
|
|
386
|
-
}
|
|
387
|
-
else {
|
|
388
|
-
// update
|
|
389
|
-
const dbDoc = foundDocs[0];
|
|
390
|
-
updateMetadata(dbDoc.meta, doc);
|
|
391
|
-
eventName = 'Modified';
|
|
392
|
-
}
|
|
393
|
-
dispatch.push(events.emit(`${resourceName}${eventName}`, doc));
|
|
394
423
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
424
|
+
let eventName;
|
|
425
|
+
if (_.isEmpty(foundDocs)) {
|
|
426
|
+
// insert
|
|
427
|
+
setDefaults(doc, this.collectionName);
|
|
428
|
+
eventName = 'Created';
|
|
399
429
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
430
|
+
else {
|
|
431
|
+
// update
|
|
432
|
+
const dbDoc = foundDocs[0];
|
|
433
|
+
updateMetadata(dbDoc.meta, doc);
|
|
434
|
+
eventName = 'Modified';
|
|
405
435
|
}
|
|
406
|
-
|
|
436
|
+
dispatch.push(events.emit(`${resourceName}${eventName}`, doc));
|
|
407
437
|
}
|
|
408
|
-
|
|
438
|
+
result = await this.db.upsert(this.collectionName, documents);
|
|
439
|
+
await dispatch;
|
|
440
|
+
if (this.bufferField) {
|
|
441
|
+
return _.map(result, doc => encodeMsgObj(doc, this.bufferField));
|
|
442
|
+
}
|
|
443
|
+
return result;
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
this.logger.error('Error upserting documents', { error: error.message });
|
|
447
|
+
result.push({
|
|
448
|
+
error: true,
|
|
449
|
+
errorNum: error.code,
|
|
450
|
+
errorMessage: error.details ? error.details : error.message
|
|
451
|
+
});
|
|
452
|
+
return result;
|
|
453
|
+
}
|
|
409
454
|
}
|
|
410
455
|
/**
|
|
411
456
|
* Finds documents by id and updates them.
|
|
@@ -413,87 +458,93 @@ class ResourcesAPIBase {
|
|
|
413
458
|
* @param [array.object] documents
|
|
414
459
|
* A list of documents or partial documents. Each document must contain an id field.
|
|
415
460
|
*/
|
|
416
|
-
update(documents) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
431
|
-
if (_.isEmpty(foundDocs)) {
|
|
432
|
-
throw { code: 404 };
|
|
433
|
-
}
|
|
434
|
-
const dbDoc = foundDocs[0];
|
|
461
|
+
async update(documents) {
|
|
462
|
+
let updateResponse = [];
|
|
463
|
+
try {
|
|
464
|
+
const collectionName = this.collectionName;
|
|
465
|
+
let docsWithUpMetadata = [];
|
|
466
|
+
for (let i = 0; i < documents.length; i += 1) {
|
|
467
|
+
let doc = documents[i];
|
|
468
|
+
if (this.bufferField) {
|
|
469
|
+
doc = decodeBufferObj(_.cloneDeep(documents[i]), this.bufferField);
|
|
470
|
+
}
|
|
471
|
+
const foundDocs = await this.db.find(collectionName, { id: doc.id });
|
|
472
|
+
let dbDoc;
|
|
473
|
+
if (foundDocs && foundDocs.length === 1) {
|
|
474
|
+
dbDoc = foundDocs[0];
|
|
435
475
|
doc = updateMetadata(dbDoc.meta, doc);
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
dbDoc = doc; // doc not existing assigning to generate error message in response
|
|
479
|
+
}
|
|
480
|
+
if (this.isGraphDB(this.db)) {
|
|
481
|
+
const db = this.db;
|
|
482
|
+
for (let eachEdgeCfg of this.edgeCfg) {
|
|
483
|
+
const toIDkey = eachEdgeCfg.to;
|
|
484
|
+
let modified_to_idValues = doc[toIDkey];
|
|
485
|
+
let db_to_idValues = dbDoc[toIDkey];
|
|
486
|
+
if (_.isArray(modified_to_idValues)) {
|
|
487
|
+
modified_to_idValues = _.sortBy(modified_to_idValues);
|
|
488
|
+
}
|
|
489
|
+
if (_.isArray(db_to_idValues)) {
|
|
490
|
+
db_to_idValues = _.sortBy(db_to_idValues);
|
|
491
|
+
}
|
|
492
|
+
// delete and recreate only if there is a difference in references
|
|
493
|
+
if (!_.isEqual(modified_to_idValues, db_to_idValues)) {
|
|
494
|
+
// TODO delete and recreate the edge (since there is no way to update the edge as we dont add id to the edge as for doc)
|
|
495
|
+
const fromIDkey = eachEdgeCfg.from;
|
|
496
|
+
const from_id = doc[fromIDkey];
|
|
497
|
+
let fromVerticeName = collectionName;
|
|
498
|
+
let toVerticeName = eachEdgeCfg.toVerticeName;
|
|
499
|
+
const direction = eachEdgeCfg.direction;
|
|
500
|
+
if (direction === 'inbound') {
|
|
501
|
+
fromVerticeName = eachEdgeCfg.fromVerticeName;
|
|
502
|
+
toVerticeName = collectionName;
|
|
447
503
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
let fromVerticeName = collectionName;
|
|
454
|
-
let toVerticeName = eachEdgeCfg.toVerticeName;
|
|
455
|
-
const direction = eachEdgeCfg.direction;
|
|
456
|
-
if (direction === 'inbound') {
|
|
457
|
-
fromVerticeName = eachEdgeCfg.fromVerticeName;
|
|
458
|
-
toVerticeName = collectionName;
|
|
459
|
-
}
|
|
460
|
-
const edgeCollectionName = eachEdgeCfg.edgeName;
|
|
461
|
-
let outgoingEdges = yield db.getOutEdges(edgeCollectionName, `${collectionName}/${dbDoc.id}`);
|
|
462
|
-
for (let outgoingEdge of outgoingEdges) {
|
|
463
|
-
yield db.removeEdge(edgeCollectionName, outgoingEdge._id);
|
|
504
|
+
const edgeCollectionName = eachEdgeCfg.edgeName;
|
|
505
|
+
let outgoingEdges = await db.getOutEdges(edgeCollectionName, `${collectionName}/${dbDoc.id}`);
|
|
506
|
+
if (_.isArray(outgoingEdges.edges)) {
|
|
507
|
+
for (let outgoingEdge of outgoingEdges.edges) {
|
|
508
|
+
await db.removeEdge(edgeCollectionName, outgoingEdge._id);
|
|
464
509
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
510
|
+
}
|
|
511
|
+
let incomingEdges = await db.getInEdges(edgeCollectionName, `${collectionName}/${dbDoc.id}`);
|
|
512
|
+
if (_.isArray(incomingEdges.edges)) {
|
|
513
|
+
for (let incomingEdge of incomingEdges.edges) {
|
|
514
|
+
await db.removeEdge(edgeCollectionName, incomingEdge._id);
|
|
468
515
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
continue;
|
|
516
|
+
}
|
|
517
|
+
// Create new edges
|
|
518
|
+
if (from_id && modified_to_idValues) {
|
|
519
|
+
if (_.isArray(modified_to_idValues)) {
|
|
520
|
+
for (let toID of modified_to_idValues) {
|
|
521
|
+
await db.createEdge(eachEdgeCfg.edgeName, null, `${fromVerticeName}/${from_id}`, `${toVerticeName}/${toID}`);
|
|
476
522
|
}
|
|
477
|
-
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
await db.createEdge(edgeCollectionName, null, `${fromVerticeName}/${from_id}`, `${toVerticeName}/${modified_to_idValues}`);
|
|
478
526
|
}
|
|
479
527
|
}
|
|
480
528
|
}
|
|
481
529
|
}
|
|
482
|
-
patches.push(yield this.db.update(collectionName, { id: doc.id }, _.omitBy(doc, _.isNil)));
|
|
483
|
-
}
|
|
484
|
-
patches = _.flatten(patches);
|
|
485
|
-
if (this.bufferField) {
|
|
486
|
-
patches = _.map(patches, patch => encodeMsgObj(patch, this.bufferField));
|
|
487
530
|
}
|
|
488
|
-
|
|
531
|
+
docsWithUpMetadata.push(doc);
|
|
489
532
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
}
|
|
494
|
-
throw { code: e.code, message: e.message, details: e.details };
|
|
533
|
+
updateResponse = await this.db.update(collectionName, docsWithUpMetadata);
|
|
534
|
+
if (this.bufferField) {
|
|
535
|
+
updateResponse = _.map(updateResponse, patch => encodeMsgObj(patch, this.bufferField));
|
|
495
536
|
}
|
|
496
|
-
|
|
537
|
+
return updateResponse;
|
|
538
|
+
}
|
|
539
|
+
catch (e) {
|
|
540
|
+
this.logger.error('Error updating documents', { error: e.message });
|
|
541
|
+
updateResponse.push({
|
|
542
|
+
error: true,
|
|
543
|
+
errorNum: e.code,
|
|
544
|
+
errorMessage: e.message
|
|
545
|
+
});
|
|
546
|
+
return updateResponse;
|
|
547
|
+
}
|
|
497
548
|
}
|
|
498
549
|
}
|
|
499
550
|
exports.ResourcesAPIBase = ResourcesAPIBase;
|