@cocreate/mongodb 1.2.5 → 1.3.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +1 -1
  3. package/src/index.js +718 -708
package/src/index.js CHANGED
@@ -4,789 +4,799 @@ 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
+ else if (key.includes('[]')) {
585
+ if (!Array.isArray(update['$set'][key]))
586
+ update['$set'][key] = [update['$set'][key]]
587
+
588
+ update['$push'] = {
589
+ [key.replace('[]', '')]: { $each: update['$set'][key] }
590
+ }
591
+ }
592
+ delete update['$set'][key]
593
+ // { $push: { "skills": { $each: ["Sports", "Acting"] } } })
594
+ // { $addToSet: { "skills": "GST" } }) // adds "GST"to all arrays if not exist
595
+ projection[key] = 1
596
+ })
597
+ }
598
+
599
+ if (data['deleteName']) {
600
+ update['$unset'] = replaceArray(data['deleteName']);
601
+ }
602
+
603
+ if (data['updateName']) {
604
+ update['$rename'] = replaceArray(data['updateName'])
605
+ for (const [key, value] of Object.entries(update['$rename'])) {
606
+ if (/\.([0-9]*)/g.test(key) || /\[([0-9]*)\]/g.test(value)) {
607
+ console.log('key is array', /\[([0-9]*)\]/g.test(value), /\.([0-9]*)/g.test(key))
608
+ } else {
609
+ let newValue = replaceArray({ [value]: value })
610
+ let oldkey = key;
611
+ for (const [key] of Object.entries(newValue)) {
612
+ update['$rename'][oldkey] = key
613
+ }
614
+ }
615
+ }
616
+ }
617
+
618
+ return { update, projection }
605
619
 
606
620
  }
607
621
 
608
622
  function createData(data, array, type) {
609
- if (!data.request)
610
- data.request = data[type] || {}
623
+ if (!data.request)
624
+ data.request = data[type] || {}
611
625
 
612
- if (data.filter && data.filter.sort)
613
- data[type] = sortData(array, data.filter.sort)
614
- else
615
- data[type] = array
626
+ if (data.filter && data.filter.sort)
627
+ data[type] = sortData(array, data.filter.sort)
628
+ else
629
+ data[type] = array
616
630
 
617
- if (data.returnLog) {
618
- if (!data.log)
619
- data.log = []
620
- data.log.push(...data[type])
621
- }
631
+ if (data.returnLog) {
632
+ if (!data.log)
633
+ data.log = []
634
+ data.log.push(...data[type])
635
+ }
622
636
 
623
- return data
637
+ return data
624
638
  }
625
639
 
626
640
  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 }
641
+ let query = {}, sort = {}
642
+ let filter = {
643
+ query: [],
644
+ sort: [],
645
+ search: {
646
+ value: [],
647
+ type: "or"
648
+ },
649
+ startIndex: 0,
650
+ ...data.filter
651
+ };
652
+
653
+ query = createQuery(filter.query);
654
+
655
+
656
+ if (filter.sort) {
657
+ for (let i = 0; i < filter.sort.length; i++) {
658
+ let direction = filter.sort[i].direction
659
+ if (direction == 'desc' || direction == -1)
660
+ direction = -1;
661
+ else
662
+ direction = 1;
663
+
664
+ sort[filter.sort[i].name] = filter.sort[i].direction
665
+ }
666
+ }
667
+ return { query, sort }
654
668
  }
655
669
 
656
- // ToDo: create impved mongodb query to cover many cases
670
+ // TODO: create impved mongodb query to cover many cases
657
671
  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;
672
+ let query = new Object();
673
+
674
+
675
+ for (let item of filters) {
676
+
677
+ if (!item.name)
678
+ continue
679
+
680
+ if (item.name == "_id") {
681
+ if (item.value)
682
+ item.value = ObjectId(item.value)
683
+ else
684
+ continue
685
+ }
686
+
687
+ let key = item.name;
688
+ if (!query[key]) {
689
+ query[key] = {};
690
+ }
691
+
692
+ switch (item.operator) {
693
+ case '$includes':
694
+ case 'includes':
695
+ query[key]['$regex'] = item.value;
696
+ break;
697
+
698
+ case '$range':
699
+ if (item.value[0] !== null && item.value[1] !== null) {
700
+ query[key] = { $gte: item.value[0], $lte: item.value[1] };
701
+ } else if (item.value[0] !== null) {
702
+ query[key] = { $gte: item.value[0] };
703
+ } else if (item.value[1] !== null) {
704
+ query[key] = { $lte: item.value[1] };
705
+ }
706
+ break;
707
+
708
+ case 'equals':
709
+ query[$eq][item.operator] = item.value;
710
+ case '$eq':
711
+ case '$ne':
712
+ case '$lt':
713
+ case '$lte':
714
+ case '$gt':
715
+ case '$gte':
716
+ case '$regex':
717
+ query[key][item.operator] = item.value;
718
+ break;
719
+ case '$in':
720
+ case '$nin':
721
+ if (!Array.isArray(item.value))
722
+ query[key] = [item.value]
723
+ else
724
+ query[key] = { $in: item.value }
725
+ break;
726
+ case '$geoWithin':
727
+ try {
728
+ let value = JSON.parse(item.value);
729
+ if (item.type) {
730
+ query[key]['$geoWithin'] = {
731
+ [item.type]: value
732
+ }
733
+ }
734
+ } catch (e) {
735
+ console.log('geowithin error');
736
+ }
737
+ break;
738
+ }
739
+ }
740
+
741
+ //. global search
742
+ //. we have to set indexes in text fields ex: db.chart.createIndex({ "$**": "text" })
743
+ // if (data['searchKey']) {
744
+ // query["$text"] = {$search: "\"Ni\""};
745
+ // }
746
+
747
+ return query;
738
748
  }
739
749
 
740
750
  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]
751
+ if (typeof error == 'object')
752
+ error['db'] = 'mongodb'
753
+ else
754
+ error = { db: 'mongodb', message: error }
755
+
756
+ if (database)
757
+ error['database'] = database
758
+ if (collection)
759
+ error['collection'] = collection
760
+ if (data.error)
761
+ data.error.push(error)
762
+ else
763
+ data.error = [error]
754
764
  }
755
765
 
756
766
  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;
767
+ let keys = Object.keys(data);
768
+ let objectData = {};
769
+
770
+ keys.forEach((k) => {
771
+ let nk = k
772
+ if (/\[([0-9]*)\]/g.test(k)) {
773
+ nk = nk.replace(/\[/g, '.');
774
+ if (nk.endsWith(']'))
775
+ nk = nk.slice(0, -1)
776
+ nk = nk.replace(/\]./g, '.');
777
+ nk = nk.replace(/\]/g, '.');
778
+ }
779
+ objectData[nk] = data[k];
780
+ });
781
+
782
+ return objectData;
773
783
  }
774
784
 
775
785
 
776
786
  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,
787
+ databaseStats,
788
+ createDatabase,
789
+ readDatabase,
790
+ updateDatabase,
791
+ deleteDatabase,
792
+
793
+ createCollection,
794
+ readCollection,
795
+ updateCollection,
796
+ deleteCollection,
797
+
798
+ createDocument,
799
+ readDocument,
800
+ updateDocument,
801
+ deleteDocument,
792
802
  }