@cocreate/mongodb 1.2.5 → 1.3.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +1 -1
  3. package/src/index.js +719 -708
package/src/index.js CHANGED
@@ -4,789 +4,800 @@ const clients = new Map()
4
4
 
5
5
 
6
6
  async function dbClient(data) {
7
- if (data.dbUrl) {
8
- let client = clients.get(data.dbUrl)
9
- if (!client) {
10
- try {
11
- client = MongoClient.connect(data.dbUrl, { useNewUrlParser: true, useUnifiedTopology: true });
12
- clients.set(data.dbUrl, client)
13
- } catch (error) {
14
- console.error(error)
15
- return { status: false }
16
- }
17
- }
18
- return client
19
- }
20
- return
7
+ if (data.dbUrl) {
8
+ let client = clients.get(data.dbUrl)
9
+ if (!client) {
10
+ try {
11
+ client = MongoClient.connect(data.dbUrl, { useNewUrlParser: true, useUnifiedTopology: true });
12
+ clients.set(data.dbUrl, client)
13
+ } catch (error) {
14
+ console.error(error)
15
+ return { status: false }
16
+ }
17
+ }
18
+ return client
19
+ }
20
+ return
21
21
  }
22
22
 
23
23
  async function databaseStats(data) {
24
- const client = await dbClient(data)
25
- if (!client) return
26
- let db = client.db(data.organization_id)
27
- let stats = db.stats()
28
- return stats
24
+ const client = await dbClient(data)
25
+ if (!client) return
26
+ let db = client.db(data.organization_id)
27
+ let stats = db.stats()
28
+ return stats
29
29
  }
30
30
 
31
31
  function createDatabase(data) {
32
- return database('createDatabase', data)
32
+ return database('createDatabase', data)
33
33
  }
34
34
 
35
35
  function readDatabase(data) {
36
- return database('readDatabase', data)
36
+ return database('readDatabase', data)
37
37
  }
38
38
 
39
39
  function updateDatabase(data) {
40
- return database('updateDatabase', data)
40
+ return database('updateDatabase', data)
41
41
  }
42
42
 
43
43
  function deleteDatabase(data) {
44
- return database('deleteDatabase', data)
44
+ return database('deleteDatabase', data)
45
45
  }
46
46
 
47
47
  function database(action, data) {
48
- return new Promise(async (resolve, reject) => {
49
- let type = 'database'
50
- let databaseArray = []
51
-
52
- try {
53
- const client = await dbClient(data)
54
- if (!client) return
55
- if (action == 'readDatabase') {
56
- const db = client.db().admin();
57
-
58
- // List all the available databases
59
- db.listDatabases(function (err, dbs) {
60
-
61
- for (let database of dbs.databases) {
62
- if (data.filter && data.filter.query) {
63
- let isFilter = queryData(database, data.filter.query)
64
- if (isFilter)
65
- databaseArray.push({ database, db: 'mongodb' })
66
- } else
67
- databaseArray.push({ database, db: 'mongodb' })
68
- }
69
-
70
- resolve(createData(data, databaseArray, type))
71
- })
72
- }
73
- if (action == 'deleteDatabase') {
74
- const db = client.db(data.database);
75
- db.dropDatabase().then(response => {
76
- resolve(response)
77
- })
78
- }
79
- } catch (error) {
80
- errorHandler(data, error)
81
- console.log(action, 'error', error);
82
- resolve(data);
83
- }
84
-
85
- }, (error) => {
86
- errorHandler(data, error)
87
- });
48
+ return new Promise(async (resolve, reject) => {
49
+ let type = 'database'
50
+ let databaseArray = []
51
+
52
+ try {
53
+ const client = await dbClient(data)
54
+ if (!client) return
55
+ if (action == 'readDatabase') {
56
+ const db = client.db().admin();
57
+
58
+ // List all the available databases
59
+ db.listDatabases(function (err, dbs) {
60
+
61
+ for (let database of dbs.databases) {
62
+ if (data.filter && data.filter.query) {
63
+ let isFilter = queryData(database, data.filter.query)
64
+ if (isFilter)
65
+ databaseArray.push({ database, db: 'mongodb' })
66
+ } else
67
+ databaseArray.push({ database, db: 'mongodb' })
68
+ }
69
+
70
+ resolve(createData(data, databaseArray, type))
71
+ })
72
+ }
73
+ if (action == 'deleteDatabase') {
74
+ const db = client.db(data.database);
75
+ db.dropDatabase().then(response => {
76
+ resolve(response)
77
+ })
78
+ }
79
+ } catch (error) {
80
+ errorHandler(data, error)
81
+ console.log(action, 'error', error);
82
+ resolve(data);
83
+ }
84
+
85
+ }, (error) => {
86
+ errorHandler(data, error)
87
+ });
88
88
  }
89
89
 
90
90
 
91
91
  function createCollection(data) {
92
- return collection('createCollection', data)
92
+ return collection('createCollection', data)
93
93
  }
94
94
 
95
95
  function readCollection(data) {
96
- return collection('readCollection', data)
96
+ return collection('readCollection', data)
97
97
  }
98
98
 
99
99
  function updateCollection(data) {
100
- return collection('updateCollection', data)
100
+ return collection('updateCollection', data)
101
101
  }
102
102
 
103
103
  function deleteCollection(data) {
104
- return collection('deleteCollection', data)
104
+ return collection('deleteCollection', data)
105
105
  }
106
106
 
107
107
  function collection(action, data) {
108
- return new Promise(async (resolve, reject) => {
109
- let type = 'collection'
110
- let collectionArray = [];
111
-
112
- try {
113
- const client = await dbClient(data)
114
- if (!client) return
115
-
116
- if (data.request)
117
- data.collection = data.request
118
-
119
- let databases = data.database;
120
- if (!Array.isArray(databases))
121
- databases = [databases]
122
-
123
- let databasesLength = databases.length
124
- for (let database of databases) {
125
- const db = client.db(database);
126
-
127
- if (action == 'readCollection') {
128
-
129
- let { query, sort } = getFilters(data);
130
-
131
- db.listCollections().toArray(function (error, result) {
132
- if (error)
133
- errorHandler(data, error, database)
134
-
135
- if (result) {
136
- for (let res of result) {
137
- if (data.filter && data.filter.query) {
138
- let isFilter = queryData(res, data.filter.query)
139
- if (isFilter)
140
- collectionArray.push({ name: res.name, database, db: 'mongodb' })
141
- } else
142
- collectionArray.push({ name: res.name, database, db: 'mongodb' })
143
- }
144
- }
145
-
146
- databasesLength -= 1
147
- if (!databasesLength) {
148
- data = createData(data, collectionArray, type)
149
- resolve(data)
150
- }
151
- })
152
- } else {
153
- let collections
154
- let value
155
- if (action == 'updateCollection')
156
- collections = Object.entries(data.collection)
157
- else
158
- collections = data.collection;
159
-
160
- if (!Array.isArray(collections))
161
- collections = [collections]
162
-
163
- let collectionsLength = collections.length
164
- for (let collection of collections) {
165
-
166
- if (action == 'createCollection') {
167
- db.createCollection(collection, function (error, result) {
168
- if (error)
169
- errorHandler(data, error, database, collection)
170
-
171
- if (result)
172
- collectionArray.push({ name: collection, database, db: 'mongodb' })
173
-
174
- collectionsLength -= 1
175
- if (!collectionsLength)
176
- databasesLength -= 1
177
-
178
- if (!databasesLength && !collectionsLength) {
179
- data = createData(data, collectionArray, type)
180
- resolve(data)
181
- }
182
- })
183
- } else {
184
- if (action == 'updateCollection') {
185
- [collection, value] = collection
186
- }
187
-
188
- const collectionObj = db.collection(collection);
189
-
190
- if (action == 'updateCollection') {
191
- collectionObj.rename(value, function (error, result) {
192
- if (error)
193
- errorHandler(data, error, database, collection)
194
-
195
- if (result)
196
- collectionArray.push({ name: value, oldName: collection, database, db: 'mongodb' })
197
-
198
- collectionsLength -= 1
199
- if (!collectionsLength)
200
- databasesLength -= 1
201
-
202
- if (!databasesLength && !collectionsLength) {
203
- data = createData(data, collectionArray, type)
204
- resolve(data)
205
- }
206
-
207
- })
208
- }
209
-
210
- if (action == 'deleteCollection') {
211
- collectionObj.drop(function (error, result) {
212
- if (error)
213
- errorHandler(data, error, database, collection)
214
-
215
- if (result)
216
- collectionArray.push({ name: collection, database, db: 'mongodb' })
217
-
218
- collectionsLength -= 1
219
- if (!collectionsLength)
220
- databasesLength -= 1
221
-
222
- if (!databasesLength && !collectionsLength) {
223
- data = createData(data, collectionArray, type)
224
- resolve(data)
225
- }
226
-
227
- })
228
-
229
- }
230
- }
231
-
232
- }
233
- }
234
- }
235
-
236
- } catch (error) {
237
- errorHandler(data, error)
238
- console.log(action, 'error', error);
239
- resolve(data);
240
- }
241
- }, (error) => {
242
- errorHandler(data, error)
243
- });
108
+ return new Promise(async (resolve, reject) => {
109
+ let type = 'collection'
110
+ let collectionArray = [];
111
+
112
+ try {
113
+ const client = await dbClient(data)
114
+ if (!client) return
115
+
116
+ if (data.request)
117
+ data.collection = data.request
118
+
119
+ let databases = data.database;
120
+ if (!Array.isArray(databases))
121
+ databases = [databases]
122
+
123
+ let databasesLength = databases.length
124
+ for (let database of databases) {
125
+ const db = client.db(database);
126
+
127
+ if (action == 'readCollection') {
128
+
129
+ let { query, sort } = getFilters(data);
130
+
131
+ db.listCollections().toArray(function (error, result) {
132
+ if (error)
133
+ errorHandler(data, error, database)
134
+
135
+ if (result) {
136
+ for (let res of result) {
137
+ if (data.filter && data.filter.query) {
138
+ let isFilter = queryData(res, data.filter.query)
139
+ if (isFilter)
140
+ collectionArray.push({ name: res.name, database, db: 'mongodb' })
141
+ } else
142
+ collectionArray.push({ name: res.name, database, db: 'mongodb' })
143
+ }
144
+ }
145
+
146
+ databasesLength -= 1
147
+ if (!databasesLength) {
148
+ data = createData(data, collectionArray, type)
149
+ resolve(data)
150
+ }
151
+ })
152
+ } else {
153
+ let collections
154
+ let value
155
+ if (action == 'updateCollection')
156
+ collections = Object.entries(data.collection)
157
+ else
158
+ collections = data.collection;
159
+
160
+ if (!Array.isArray(collections))
161
+ collections = [collections]
162
+
163
+ let collectionsLength = collections.length
164
+ for (let collection of collections) {
165
+
166
+ if (action == 'createCollection') {
167
+ db.createCollection(collection, function (error, result) {
168
+ if (error)
169
+ errorHandler(data, error, database, collection)
170
+
171
+ if (result)
172
+ collectionArray.push({ name: collection, database, db: 'mongodb' })
173
+
174
+ collectionsLength -= 1
175
+ if (!collectionsLength)
176
+ databasesLength -= 1
177
+
178
+ if (!databasesLength && !collectionsLength) {
179
+ data = createData(data, collectionArray, type)
180
+ resolve(data)
181
+ }
182
+ })
183
+ } else {
184
+ if (action == 'updateCollection') {
185
+ [collection, value] = collection
186
+ }
187
+
188
+ const collectionObj = db.collection(collection);
189
+
190
+ if (action == 'updateCollection') {
191
+ collectionObj.rename(value, function (error, result) {
192
+ if (error)
193
+ errorHandler(data, error, database, collection)
194
+
195
+ if (result)
196
+ collectionArray.push({ name: value, oldName: collection, database, db: 'mongodb' })
197
+
198
+ collectionsLength -= 1
199
+ if (!collectionsLength)
200
+ databasesLength -= 1
201
+
202
+ if (!databasesLength && !collectionsLength) {
203
+ data = createData(data, collectionArray, type)
204
+ resolve(data)
205
+ }
206
+
207
+ })
208
+ }
209
+
210
+ if (action == 'deleteCollection') {
211
+ collectionObj.drop(function (error, result) {
212
+ if (error)
213
+ errorHandler(data, error, database, collection)
214
+
215
+ if (result)
216
+ collectionArray.push({ name: collection, database, db: 'mongodb' })
217
+
218
+ collectionsLength -= 1
219
+ if (!collectionsLength)
220
+ databasesLength -= 1
221
+
222
+ if (!databasesLength && !collectionsLength) {
223
+ data = createData(data, collectionArray, type)
224
+ resolve(data)
225
+ }
226
+
227
+ })
228
+
229
+ }
230
+ }
231
+
232
+ }
233
+ }
234
+ }
235
+
236
+ } catch (error) {
237
+ errorHandler(data, error)
238
+ console.log(action, 'error', error);
239
+ resolve(data);
240
+ }
241
+ }, (error) => {
242
+ errorHandler(data, error)
243
+ });
244
244
  }
245
245
 
246
246
 
247
247
  function createDocument(data) {
248
- return document('createDocument', data)
248
+ return document('createDocument', data)
249
249
  }
250
250
 
251
251
  function readDocument(data) {
252
- return document('readDocument', data)
252
+ return document('readDocument', data)
253
253
  }
254
254
 
255
255
  function updateDocument(data) {
256
- return document('updateDocument', data)
256
+ return document('updateDocument', data)
257
257
  }
258
258
 
259
259
  function deleteDocument(data) {
260
- return document('deleteDocument', data)
260
+ return document('deleteDocument', data)
261
261
  }
262
262
 
263
263
  function document(action, data) {
264
- return new Promise(async (resolve, reject) => {
265
- try {
266
- const client = await dbClient(data)
267
- if (!client) return
268
-
269
- let type = 'document'
270
- let documents = [];
271
-
272
- if (data.request)
273
- data[type] = data.request
274
-
275
-
276
- if (!data['timeStamp'])
277
- data['timeStamp'] = new Date().toISOString()
278
-
279
-
280
- let isFilter
281
- if (data.filter && data.filter.query)
282
- isFilter = true
283
-
284
- let databases = data.database;
285
- if (!Array.isArray(databases))
286
- databases = [databases]
287
-
288
- let databasesLength = databases.length
289
- for (let database of databases) {
290
- let collections = data.collection;
291
- if (!Array.isArray(collections))
292
- collections = [collections]
293
-
294
- let collectionsLength = collections.length
295
- for (let collection of collections) {
296
- const db = client.db(database);
297
- const collectionObj = db.collection(collection);
298
-
299
- let { query, sort } = getFilters(data);
300
- if (data['organization_id']) {
301
- query['organization_id'] = { $eq: data['organization_id'] }
302
- }
303
-
304
- let _ids = []
305
- let update_ids = []
306
- let updateData = {}
307
-
308
- if (data[type]) {
309
- if (!Array.isArray(data[type]))
310
- data[type] = [data[type]]
311
- for (let i = 0; i < data[type].length; i++) {
312
- data[type][i] = replaceArray(data[type][i])
313
- data[type][i]['organization_id'] = data['organization_id'];
314
-
315
-
316
- if (action == 'createDocument') {
317
- data[type][i] = dotNotationToObject(data[type][i])
318
-
319
- if (!data[type][i]._id)
320
- data[type][i]._id = ObjectId()
321
- else
322
- data[type][i]._id = ObjectId(data[type][i]._id)
323
- data[type][i]['created'] = { on: data.timeStamp, by: data.user_id || data.clientId }
324
- }
325
- if (action == 'readDocument' && data[type][i]._id) {
326
- _ids.push(ObjectId(data[type][i]._id))
327
- }
328
- if (action == 'updateDocument') {
329
- if (data[type][i]._id)
330
- update_ids.push({ _id: data[type][i]._id, updateDoc: data[type][i], updateType: '_id' })
331
-
332
- if (!data[type][i]._id)
333
- updateData = createUpdate({ document: [data[type][i]] }, type)
334
-
335
- data[type][i]['modified'] = { on: data.timeStamp, by: data.user_id || data.clientId }
336
-
337
- }
338
- if (action == 'deleteDocument') {
339
- if (data[type][i]._id) {
340
- _ids.push(ObjectId(data[type][i]._id))
341
- documents.push({ _id: data[type][i]._id, db: 'mongodb', database, collection })
342
- }
343
- }
344
- }
345
- if (_ids.length == 1)
346
- query['_id'] = ObjectId(_ids[0])
347
- else if (_ids.length > 0)
348
- query['_id'] = { $in: _ids }
349
- }
350
-
351
-
352
- if (action == 'createDocument') {
353
- collectionObj.insertMany(data[type], function (error, result) {
354
- if (error)
355
- errorHandler(data, error, database, collection)
356
-
357
- for (let i = 0; i < data[type].length; i++)
358
- documents.push({ db: 'mongodb', database, collection, ...data[type][i] })
359
-
360
- collectionsLength -= 1
361
- if (!collectionsLength)
362
- databasesLength -= 1
363
-
364
- if (!databasesLength && !collectionsLength) {
365
- data = createData(data, documents, type)
366
- resolve(data)
367
- }
368
- });
369
- }
370
-
371
- if (action == 'readDocument') {
372
- let index = 0, limit = 0
373
- if (data.filter) {
374
- const count = await collectionObj.estimatedDocumentCount()
375
- data.filter.count = count
376
-
377
- if (data.filter.startIndex)
378
- index = data.filter.startIndex
379
- if (data.filter.limit)
380
- limit = data.filter.limit
381
- if (limit)
382
- limit = index + limit;
383
- }
384
-
385
- collectionObj.find(query).limit(limit).sort(sort).toArray(function (error, result) {
386
- if (error)
387
- errorHandler(data, error, database, collection)
388
-
389
- if (result) {
390
- // ToDo: forEach at cursor
391
- for (let doc of result) {
392
- let isMatch = true
393
- if (data.filter && data.filter['search'])
394
- isMatch = searchData(doc, data.filter['search'])
395
- if (isMatch) {
396
- doc.db = 'mongodb'
397
- doc.database = database
398
- doc.collection = collection
399
- doc._id = doc._id.toString()
400
- documents.push(doc)
401
- }
402
- }
403
-
404
- if (index && limit) {
405
- documents = documents.slice(index, limit)
406
- }
407
-
408
- if (data.returnDocument == false) {
409
-
410
- for (let item of data['data']) {
411
- let resp = {};
412
- resp['_id'] = tmp['_id']
413
- data[type].forEach((f) => resp[f] = item[f])
414
- documents.push(resp);
415
- }
416
-
417
- data['data'] = documents
418
- }
419
- }
420
-
421
- collectionsLength -= 1
422
- if (!collectionsLength)
423
- databasesLength -= 1
424
-
425
- if (!databasesLength && !collectionsLength) {
426
- data = createData(data, documents, type)
427
- resolve(data)
428
- }
429
- });
430
- }
431
-
432
- if (action == 'updateDocument' || action == 'deleteDocument') {
433
- const queryDocs = () => {
434
- return new Promise(async (resolve, reject) => {
435
-
436
- collectionObj.find(query).sort(sort).toArray(function (error, result) {
437
- if (error)
438
- errorHandler(data, error, database, collection)
439
-
440
- if (data.filter && data.filter.search) {
441
- let searchResult = []
442
-
443
- for (let doc of result) {
444
- let isMatch = searchData(doc, data.filter.search)
445
- if (isMatch)
446
- searchResult.push(doc)
447
- }
448
- result = searchResult
449
- }
450
- resolve(result)
451
- })
452
- }, (err) => {
453
- console.log(err);
454
- });
455
- }
456
-
457
- let Result, $update, update, projection;
458
-
459
- if (isFilter && data.returnDocument != false)
460
- if (action == 'deleteDocument' || action == 'updateDocument' && updateData.update)
461
- Result = await queryDocs()
462
-
463
- if (Result) {
464
- for (let doc of Result) {
465
- if (action == 'deleteDocument')
466
- documents.push({ _id: doc._id, db: 'mongodb', database, collection })
467
- else
468
- doc['modified'] = { on: data.timeStamp, by: data.user_id || data.clientId }
469
-
470
- _ids.push(doc._id)
471
- }
472
- update_ids.push({ updateType: 'filter' })
473
- }
474
-
475
- if (action == 'updateDocument') {
476
- let docsLength = update_ids.length
477
- for (let { updateDoc, updateType } of update_ids) {
478
-
479
- if (updateType == '_id') {
480
- let update_id = updateDoc._id
481
- query['_id'] = ObjectId(update_id)
482
- $update = createUpdate({ document: [updateDoc] }, type)
483
- update = $update.update
484
- projection = $update.projection
485
- documents.push({ _id: update_id, db: 'mongodb', database, collection, ...update['$set'] })
486
- }
487
-
488
- if (updateType == 'filter') {
489
- query['_id'] = { $in: _ids }
490
- $update = updateData
491
- update = $update.update
492
- projection = $update.projection
493
- for (let _id of _ids)
494
- documents.push({ _id, db: 'mongodb', database, collection, ...update['$set'] })
495
-
496
- }
497
-
498
- update['$set']['organization_id'] = data.organization_id
499
-
500
- collectionObj.updateMany(query, update, {
501
- upsert: data.upsert,
502
- projection
503
- }).then((result) => {
504
-
505
- }).catch((error) => {
506
- errorHandler(data, error, database, collection)
507
- console.log(action, 'error', error);
508
- }).finally((error) => {
509
- docsLength -= 1
510
- if (!docsLength)
511
- collectionsLength -= 1
512
-
513
- if (!collectionsLength)
514
- databasesLength -= 1
515
-
516
- if (!databasesLength && !collectionsLength) {
517
- data = createData(data, documents, type)
518
- resolve(data)
519
- }
520
- })
521
- }
522
-
523
- if (!update_ids.length) {
524
- docsLength -= 1
525
- if (!docsLength)
526
- collectionsLength -= 1
527
-
528
- if (!collectionsLength)
529
- databasesLength -= 1
530
-
531
- if (!databasesLength && !collectionsLength) {
532
- data = createData(data, documents, type)
533
- resolve(data)
534
- }
535
- }
536
-
537
- }
538
-
539
- if (action == 'deleteDocument') {
540
- if (_ids.length == 1)
541
- query['_id'] = ObjectId(_ids[0])
542
- else if (_ids.length > 0)
543
- query['_id'] = { $in: _ids }
544
- collectionObj.deleteMany(query, function (error, result) {
545
- collectionsLength -= 1
546
- if (!collectionsLength)
547
- databasesLength -= 1
548
-
549
- if (!databasesLength && !collectionsLength) {
550
- data = createData(data, documents, type)
551
- resolve(data)
552
- }
553
-
554
- })
555
- }
556
-
557
- }
558
-
559
- }
560
- }
561
-
562
- } catch (error) {
563
- errorHandler(data, error)
564
- console.log(action, 'error', error);
565
- resolve(data);
566
- }
567
- }, (error) => {
568
- errorHandler(data, error)
569
- });
264
+ return new Promise(async (resolve, reject) => {
265
+ try {
266
+ const client = await dbClient(data)
267
+ if (!client) return
268
+
269
+ let type = 'document'
270
+ let documents = [];
271
+
272
+ if (data.request)
273
+ data[type] = data.request
274
+
275
+
276
+ if (!data['timeStamp'])
277
+ data['timeStamp'] = new Date().toISOString()
278
+
279
+
280
+ let isFilter
281
+ if (data.filter && data.filter.query)
282
+ isFilter = true
283
+
284
+ let databases = data.database;
285
+ if (!Array.isArray(databases))
286
+ databases = [databases]
287
+
288
+ let databasesLength = databases.length
289
+ for (let database of databases) {
290
+ let collections = data.collection;
291
+ if (!Array.isArray(collections))
292
+ collections = [collections]
293
+
294
+ let collectionsLength = collections.length
295
+ for (let collection of collections) {
296
+ const db = client.db(database);
297
+ const collectionObj = db.collection(collection);
298
+
299
+ let { query, sort } = getFilters(data);
300
+ if (data['organization_id']) {
301
+ query['organization_id'] = { $eq: data['organization_id'] }
302
+ }
303
+
304
+ let _ids = []
305
+ let update_ids = []
306
+ let updateData = {}
307
+
308
+ if (data[type]) {
309
+ if (!Array.isArray(data[type]))
310
+ data[type] = [data[type]]
311
+ for (let i = 0; i < data[type].length; i++) {
312
+ data[type][i] = replaceArray(data[type][i])
313
+ data[type][i]['organization_id'] = data['organization_id'];
314
+
315
+
316
+ if (action == 'createDocument') {
317
+ data[type][i] = dotNotationToObject(data[type][i])
318
+
319
+ if (!data[type][i]._id)
320
+ data[type][i]._id = ObjectId()
321
+ else
322
+ data[type][i]._id = ObjectId(data[type][i]._id)
323
+ data[type][i]['created'] = { on: data.timeStamp, by: data.user_id || data.clientId }
324
+ }
325
+ if (action == 'readDocument' && data[type][i]._id) {
326
+ _ids.push(ObjectId(data[type][i]._id))
327
+ }
328
+ if (action == 'updateDocument') {
329
+ if (data[type][i]._id)
330
+ update_ids.push({ _id: data[type][i]._id, updateDoc: data[type][i], updateType: '_id' })
331
+
332
+ if (!data[type][i]._id)
333
+ updateData = createUpdate({ document: [data[type][i]] }, type)
334
+
335
+ data[type][i]['modified'] = { on: data.timeStamp, by: data.user_id || data.clientId }
336
+
337
+ }
338
+ if (action == 'deleteDocument') {
339
+ if (data[type][i]._id) {
340
+ _ids.push(ObjectId(data[type][i]._id))
341
+ documents.push({ _id: data[type][i]._id, db: 'mongodb', database, collection })
342
+ }
343
+ }
344
+ }
345
+ if (_ids.length == 1)
346
+ query['_id'] = ObjectId(_ids[0])
347
+ else if (_ids.length > 0)
348
+ query['_id'] = { $in: _ids }
349
+ }
350
+
351
+
352
+ if (action == 'createDocument') {
353
+ collectionObj.insertMany(data[type], function (error, result) {
354
+ if (error)
355
+ errorHandler(data, error, database, collection)
356
+
357
+ for (let i = 0; i < data[type].length; i++)
358
+ documents.push({ db: 'mongodb', database, collection, ...data[type][i] })
359
+
360
+ collectionsLength -= 1
361
+ if (!collectionsLength)
362
+ databasesLength -= 1
363
+
364
+ if (!databasesLength && !collectionsLength) {
365
+ data = createData(data, documents, type)
366
+ resolve(data)
367
+ }
368
+ });
369
+ }
370
+
371
+ if (action == 'readDocument') {
372
+ let index = 0, limit = 0
373
+ if (data.filter) {
374
+ const count = await collectionObj.estimatedDocumentCount()
375
+ data.filter.count = count
376
+
377
+ if (data.filter.startIndex)
378
+ index = data.filter.startIndex
379
+ if (data.filter.limit)
380
+ limit = data.filter.limit
381
+ if (limit)
382
+ limit = index + limit;
383
+ }
384
+
385
+ collectionObj.find(query).limit(limit).sort(sort).toArray(function (error, result) {
386
+ if (error)
387
+ errorHandler(data, error, database, collection)
388
+
389
+ if (result) {
390
+ // TODO: forEach at cursor
391
+ for (let doc of result) {
392
+ let isMatch = true
393
+ if (data.filter && data.filter['search'])
394
+ isMatch = searchData(doc, data.filter['search'])
395
+ if (isMatch) {
396
+ doc.db = 'mongodb'
397
+ doc.database = database
398
+ doc.collection = collection
399
+ doc._id = doc._id.toString()
400
+ documents.push(doc)
401
+ }
402
+ }
403
+
404
+ if (index && limit) {
405
+ documents = documents.slice(index, limit)
406
+ }
407
+
408
+ if (data.returnDocument == false) {
409
+
410
+ for (let item of data['data']) {
411
+ let resp = {};
412
+ resp['_id'] = tmp['_id']
413
+ data[type].forEach((f) => resp[f] = item[f])
414
+ documents.push(resp);
415
+ }
416
+
417
+ data['data'] = documents
418
+ }
419
+ }
420
+
421
+ collectionsLength -= 1
422
+ if (!collectionsLength)
423
+ databasesLength -= 1
424
+
425
+ if (!databasesLength && !collectionsLength) {
426
+ data = createData(data, documents, type)
427
+ resolve(data)
428
+ }
429
+ });
430
+ }
431
+
432
+ if (action == 'updateDocument' || action == 'deleteDocument') {
433
+ const queryDocs = () => {
434
+ return new Promise(async (resolve, reject) => {
435
+
436
+ collectionObj.find(query).sort(sort).toArray(function (error, result) {
437
+ if (error)
438
+ errorHandler(data, error, database, collection)
439
+
440
+ if (data.filter && data.filter.search) {
441
+ let searchResult = []
442
+
443
+ for (let doc of result) {
444
+ let isMatch = searchData(doc, data.filter.search)
445
+ if (isMatch)
446
+ searchResult.push(doc)
447
+ }
448
+ result = searchResult
449
+ }
450
+ resolve(result)
451
+ })
452
+ }, (err) => {
453
+ console.log(err);
454
+ });
455
+ }
456
+
457
+ let Result, $update, update, projection;
458
+
459
+ if (isFilter && data.returnDocument != false)
460
+ if (action == 'deleteDocument' || action == 'updateDocument' && updateData.update)
461
+ Result = await queryDocs()
462
+
463
+ if (Result) {
464
+ for (let doc of Result) {
465
+ if (action == 'deleteDocument')
466
+ documents.push({ _id: doc._id, db: 'mongodb', database, collection })
467
+ else
468
+ doc['modified'] = { on: data.timeStamp, by: data.user_id || data.clientId }
469
+
470
+ _ids.push(doc._id)
471
+ }
472
+ update_ids.push({ updateType: 'filter' })
473
+ }
474
+
475
+ if (action == 'updateDocument') {
476
+ let docsLength = update_ids.length
477
+ for (let { updateDoc, updateType } of update_ids) {
478
+
479
+ if (updateType == '_id') {
480
+ let update_id = updateDoc._id
481
+ query['_id'] = ObjectId(update_id)
482
+ $update = createUpdate({ document: [updateDoc] }, type)
483
+ update = $update.update
484
+ projection = $update.projection
485
+ documents.push({ _id: update_id, db: 'mongodb', database, collection, ...update['$set'] })
486
+ }
487
+
488
+ if (updateType == 'filter') {
489
+ query['_id'] = { $in: _ids }
490
+ $update = updateData
491
+ update = $update.update
492
+ projection = $update.projection
493
+ for (let _id of _ids)
494
+ documents.push({ _id, db: 'mongodb', database, collection, ...update['$set'] })
495
+
496
+ }
497
+
498
+ update['$set']['organization_id'] = data.organization_id
499
+
500
+ collectionObj.updateMany(query, update, {
501
+ upsert: data.upsert,
502
+ projection
503
+ }).then((result) => {
504
+
505
+ }).catch((error) => {
506
+ errorHandler(data, error, database, collection)
507
+ console.log(action, 'error', error);
508
+ }).finally((error) => {
509
+ docsLength -= 1
510
+ if (!docsLength)
511
+ collectionsLength -= 1
512
+
513
+ if (!collectionsLength)
514
+ databasesLength -= 1
515
+
516
+ if (!databasesLength && !collectionsLength) {
517
+ data = createData(data, documents, type)
518
+ resolve(data)
519
+ }
520
+ })
521
+ }
522
+
523
+ if (!update_ids.length) {
524
+ docsLength -= 1
525
+ if (!docsLength)
526
+ collectionsLength -= 1
527
+
528
+ if (!collectionsLength)
529
+ databasesLength -= 1
530
+
531
+ if (!databasesLength && !collectionsLength) {
532
+ data = createData(data, documents, type)
533
+ resolve(data)
534
+ }
535
+ }
536
+
537
+ }
538
+
539
+ if (action == 'deleteDocument') {
540
+ if (_ids.length == 1)
541
+ query['_id'] = ObjectId(_ids[0])
542
+ else if (_ids.length > 0)
543
+ query['_id'] = { $in: _ids }
544
+ collectionObj.deleteMany(query, function (error, result) {
545
+ collectionsLength -= 1
546
+ if (!collectionsLength)
547
+ databasesLength -= 1
548
+
549
+ if (!databasesLength && !collectionsLength) {
550
+ data = createData(data, documents, type)
551
+ resolve(data)
552
+ }
553
+
554
+ })
555
+ }
556
+
557
+ }
558
+
559
+ }
560
+ }
561
+
562
+ } catch (error) {
563
+ errorHandler(data, error)
564
+ console.log(action, 'error', error);
565
+ resolve(data);
566
+ }
567
+ }, (error) => {
568
+ errorHandler(data, error)
569
+ });
570
570
 
571
571
  }
572
572
 
573
573
  function createUpdate(data, type) {
574
- let update = {}, projection = {};
575
- if (data[type][0]) {
576
- update['$set'] = data[type][0]
577
- // update['$set']['organization_id'] = data['organization_id'];
578
- if (update['$set']['_id'])
579
- delete update['$set']['_id']
580
- Object.keys(update['$set']).forEach(x => {
581
- projection[x] = 1
582
- })
583
- }
584
-
585
- if (data['deleteName']) {
586
- update['$unset'] = replaceArray(data['deleteName']);
587
- }
588
-
589
- if (data['updateName']) {
590
- update['$rename'] = replaceArray(data['updateName'])
591
- for (const [key, value] of Object.entries(update['$rename'])) {
592
- if (/\.([0-9]*)/g.test(key) || /\[([0-9]*)\]/g.test(value)) {
593
- console.log('key is array', /\[([0-9]*)\]/g.test(value), /\.([0-9]*)/g.test(key))
594
- } else {
595
- let newValue = replaceArray({ [value]: value })
596
- let oldkey = key;
597
- for (const [key] of Object.entries(newValue)) {
598
- update['$rename'][oldkey] = key
599
- }
600
- }
601
- }
602
- }
603
-
604
- return { update, projection }
574
+ let update = {}, projection = {};
575
+ if (data[type][0]) {
576
+ update['$set'] = data[type][0]
577
+ // update['$set']['organization_id'] = data['organization_id'];
578
+ if (update['$set']['_id'])
579
+ delete update['$set']['_id']
580
+ Object.keys(update['$set']).forEach(key => {
581
+
582
+ if (key.includes('[u]')) {
583
+ update['$addToSet'] = { [key.replace('[u]', '')]: update['$set'][key] }
584
+ delete update['$set'][key]
585
+ } else if (key.includes('[]')) {
586
+ if (!Array.isArray(update['$set'][key]))
587
+ update['$set'][key] = [update['$set'][key]]
588
+
589
+ update['$push'] = {
590
+ [key.replace('[]', '')]: { $each: update['$set'][key] }
591
+ }
592
+ delete update['$set'][key]
593
+ }
594
+ // { $push: { "skills": { $each: ["Sports", "Acting"] } } })
595
+ // { $addToSet: { "skills": "GST" } }) // adds "GST"to all arrays if not exist
596
+ projection[key] = 1
597
+ })
598
+ }
599
+
600
+ if (data['deleteName']) {
601
+ update['$unset'] = replaceArray(data['deleteName']);
602
+ }
603
+
604
+ if (data['updateName']) {
605
+ update['$rename'] = replaceArray(data['updateName'])
606
+ for (const [key, value] of Object.entries(update['$rename'])) {
607
+ if (/\.([0-9]*)/g.test(key) || /\[([0-9]*)\]/g.test(value)) {
608
+ console.log('key is array', /\[([0-9]*)\]/g.test(value), /\.([0-9]*)/g.test(key))
609
+ } else {
610
+ let newValue = replaceArray({ [value]: value })
611
+ let oldkey = key;
612
+ for (const [key] of Object.entries(newValue)) {
613
+ update['$rename'][oldkey] = key
614
+ }
615
+ }
616
+ }
617
+ }
618
+
619
+ return { update, projection }
605
620
 
606
621
  }
607
622
 
608
623
  function createData(data, array, type) {
609
- if (!data.request)
610
- data.request = data[type] || {}
624
+ if (!data.request)
625
+ data.request = data[type] || {}
611
626
 
612
- if (data.filter && data.filter.sort)
613
- data[type] = sortData(array, data.filter.sort)
614
- else
615
- data[type] = array
627
+ if (data.filter && data.filter.sort)
628
+ data[type] = sortData(array, data.filter.sort)
629
+ else
630
+ data[type] = array
616
631
 
617
- if (data.returnLog) {
618
- if (!data.log)
619
- data.log = []
620
- data.log.push(...data[type])
621
- }
632
+ if (data.returnLog) {
633
+ if (!data.log)
634
+ data.log = []
635
+ data.log.push(...data[type])
636
+ }
622
637
 
623
- return data
638
+ return data
624
639
  }
625
640
 
626
641
  function getFilters(data) {
627
- let query = {}, sort = {}
628
- let filter = {
629
- query: [],
630
- sort: [],
631
- search: {
632
- value: [],
633
- type: "or"
634
- },
635
- startIndex: 0,
636
- ...data.filter
637
- };
638
-
639
- query = createQuery(filter.query);
640
-
641
-
642
- if (filter.sort) {
643
- for (let i = 0; i < filter.sort.length; i++) {
644
- let direction = filter.sort[i].direction
645
- if (direction == 'desc' || direction == -1)
646
- direction = -1;
647
- else
648
- direction = 1;
649
-
650
- sort[filter.sort[i].name] = filter.sort[i].direction
651
- }
652
- }
653
- return { query, sort }
642
+ let query = {}, sort = {}
643
+ let filter = {
644
+ query: [],
645
+ sort: [],
646
+ search: {
647
+ value: [],
648
+ type: "or"
649
+ },
650
+ startIndex: 0,
651
+ ...data.filter
652
+ };
653
+
654
+ query = createQuery(filter.query);
655
+
656
+
657
+ if (filter.sort) {
658
+ for (let i = 0; i < filter.sort.length; i++) {
659
+ let direction = filter.sort[i].direction
660
+ if (direction == 'desc' || direction == -1)
661
+ direction = -1;
662
+ else
663
+ direction = 1;
664
+
665
+ sort[filter.sort[i].name] = filter.sort[i].direction
666
+ }
667
+ }
668
+ return { query, sort }
654
669
  }
655
670
 
656
- // ToDo: create impved mongodb query to cover many cases
671
+ // TODO: create impved mongodb query to cover many cases
657
672
  function createQuery(filters) {
658
- let query = new Object();
659
-
660
-
661
- for (let item of filters) {
662
-
663
- if (!item.name)
664
- continue
665
-
666
- if (item.name == "_id") {
667
- if (item.value)
668
- item.value = ObjectId(item.value)
669
- else
670
- continue
671
- }
672
-
673
- let key = item.name;
674
- if (!query[key]) {
675
- query[key] = {};
676
- }
677
-
678
- switch (item.operator) {
679
- case '$includes':
680
- case 'includes':
681
- query[key]['$regex'] = item.value;
682
- break;
683
-
684
- case '$range':
685
- if (item.value[0] !== null && item.value[1] !== null) {
686
- query[key] = { $gte: item.value[0], $lte: item.value[1] };
687
- } else if (item.value[0] !== null) {
688
- query[key] = { $gte: item.value[0] };
689
- } else if (item.value[1] !== null) {
690
- query[key] = { $lte: item.value[1] };
691
- }
692
- break;
693
-
694
- case 'equals':
695
- query[$eq][item.operator] = item.value;
696
- case '$eq':
697
- case '$ne':
698
- case '$lt':
699
- case '$lte':
700
- case '$gt':
701
- case '$gte':
702
- case '$regex':
703
- query[key][item.operator] = item.value;
704
- break;
705
- case '$in':
706
- // var in_values = [];
707
- // item.value.forEach(function(v) {
708
- // in_values.push(new RegExp(".*" + v + ".*", "i"));
709
- // });
710
-
711
- query[key] = { $in: item.value }
712
- break;
713
- case '$nin':
714
- query[key][item.operator] = item.value;
715
- break;
716
- case '$geoWithin':
717
- try {
718
- let value = JSON.parse(item.value);
719
- if (item.type) {
720
- query[key]['$geoWithin'] = {
721
- [item.type]: value
722
- }
723
- }
724
- } catch (e) {
725
- console.log('geowithin error');
726
- }
727
- break;
728
- }
729
- }
730
-
731
- //. global search
732
- //. we have to set indexes in text fields ex: db.chart.createIndex({ "$**": "text" })
733
- // if (data['searchKey']) {
734
- // query["$text"] = {$search: "\"Ni\""};
735
- // }
736
-
737
- return query;
673
+ let query = new Object();
674
+
675
+
676
+ for (let item of filters) {
677
+
678
+ if (!item.name)
679
+ continue
680
+
681
+ if (item.name == "_id") {
682
+ if (item.value)
683
+ item.value = ObjectId(item.value)
684
+ else
685
+ continue
686
+ }
687
+
688
+ let key = item.name;
689
+ if (!query[key]) {
690
+ query[key] = {};
691
+ }
692
+
693
+ switch (item.operator) {
694
+ case '$includes':
695
+ case 'includes':
696
+ query[key]['$regex'] = item.value;
697
+ break;
698
+
699
+ case '$range':
700
+ if (item.value[0] !== null && item.value[1] !== null) {
701
+ query[key] = { $gte: item.value[0], $lte: item.value[1] };
702
+ } else if (item.value[0] !== null) {
703
+ query[key] = { $gte: item.value[0] };
704
+ } else if (item.value[1] !== null) {
705
+ query[key] = { $lte: item.value[1] };
706
+ }
707
+ break;
708
+
709
+ case 'equals':
710
+ query[$eq][item.operator] = item.value;
711
+ case '$eq':
712
+ case '$ne':
713
+ case '$lt':
714
+ case '$lte':
715
+ case '$gt':
716
+ case '$gte':
717
+ case '$regex':
718
+ query[key][item.operator] = item.value;
719
+ break;
720
+ case '$in':
721
+ case '$nin':
722
+ if (!Array.isArray(item.value))
723
+ query[key] = [item.value]
724
+ else
725
+ query[key] = { $in: item.value }
726
+ break;
727
+ case '$geoWithin':
728
+ try {
729
+ let value = JSON.parse(item.value);
730
+ if (item.type) {
731
+ query[key]['$geoWithin'] = {
732
+ [item.type]: value
733
+ }
734
+ }
735
+ } catch (e) {
736
+ console.log('geowithin error');
737
+ }
738
+ break;
739
+ }
740
+ }
741
+
742
+ //. global search
743
+ //. we have to set indexes in text fields ex: db.chart.createIndex({ "$**": "text" })
744
+ // if (data['searchKey']) {
745
+ // query["$text"] = {$search: "\"Ni\""};
746
+ // }
747
+
748
+ return query;
738
749
  }
739
750
 
740
751
  function errorHandler(data, error, database, collection) {
741
- if (typeof error == 'object')
742
- error['db'] = 'mongodb'
743
- else
744
- error = { db: 'mongodb', message: error }
745
-
746
- if (database)
747
- error['database'] = database
748
- if (collection)
749
- error['collection'] = collection
750
- if (data.error)
751
- data.error.push(error)
752
- else
753
- data.error = [error]
752
+ if (typeof error == 'object')
753
+ error['db'] = 'mongodb'
754
+ else
755
+ error = { db: 'mongodb', message: error }
756
+
757
+ if (database)
758
+ error['database'] = database
759
+ if (collection)
760
+ error['collection'] = collection
761
+ if (data.error)
762
+ data.error.push(error)
763
+ else
764
+ data.error = [error]
754
765
  }
755
766
 
756
767
  function replaceArray(data) {
757
- let keys = Object.keys(data);
758
- let objectData = {};
759
-
760
- keys.forEach((k) => {
761
- let nk = k
762
- if (/\[([0-9]*)\]/g.test(k)) {
763
- nk = nk.replace(/\[/g, '.');
764
- if (nk.endsWith(']'))
765
- nk = nk.slice(0, -1)
766
- nk = nk.replace(/\]./g, '.');
767
- nk = nk.replace(/\]/g, '.');
768
- }
769
- objectData[nk] = data[k];
770
- });
771
-
772
- return objectData;
768
+ let keys = Object.keys(data);
769
+ let objectData = {};
770
+
771
+ keys.forEach((k) => {
772
+ let nk = k
773
+ if (/\[([0-9]*)\]/g.test(k)) {
774
+ nk = nk.replace(/\[/g, '.');
775
+ if (nk.endsWith(']'))
776
+ nk = nk.slice(0, -1)
777
+ nk = nk.replace(/\]./g, '.');
778
+ nk = nk.replace(/\]/g, '.');
779
+ }
780
+ objectData[nk] = data[k];
781
+ });
782
+
783
+ return objectData;
773
784
  }
774
785
 
775
786
 
776
787
  module.exports = {
777
- databaseStats,
778
- createDatabase,
779
- readDatabase,
780
- updateDatabase,
781
- deleteDatabase,
782
-
783
- createCollection,
784
- readCollection,
785
- updateCollection,
786
- deleteCollection,
787
-
788
- createDocument,
789
- readDocument,
790
- updateDocument,
791
- deleteDocument,
788
+ databaseStats,
789
+ createDatabase,
790
+ readDatabase,
791
+ updateDatabase,
792
+ deleteDatabase,
793
+
794
+ createCollection,
795
+ readCollection,
796
+ updateCollection,
797
+ deleteCollection,
798
+
799
+ createDocument,
800
+ readDocument,
801
+ updateDocument,
802
+ deleteDocument,
792
803
  }