@cocreate/mongodb 1.8.0 → 1.9.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.
package/src/index.js CHANGED
@@ -20,52 +20,44 @@ async function dbClient(data) {
20
20
  return
21
21
  }
22
22
 
23
- async function databaseStats(data) {
24
- const client = await dbClient(data)
25
- if (!client) return
26
- const db = client.db(data.organization_id)
27
- const stats = await db.stats()
28
- stats.storage = data.storageName
29
- if (!data.stats)
30
- data.stats = [stats]
31
- else
32
- data.stats.push(stats)
33
- return data
34
- }
35
-
36
- function createDatabase(data) {
37
- return database('createDatabase', data)
38
- }
39
-
40
- function readDatabase(data) {
41
- return database('readDatabase', data)
42
- }
43
-
44
- function updateDatabase(data) {
45
- return database('updateDatabase', data)
46
- }
47
-
48
- function deleteDatabase(data) {
49
- return database('deleteDatabase', data)
23
+ function send(data) {
24
+ let [method, type] = data.method.split('.')
25
+ // let action = data.method.replace(/\.([a-z])/g, (_, match) => match.toUpperCase());
26
+
27
+ if (type === 'database')
28
+ return database(method + type.charAt(0).toUpperCase() + type.slice(1), data)
29
+ if (type === 'array')
30
+ return array(method + type.charAt(0).toUpperCase() + type.slice(1), data)
31
+ if (type === 'object')
32
+ return object(method + type.charAt(0).toUpperCase() + type.slice(1), data)
50
33
  }
51
34
 
52
35
  function database(action, data) {
53
36
  return new Promise(async (resolve, reject) => {
54
37
  let type = 'database'
55
38
  let databaseArray = []
39
+ let dataTransferedIn = 0
40
+ let dataTransferedOut = 0
56
41
 
57
42
  try {
58
43
  const client = await dbClient(data)
59
44
  if (!client) return
60
45
  if (action == 'readDatabase') {
61
46
  const db = client.db().admin();
47
+ // TODO: support if a database name is defined then return the database details and stats
48
+ // else apply filter and return dbs for which each should have stats and details
49
+ // if (data.database) {
50
+ // const db = client.db(data.organization_id)
51
+ // const stats = await db.stats()
52
+ // }
62
53
 
63
54
  // List all the available databases
64
55
  db.listDatabases(function (err, dbs) {
56
+ dataTransferedIn += getBytes(dbs)
65
57
 
66
58
  for (let database of dbs.databases) {
67
- if (data.filter && data.filter.query) {
68
- let isFilter = queryData(database, data.filter.query)
59
+ if (data.$filter && data.$filter.query) {
60
+ let isFilter = queryData(database, data.$filter.query)
69
61
  if (isFilter)
70
62
  databaseArray.push({ database, storage: data.storageName })
71
63
  } else
@@ -77,8 +69,9 @@ function database(action, data) {
77
69
  }
78
70
  if (action == 'deleteDatabase') {
79
71
  const db = client.db(data.database);
80
- db.dropDatabase().then(response => {
81
- resolve(response)
72
+ db.dropDatabase().then(restult => {
73
+ dataTransferedIn += getBytes(restult)
74
+ resolve(restult)
82
75
  })
83
76
  }
84
77
  } catch (error) {
@@ -92,27 +85,12 @@ function database(action, data) {
92
85
  });
93
86
  }
94
87
 
95
-
96
- function createCollection(data) {
97
- return array('createCollection', data)
98
- }
99
-
100
- function readCollection(data) {
101
- return array('readCollection', data)
102
- }
103
-
104
- function updateCollection(data) {
105
- return array('updateCollection', data)
106
- }
107
-
108
- function deleteCollection(data) {
109
- return array('deleteCollection', data)
110
- }
111
-
112
88
  function array(action, data) {
113
89
  return new Promise(async (resolve, reject) => {
114
90
  let type = 'array'
115
91
  let arrayArray = [];
92
+ let dataTransferedIn = 0
93
+ let dataTransferedOut = 0
116
94
 
117
95
  try {
118
96
  const client = await dbClient(data)
@@ -131,16 +109,18 @@ function array(action, data) {
131
109
 
132
110
  if (action == 'readCollection') {
133
111
 
134
- let { query, sort } = await getFilters(data);
112
+ let { query, sort } = await createFilter(data);
135
113
 
136
114
  db.listCollections().toArray(function (error, result) {
137
115
  if (error)
138
116
  errorHandler(data, error, database)
139
117
 
140
118
  if (result) {
119
+ dataTransferedIn += getBytes(result)
120
+
141
121
  for (let res of result) {
142
- if (data.filter && data.filter.query) {
143
- let isFilter = queryData(res, data.filter.query)
122
+ if (data.$filter && data.$filter.query) {
123
+ let isFilter = queryData(res, data.$filter.query)
144
124
  if (isFilter)
145
125
  arrayArray.push({ name: res.name, database, storage: data.storageName })
146
126
  } else
@@ -150,7 +130,7 @@ function array(action, data) {
150
130
 
151
131
  databasesLength -= 1
152
132
  if (!databasesLength) {
153
- data = createData(data, arrayArray, type)
133
+ data = createData(data, arrayArray, type, dataTransferedIn, dataTransferedOut)
154
134
  resolve(data)
155
135
  }
156
136
  })
@@ -169,19 +149,22 @@ function array(action, data) {
169
149
  for (let array of arrays) {
170
150
 
171
151
  if (action == 'createCollection') {
152
+ dataTransferedOut += getBytes(array)
172
153
  db.createCollection(array, function (error, result) {
173
154
  if (error)
174
155
  errorHandler(data, error, database, array)
175
156
 
176
- if (result)
157
+ if (result) {
158
+ dataTransferedIn += getBytes(result)
177
159
  arrayArray.push({ name: array, database, storage: data.storageName })
160
+ }
178
161
 
179
162
  arraysLength -= 1
180
163
  if (!arraysLength)
181
164
  databasesLength -= 1
182
165
 
183
166
  if (!databasesLength && !arraysLength) {
184
- data = createData(data, arrayArray, type)
167
+ data = createData(data, arrayArray, type, dataTransferedIn, dataTransferedOut)
185
168
  resolve(data)
186
169
  }
187
170
  })
@@ -193,19 +176,21 @@ function array(action, data) {
193
176
  const arrayObj = db.collection(array);
194
177
 
195
178
  if (action == 'updateCollection') {
179
+ dataTransferedOut += getBytes(result)
196
180
  arrayObj.rename(value, function (error, result) {
197
181
  if (error)
198
182
  errorHandler(data, error, database, array)
199
183
 
200
- if (result)
184
+ if (result) {
185
+ dataTransferedIn += getBytes(result)
201
186
  arrayArray.push({ name: value, oldName: array, database, storage: data.storageName })
202
-
187
+ }
203
188
  arraysLength -= 1
204
189
  if (!arraysLength)
205
190
  databasesLength -= 1
206
191
 
207
192
  if (!databasesLength && !arraysLength) {
208
- data = createData(data, arrayArray, type)
193
+ data = createData(data, arrayArray, type, dataTransferedIn, dataTransferedOut)
209
194
  resolve(data)
210
195
  }
211
196
 
@@ -217,15 +202,17 @@ function array(action, data) {
217
202
  if (error)
218
203
  errorHandler(data, error, database, array)
219
204
 
220
- if (result)
205
+ if (result) {
206
+ dataTransferedOut += getBytes(result)
221
207
  arrayArray.push({ name: array, database, storage: data.storageName })
208
+ }
222
209
 
223
210
  arraysLength -= 1
224
211
  if (!arraysLength)
225
212
  databasesLength -= 1
226
213
 
227
214
  if (!databasesLength && !arraysLength) {
228
- data = createData(data, arrayArray, type)
215
+ data = createData(data, arrayArray, type, dataTransferedIn, dataTransferedOut)
229
216
  resolve(data)
230
217
  }
231
218
 
@@ -248,29 +235,13 @@ function array(action, data) {
248
235
  });
249
236
  }
250
237
 
251
-
252
- function createObject(data) {
253
- return object('createObject', data)
254
- }
255
-
256
- function readObject(data) {
257
- return object('readObject', data)
258
- }
259
-
260
- function updateObject(data) {
261
- return object('updateObject', data)
262
- }
263
-
264
- function deleteObject(data) {
265
- return object('deleteObject', data)
266
- }
267
-
268
238
  function object(action, data) {
269
239
  return new Promise(async (resolve, reject) => {
270
240
  try {
271
241
  const client = await dbClient(data)
272
242
  if (!client) return
273
-
243
+ let dataTransferedIn = 0
244
+ let dataTransferedOut = 0
274
245
  let type = 'object'
275
246
  let documents = [];
276
247
 
@@ -284,238 +255,149 @@ function object(action, data) {
284
255
  if (!Array.isArray(databases))
285
256
  databases = [databases]
286
257
 
287
- let databasesLength = databases.length
288
258
  for (let database of databases) {
289
259
  let arrays = data.array;
290
260
  if (!Array.isArray(arrays))
291
261
  arrays = [arrays]
292
262
 
293
- let arraysLength = arrays.length
294
263
  for (let array of arrays) {
295
264
  const db = client.db(database);
296
265
  const arrayObj = db.collection(array);
266
+ const reference = { $storage: data.storageName, $database: database, $array: array }
297
267
 
298
268
  if (data[type] && !Array.isArray(data[type]))
299
269
  data[type] = [data[type]]
300
270
 
301
- if (action == 'createObject') {
302
- for (let i = 0; i < data[type].length; i++) {
303
- data[type][i] = replaceArray(data[type][i])
304
- data[type][i] = dotNotationToObject(data[type][i])
305
- data[type][i]['organization_id'] = data['organization_id'];
271
+ let isFilter
272
+ if (data.$filter && data.$filter.query)
273
+ isFilter = true
306
274
 
307
- if (!data[type][i]._id)
308
- data[type][i]._id = ObjectId()
309
- else
310
- data[type][i]._id = ObjectId(data[type][i]._id)
311
- data[type][i]['created'] = { on: data.timeStamp, by: data.user_id || data.clientId }
312
- }
275
+ let filter = await createFilter(data, arrayObj);
313
276
 
314
- arrayObj.insertMany(data[type], function (error, result) {
315
- if (error)
316
- errorHandler(data, error, database, array)
277
+ let projections = {}, projection = {}, update = {}, options = {}
317
278
 
318
- for (let i = 0; i < data[type].length; i++)
319
- documents.push({ storage: data.storageName, database, array, ...data[type][i] })
279
+ if (isFilter && (!data[type] || !data[type].length))
280
+ data[type] = [{}]
320
281
 
321
- arraysLength -= 1
322
- if (!arraysLength)
323
- databasesLength -= 1
282
+ if (action === 'updateObject')
283
+ createUpdate(update, options, data, true)
324
284
 
325
- if (!databasesLength && !arraysLength) {
326
- data = createData(data, documents, type)
327
- resolve(data)
328
- }
329
- });
330
- } else {
331
- let isFilter
332
- if (data.filter && data.filter.query)
285
+ for (let i = 0; i < data[type].length; i++) {
286
+ if (action !== 'createObject' && data[type][i].$filter) {
333
287
  isFilter = true
288
+ reference['$filter'] = data[type][i].$filter
289
+ filter = await createFilter({ $filter: data[type][i].$filter }, arrayObj)
290
+ }
334
291
 
335
- let { query, sort, index, limit } = await getFilters(data, arrayObj);
336
-
337
- if (action == 'readObject') {
338
- if (data[type]) {
339
- let _ids = []
340
- for (let i = 0; i < data[type].length; i++) {
341
- data[type][i] = replaceArray(data[type][i])
342
- if (data[type][i]._id) {
343
- _ids.push(ObjectId(data[type][i]._id))
344
- }
345
- }
346
-
347
- if (_ids.length == 1)
348
- query['_id'] = _ids[0]
349
- else if (_ids.length > 0)
350
- query['_id'] = { $in: _ids }
292
+ let { query, sort, index, limit } = filter
351
293
 
352
- }
294
+ if (action === 'createObject') {
295
+ data[type][i] = replaceArray(data[type][i])
296
+ data[type][i] = dotNotationToObject(data[type][i])
297
+ data[type][i]._id = ObjectId(data[type][i]._id)
298
+ data[type][i]['organization_id'] = data['organization_id'];
299
+ data[type][i]['created'] = { on: data.timeStamp, by: data.user_id || data.clientId }
300
+ } else if (action === 'readObject') {
301
+ projection = createProjection(data[type][i])
302
+ } else if (action === 'updateObject') {
303
+ data[type][i].modified = { on: data.timeStamp, by: data.user_id || data.clientId }
304
+ data[type][i].organization_id = data.organization_id
305
+ createUpdate(update, options, data[type][i])
306
+ }
353
307
 
308
+ if (data[type][i]._id) {
354
309
  try {
355
- const cursor = arrayObj.find(query).sort(sort).skip(index).limit(limit);
356
- while (await cursor.hasNext()) {
357
- const document = await cursor.next();
358
-
359
- if (data.filter && data.filter.search) {
360
- let isMatch = searchData(document, data.filter.search)
361
- if (!isMatch)
362
- continue;
363
- }
364
-
365
- document.storage = 'mongodb'
366
- document.database = database
367
- document.array = array
368
- document._id = document._id.toString()
369
-
370
- if (data.returnObject == false) {
371
- let tempDoc = {};
372
- let docs = new Map(data[type].map((obj) => [obj._id, obj]));
373
- let doc1 = docs.get(document._id)
374
- if (doc1) {
375
- tempDoc._id = tempDoc
376
- for (let key of Object.keys(doc1)) {
377
- tempDoc[key] = document[key]
378
- }
379
- document = tempDoc
380
- }
381
- }
310
+ if (action !== 'createObject') {
311
+ query._id = ObjectId(data[type][i]._id)
312
+ }
382
313
 
383
- documents.push(document)
314
+ dataTransferedOut += getBytes({ query, update, projection, options })
315
+
316
+ let result
317
+ if (action === 'createObject') {
318
+ let _id = data[type][i]._id.toString()
319
+ // TODO: type error occuring when pushing the item pushes but throws an error
320
+ documents.push({ ...data[type][i], ...reference, _id })
321
+ } else if (action === 'readObject') {
322
+ result = await arrayObj.findOne(query, projection);
323
+ result._id = result._id.toString()
324
+ documents.push({ ...result, ...reference })
325
+ } else if (action === 'updateObject') {
326
+ result = await arrayObj.updateOne(query, update, options);
327
+ documents.push({ ...data[type][i], ...reference })
328
+ } else if (action === 'deleteObject') {
329
+ result = await arrayObj.deleteOne(query);
330
+ documents.push({ ...reference, _id: data[type][i]._id })
384
331
  }
332
+ dataTransferedIn += getBytes(result)
333
+
385
334
  } catch (error) {
386
335
  errorHandler(data, error, database, array)
387
336
  }
337
+ } else if (isFilter) {
338
+ try {
339
+ if (action === 'readObject')
340
+ projection = { ...projections, ...projection }
388
341
 
389
- arraysLength -= 1
390
- if (!arraysLength)
391
- databasesLength -= 1
342
+ delete query._id
392
343
 
393
- if (!databasesLength && !arraysLength) {
394
- data = createData(data, documents, type)
395
- resolve(data)
396
- }
397
- } else if (action == 'updateObject') {
344
+ dataTransferedOut += getBytes({ query, projection, sort, index, limit })
345
+ let document = ''
398
346
 
399
- if (!data[type].length) {
400
- arraysLength -= 1
347
+ const cursor = arrayObj.find(query, projection).sort(sort).skip(index).limit(limit);
348
+ if (!(await cursor.hasNext()) && action === 'updateObject' && data.upsert)
349
+ document = { _id: ObjectId(data[type][i]._id) }
350
+ while (await cursor.hasNext() || document) {
351
+ if (!document)
352
+ document = await cursor.next();
401
353
 
402
- if (!arraysLength)
403
- databasesLength -= 1
354
+ dataTransferedIn += getBytes(document)
404
355
 
405
- if (!databasesLength && !arraysLength) {
406
- data = createData(data, documents, type)
407
- resolve(data)
408
- }
409
- }
410
-
411
- let docsLength = data[type].length
412
- for (let i = 0; i < data[type].length; i++) {
413
- if (data[type][i]._id)
414
- query['_id'] = ObjectId(data[type][i]._id)
415
-
416
- data[type][i] = replaceArray(data[type][i])
417
- let { update, projection } = createUpdate(data, type, i)
418
-
419
- if (query['_id']) {
420
- arrayObj.updateOne(query, update, {
421
- upsert: data.upsert,
422
- projection
423
- }).then((result) => {
424
- documents.push({ _id: query['_id'].toString(), storage: data.storageName, database, array, ...update['$set'] })
425
- }).catch((error) => {
426
- errorHandler(data, error, database, array)
427
- console.log(action, 'error', error);
428
- }).finally(() => {
429
- docsLength -= 1
430
- if (!docsLength)
431
- arraysLength -= 1
432
-
433
- if (!arraysLength)
434
- databasesLength -= 1
435
-
436
- if (!databasesLength && !arraysLength) {
437
- data = createData(data, documents, type)
438
- resolve(data)
439
- }
440
- })
441
- } else if (update && isFilter) {
442
- const cursor = arrayObj.find(query).sort(sort).skip(index).limit(limit);
443
- while (await cursor.hasNext()) {
444
- const document = await cursor.next();
445
-
446
- if (data.filter && data.filter.search) {
447
- let isMatch = searchData(document, data.filter.search)
448
- if (!isMatch)
449
- continue;
450
- }
451
-
452
- arrayObj.updateOne({ _id: document._id }, update, {
453
- upsert: data.upsert,
454
- projection
455
- }).then((result) => {
456
- if (data.returnObject != false)
457
- documents.push({ _id: document._id, storage: data.storageName, database, array, ...update['$set'] })
458
- }).catch((error) => {
459
- errorHandler(data, error, database, array)
460
- console.log(action, 'error', error);
461
- })
462
- }
463
- }
464
- }
465
- } else if (action == 'deleteObject') {
466
- if (isFilter && data.returnObject != false) {
467
- const cursor = arrayObj.find(query).sort(sort).skip(index).limit(limit);
468
- while (await cursor.hasNext()) {
469
- const document = await cursor.next();
470
-
471
- if (data.filter && data.filter.search) {
472
- let isMatch = searchData(document, data.filter.search)
356
+ if (data.$filter && data.$filter.search) {
357
+ let isMatch = searchData(document, data.$filter.search)
473
358
  if (!isMatch)
474
359
  continue;
475
360
  }
476
361
 
477
- arrayObj.deleteOne({
478
- _id: document._id
479
- }).then((result) => {
480
- documents.push({ _id: document._id, storage: data.storageName, database, array })
481
- }).catch((error) => {
482
- errorHandler(data, error, database, array)
483
- console.log(action, 'error', error);
484
- });
485
- }
362
+ if (action === 'readObject') {
363
+ documents.push({ ...document, ...reference, _id: document._id.toString() })
364
+ } else {
365
+ dataTransferedOut += getBytes({ _id: document._id, update, options })
486
366
 
487
- }
367
+ let result
368
+ if (action === 'updateObject') {
369
+ result = await arrayObj.updateOne({ _id: document._id }, update, options);
370
+ } else if (action === 'deleteObject') {
371
+ result = await arrayObj.deleteOne({ _id: document._id });
372
+ }
488
373
 
489
- let _ids = [];
490
- for (let i = 0; i < data[type].length; i++) {
491
- if (data[type][i]._id) {
492
- _ids.push(ObjectId(data[type][i]._id))
493
- documents.push({ _id: data[type][i]._id, storage: data.storageName, database, array })
374
+ dataTransferedIn += getBytes(result)
375
+ documents.push({ ...data[type][i], ...reference, _id: document._id.toString() })
376
+ }
377
+ document = ''
494
378
  }
379
+ } catch (error) {
380
+ errorHandler(data, error, database, array)
495
381
  }
382
+ }
383
+ }
496
384
 
497
- if (_ids.length == 1)
498
- query['_id'] = _ids[0]
499
- else if (_ids.length)
500
- query['_id'] = { $in: _ids }
501
-
502
- arrayObj.deleteMany(query, function (error, result) {
503
- arraysLength -= 1
504
- if (!arraysLength)
505
- databasesLength -= 1
506
-
507
- if (!databasesLength && !arraysLength) {
508
- data = createData(data, documents, type)
509
- resolve(data)
510
- }
511
-
512
- })
385
+ if (action === 'createObject') {
386
+ try {
387
+ dataTransferedOut += getBytes(data[type])
388
+ const result = await arrayObj.insertMany(data[type]);
389
+ dataTransferedIn += getBytes(result)
390
+ } catch (error) {
391
+ errorHandler(data, error, database, array)
513
392
  }
514
393
  }
515
394
 
516
395
  }
517
396
  }
518
397
 
398
+ data = createData(data, documents, type, dataTransferedIn, dataTransferedOut)
399
+ resolve(data)
400
+
519
401
  } catch (error) {
520
402
  errorHandler(data, error)
521
403
  console.log(action, 'error', error);
@@ -527,156 +409,120 @@ function object(action, data) {
527
409
 
528
410
  }
529
411
 
530
- function createUpdate(data, type, index) {
531
- let update = {}, projection = {};
532
- if (data[type][index]) {
533
- update['$set'] = data[type][index]
534
- update['$set']['modified'] = { on: data.timeStamp, by: data.user_id || data.clientId }
535
- update['$set']['organization_id'] = data.organization_id
536
-
537
- if (update['$set']['_id'])
538
- delete update['$set']['_id']
539
-
540
- Object.keys(update['$set']).forEach(key => {
541
- if (key.includes('$rename') || key.includes('$update')) {
542
-
543
- } else if (key.includes('$delete')) {
544
-
545
- } else if (key.includes('$inc')) {
546
- update['$inc'] = update['$set'][key]
547
- delete update['$set'][key]
548
- } else if (key.endsWith(']')) {
549
- // Use a regular expression to extract the key and index (including a potentially undefined or keyword index)
550
- const regex = /^(.*(?:\[\d+\].*?)?)\[(.*?)\](?:\[\])?$/;
551
- const match = inputString.match(regex);
552
- const index = parseInt(match[2], 10);
553
-
554
- if (index && index !== -1 && index !== 1 && update['$set'][key] === '$delete') {
555
- match[1] = replaceArray({ [update['$set'][key]]: update['$set'][key] });
556
- match[1] = Object.keys(match[1])[0]
557
-
558
- if (!update['$unset'])
559
- update['$unset'] = {}
560
-
561
- update.$unset[match[1]] = 1;
562
-
563
- if (!update['$pull'])
564
- update['$pull'] = {}
565
-
566
- update.$pull[match[1]] = null;
567
- } else {
568
- match[1] = replaceArray({ [match[1]]: update['$set'][key] });
569
- match[1] = Object.keys(match[1])[0]
570
-
571
- if (update['$set'][key] === '$pop' || update['$set'][key] === '$delete') {
572
- if (!update['$pop'])
573
- update['$pop'] = {}
574
-
575
- update.$pop[match[1]] = index || 1
576
- } else if (match[2] === '$addToSet') {
577
- if (!update['$addToSet'])
578
- update['$addToSet'] = {}
579
-
580
- update.$addToSet[match[1]] = update['$set'][key]
581
- } else if (match[2] === '$pull') {
582
- if (!update['$pull'])
583
- update['$pull'] = {}
412
+ function createUpdate(update, options, data, isGlobal) {
413
+ if (data.upsert)
414
+ options.upsert = data.upsert
415
+ if (data.$upsert)
416
+ options.upsert = data.$upsert
417
+
418
+ Object.keys(data).forEach(key => {
419
+ if (isGlobal && !key.startsWith('$') || key === '_id')
420
+ return
421
+
422
+ let operator
423
+ if (key.endsWith(']')) {
424
+ const regex = /^(.*(?:\[\d+\].*?)?)\[(.*?)\](?:\[\])?$/;
425
+ var match = key.match(regex);
426
+ var index = parseInt(match[2], 10);
427
+ if (index === NaN)
428
+ operator = match[2]
429
+ var arrayKey = match[1].replace(/\[(\d+)\]/g, '.$1');
430
+ }
584
431
 
585
- update.$pull[match[1]] = update['$set'][key]
586
- } else {
587
- if (!Array.isArray(update['$set'][key]))
588
- update['$set'][key] = [update['$set'][key]]
432
+ if (key.startsWith('$'))
433
+ operator = key.split('.')[0]
434
+ else if (!operator && typeof data[key] === 'string' && data[key].startsWith('$'))
435
+ operator = data[key]
589
436
 
590
- let insert = { $each: update['$set'][key] }
591
- if (index)
592
- insert.$postion = match[2]
437
+ if (!update['$set'])
438
+ update['$set'] = {}
593
439
 
594
- if (!update['$push'])
595
- update['$push'] = {}
440
+ let originalKey = key
441
+ key = key.replace(/\[(\d+)\]/g, '.$1');
596
442
 
597
- update.$push[match[1]] = insert
443
+ let operators = ['$rename', '$inc', '$push', '$splice', '$unset', '$delete', '$slice', '$pop']
444
+ if (!operators.includes(operator) && typeof index !== 'number') {
445
+ if (!isGlobal)
446
+ update['$set'][key] = data[originalKey]
447
+ return
448
+ }
598
449
 
599
- }
450
+ let updates = {}
451
+ if (operator === '$rename') {
452
+ if (key === '$rename')
453
+ for (let oldkey of Object.keys(data[originalKey])) {
454
+ key = '$rename.' + oldkey
455
+ updates[key] = data[originalKey][oldkey].replace(/\[(\d+)\]/g, '.$1')
600
456
  }
457
+ else
458
+ updates[key] = data[originalKey].replace(/\[(\d+)\]/g, '.$1')
459
+
460
+ } else if (operator === '$delete' || operator === '$unset' || operator === '$slice') {
461
+ operator = '$unset'
462
+ updates[key] = 1
463
+ if (!updates['$pull'])
464
+ updates['$pull'] = {}
465
+ updates['$pull'][key] = null
466
+ } else if (operator === '$pop') {
467
+ key = arrayKey
468
+ updates[key] = index || 1
469
+ } else if (operator === '$addToSet' || operator === '$pull') {
470
+ key = arrayKey
471
+ updates[key] = data[originalKey]
472
+ } else if (operator === '$push' || typeof index === 'number') {
473
+ if (!Array.isArray(data[originalKey]))
474
+ updates[key] = [data[originalKey]]
475
+ else
476
+ updates[key] = data[originalKey]
601
477
 
602
- delete update['$set'][key]
603
-
604
- }
605
- projection[key] = 1
606
- })
607
- }
608
-
609
- if (data['deleteName']) {
610
- update['$unset'] = replaceArray(data['deleteName']);
611
- }
478
+ let insert = { $each: updates[key] }
479
+ if (typeof index === 'number' && index >= 0)
480
+ insert.$postion = index
612
481
 
613
- if (data['updateName']) {
614
- update['$rename'] = replaceArray(data['updateName'])
615
- for (const [key, value] of Object.entries(update['$rename'])) {
616
- if (/\.([0-9]*)/g.test(key) || /\[([0-9]*)\]/g.test(value)) {
617
- console.log('key is array', /\[([0-9]*)\]/g.test(value), /\.([0-9]*)/g.test(key))
618
- } else {
619
- let newValue = replaceArray({ [value]: value })
620
- let oldkey = key;
621
- for (const [key] of Object.entries(newValue)) {
622
- update['$rename'][oldkey] = key
623
- }
624
- }
482
+ updates[key] = insert
483
+ } else if (operator === '$inc') {
484
+ updates[key] = data[originalKey]
625
485
  }
626
- }
627
486
 
628
- return { update, projection }
487
+ if (!update[operator])
488
+ update[operator] = {}
629
489
 
490
+ if (key === operator)
491
+ update[operator] = { ...update[operator], ...replaceArray(updates[key]) }
492
+ else
493
+ update[operator][key.replace(operator, '')] = updates[key]
494
+ })
630
495
  }
631
496
 
632
- function createData(data, array, type) {
633
- if (!data.request)
634
- data.request = data[type] || {}
635
-
636
- if (data.filter && data.filter.sort)
637
- data[type] = sortData(array, data.filter.sort)
638
- else
639
- data[type] = array
497
+ async function createFilter(data, arrayObj) {
498
+ let query = {}, sort = {}, index = 0, limit = 0, count
640
499
 
641
- if (data.returnLog) {
642
- if (!data.log)
643
- data.log = []
644
- data.log.push(...data[type])
645
- }
646
-
647
- return data
648
- }
500
+ if (data.$filter) {
501
+ if (data.$filter.query)
502
+ query = createQuery(data.$filter.query);
649
503
 
650
- async function getFilters(data, arrayObj) {
651
- let query =
652
- {}, sort = {}, index = 0, limit = 0, count
653
- if (data.filter) {
654
504
 
655
- if (data.filter.query)
656
- query = createQuery(data.filter.query);
657
-
658
-
659
- if (data.filter.sort) {
660
- for (let i = 0; i < data.filter.sort.length; i++) {
661
- let direction = data.filter.sort[i].direction
505
+ if (data.$filter.sort) {
506
+ for (let i = 0; i < data.$filter.sort.length; i++) {
507
+ let direction = data.$filter.sort[i].direction
662
508
  if (direction == 'desc' || direction == -1)
663
509
  direction = -1;
664
510
  else
665
511
  direction = 1;
666
512
 
667
- sort[data.filter.sort[i].key] = direction
513
+ sort[data.$filter.sort[i].key] = direction
668
514
  }
669
515
  }
670
516
 
671
517
  if (arrayObj) {
672
518
  count = await arrayObj.estimatedDocumentCount()
673
- data.filter.count = count
519
+ data.$filter.count = count
674
520
  }
675
521
 
676
- if (data.filter.index)
677
- index = data.filter.index
678
- if (data.filter.limit)
679
- limit = data.filter.limit
522
+ if (data.$filter.index)
523
+ index = data.$filter.index
524
+ if (data.$filter.limit)
525
+ limit = data.$filter.limit
680
526
  if (limit)
681
527
  limit = index + limit;
682
528
  }
@@ -687,6 +533,7 @@ async function getFilters(data, arrayObj) {
687
533
  return { query, sort, index, limit, count }
688
534
  }
689
535
 
536
+
690
537
  // TODO: improve mongodb query to cover many cases
691
538
  function createQuery(queries) {
692
539
  let query = new Object();
@@ -742,6 +589,13 @@ function createQuery(queries) {
742
589
  else
743
590
  query[key] = { $in: item.value }
744
591
  break;
592
+ case '$or':
593
+ if (!query[item.operator])
594
+ query[item.operator] = [{ [key]: item.value }];
595
+ else
596
+ query[item.operator].push({ [key]: item.value })
597
+ delete query[key]
598
+ break;
745
599
  case '$geoWithin':
746
600
  try {
747
601
  let value = JSON.parse(item.value);
@@ -766,6 +620,63 @@ function createQuery(queries) {
766
620
  return query;
767
621
  }
768
622
 
623
+ function createProjection(data) {
624
+ let projection = {}
625
+
626
+ Object.keys(data).forEach((key) => {
627
+ if (!['_id', 'organization_id'].includes(key) && !key.startsWith('$'))
628
+ projection[key.replace(/\[(\d+)\]/g, '.$1')] = 1
629
+ });
630
+
631
+ return projection;
632
+ }
633
+
634
+ function replaceArray(data) {
635
+ let object = {}
636
+
637
+ Object.keys(data).forEach((key) => {
638
+ object[key.replace(/\[(\d+)\]/g, '.$1')] = data[key]
639
+ });
640
+
641
+ return object;
642
+ }
643
+
644
+ function createData(data, array, type, dataTransferedIn, dataTransferedOut) {
645
+ if (dataTransferedIn) {
646
+ process.emit("setBandwidth", {
647
+ type: 'in',
648
+ data: dataTransferedIn,
649
+ organization_id: data.organization_id
650
+ });
651
+ }
652
+
653
+ if (dataTransferedOut) {
654
+ process.emit("setBandwidth", {
655
+ type: 'out',
656
+ data: dataTransferedOut,
657
+ organization_id: data.organization_id
658
+ });
659
+ }
660
+
661
+ if (!data.request)
662
+ data.request = data[type] || {}
663
+
664
+ data[type] = array
665
+
666
+ if (data.returnLog) {
667
+ if (!data.log)
668
+ data.log = []
669
+ data.log.push(...data[type])
670
+ }
671
+
672
+ return data
673
+ }
674
+
675
+ function getBytes(data) {
676
+ const jsonString = JSON.stringify(data);
677
+ return Buffer.byteLength(jsonString, 'utf8');
678
+ }
679
+
769
680
  function errorHandler(data, error, database, array) {
770
681
  if (typeof error == 'object')
771
682
  error['storage'] = 'mongodb'
@@ -782,40 +693,4 @@ function errorHandler(data, error, database, array) {
782
693
  data.error = [error]
783
694
  }
784
695
 
785
- function replaceArray(data) {
786
- let keys = Object.keys(data);
787
- let objectData = {};
788
-
789
- keys.forEach((k) => {
790
- let nk = k
791
- if (/\[([0-9]*)\]/g.test(k)) {
792
- nk = nk.replace(/\[/g, '.');
793
- if (nk.endsWith(']'))
794
- nk = nk.slice(0, -1)
795
- nk = nk.replace(/\]./g, '.');
796
- nk = nk.replace(/\]/g, '.');
797
- }
798
- objectData[nk] = data[k];
799
- });
800
-
801
- return objectData;
802
- }
803
-
804
-
805
- module.exports = {
806
- databaseStats,
807
- createDatabase,
808
- readDatabase,
809
- updateDatabase,
810
- deleteDatabase,
811
-
812
- createCollection,
813
- readCollection,
814
- updateCollection,
815
- deleteCollection,
816
-
817
- createObject,
818
- readObject,
819
- updateObject,
820
- deleteObject,
821
- }
696
+ module.exports = { send }