meadow 2.0.23 → 2.0.26

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 (59) hide show
  1. package/README.md +110 -141
  2. package/docs/README.md +34 -230
  3. package/docs/_cover.md +14 -0
  4. package/docs/_sidebar.md +44 -12
  5. package/docs/_topbar.md +5 -0
  6. package/docs/api/doCount.md +109 -0
  7. package/docs/api/doCreate.md +132 -0
  8. package/docs/api/doDelete.md +101 -0
  9. package/docs/api/doRead.md +122 -0
  10. package/docs/api/doReads.md +136 -0
  11. package/docs/api/doUndelete.md +98 -0
  12. package/docs/api/doUpdate.md +129 -0
  13. package/docs/api/getRoleName.md +84 -0
  14. package/docs/api/loadFromPackage.md +153 -0
  15. package/docs/api/marshalRecordFromSourceToObject.md +92 -0
  16. package/docs/api/query.md +133 -0
  17. package/docs/api/rawQueries.md +197 -0
  18. package/docs/api/reference.md +117 -0
  19. package/docs/api/setAuthorizer.md +103 -0
  20. package/docs/api/setDefault.md +90 -0
  21. package/docs/api/setDefaultIdentifier.md +84 -0
  22. package/docs/api/setDomain.md +56 -0
  23. package/docs/api/setIDUser.md +91 -0
  24. package/docs/api/setJsonSchema.md +92 -0
  25. package/docs/api/setProvider.md +87 -0
  26. package/docs/api/setSchema.md +107 -0
  27. package/docs/api/setScope.md +68 -0
  28. package/docs/api/validateObject.md +119 -0
  29. package/docs/architecture.md +316 -0
  30. package/docs/audit-tracking.md +226 -0
  31. package/docs/configuration.md +317 -0
  32. package/docs/providers/meadow-endpoints.md +306 -0
  33. package/docs/providers/mongodb.md +319 -0
  34. package/docs/providers/postgresql.md +312 -0
  35. package/docs/providers/rocksdb.md +297 -0
  36. package/docs/query-dsl.md +269 -0
  37. package/docs/quick-start.md +384 -0
  38. package/docs/raw-queries.md +193 -0
  39. package/docs/retold-catalog.json +61 -1
  40. package/docs/retold-keyword-index.json +15860 -4839
  41. package/docs/soft-deletes.md +224 -0
  42. package/package.json +36 -9
  43. package/scripts/bookstore-seed-postgresql.sql +135 -0
  44. package/scripts/dgraph-test-db.sh +144 -0
  45. package/scripts/meadow-test-cleanup.sh +5 -1
  46. package/scripts/mongodb-test-db.sh +98 -0
  47. package/scripts/postgresql-test-db.sh +124 -0
  48. package/scripts/solr-test-db.sh +135 -0
  49. package/source/Meadow.js +5 -0
  50. package/source/providers/Meadow-Provider-DGraph.js +679 -0
  51. package/source/providers/Meadow-Provider-MongoDB.js +527 -0
  52. package/source/providers/Meadow-Provider-PostgreSQL.js +361 -0
  53. package/source/providers/Meadow-Provider-RocksDB.js +1300 -0
  54. package/source/providers/Meadow-Provider-Solr.js +726 -0
  55. package/test/Meadow-Provider-DGraph_tests.js +741 -0
  56. package/test/Meadow-Provider-MongoDB_tests.js +661 -0
  57. package/test/Meadow-Provider-PostgreSQL_tests.js +787 -0
  58. package/test/Meadow-Provider-RocksDB_tests.js +887 -0
  59. package/test/Meadow-Provider-Solr_tests.js +679 -0
@@ -0,0 +1,679 @@
1
+ // ##### Part of the **[retold](https://stevenvelozo.github.io/retold/)** system
2
+ /**
3
+ * @license MIT
4
+ * @author <steven@velozo.com>
5
+ */
6
+ var MeadowProvider = function ()
7
+ {
8
+ function createNew(pFable)
9
+ {
10
+ // If a valid Fable object isn't passed in, return a constructor
11
+ if (typeof (pFable) !== 'object')
12
+ {
13
+ return { new: createNew };
14
+ }
15
+ var _Fable = pFable;
16
+ var _GlobalLogLevel = 0;
17
+ if (_Fable.settings.DGraph)
18
+ {
19
+ _GlobalLogLevel = _Fable.settings.DGraph.GlobalLogLevel || 0;
20
+ }
21
+
22
+ /**
23
+ * Get the DGraph client from the connection service.
24
+ */
25
+ var getClient = function ()
26
+ {
27
+ if (typeof (_Fable.MeadowDGraphProvider) == 'object' && _Fable.MeadowDGraphProvider.connected)
28
+ {
29
+ return _Fable.MeadowDGraphProvider.pool;
30
+ }
31
+ return false;
32
+ };
33
+
34
+ var getProvider = function ()
35
+ {
36
+ if (typeof (_Fable.MeadowDGraphProvider) == 'object')
37
+ {
38
+ return _Fable.MeadowDGraphProvider;
39
+ }
40
+ return false;
41
+ };
42
+
43
+ /**
44
+ * Deep-walk an object and replace $$NOW sentinels with ISO datetime strings.
45
+ * DGraph expects RFC3339/ISO8601 formatted datetime strings.
46
+ *
47
+ * @param {Object} pObj Object to process (mutated in place)
48
+ * @return {Object} The same object with sentinels replaced
49
+ */
50
+ var replaceSentinels = function (pObj)
51
+ {
52
+ if (typeof pObj !== 'object' || pObj === null)
53
+ {
54
+ return pObj;
55
+ }
56
+
57
+ for (var tmpKey in pObj)
58
+ {
59
+ if (!pObj.hasOwnProperty(tmpKey))
60
+ {
61
+ continue;
62
+ }
63
+
64
+ if (pObj[tmpKey] === '$$NOW')
65
+ {
66
+ pObj[tmpKey] = new Date().toISOString();
67
+ }
68
+ else if (typeof pObj[tmpKey] === 'object' && pObj[tmpKey] !== null)
69
+ {
70
+ replaceSentinels(pObj[tmpKey]);
71
+ }
72
+ }
73
+ return pObj;
74
+ };
75
+
76
+ /**
77
+ * Get the next auto-increment sequence value for a type/column pair.
78
+ * Uses MeadowCounter nodes in DGraph with query-then-mutate.
79
+ *
80
+ * @param {Object} pClient DGraph client instance
81
+ * @param {String} pScope Type name
82
+ * @param {String} pIDColumn Identity column name
83
+ * @param {Function} fCallback (error, nextSequenceValue)
84
+ */
85
+ var getNextSequence = function (pClient, pScope, pIDColumn, fCallback)
86
+ {
87
+ var tmpCounterKey = pScope + '.' + pIDColumn;
88
+
89
+ // Query for existing counter
90
+ var tmpQuery = '{ counter(func: eq(MeadowCounter.scope, "' + tmpCounterKey + '")) { uid MeadowCounter.sequence } }';
91
+ var tmpTxn = pClient.newTxn();
92
+
93
+ tmpTxn.query(tmpQuery)
94
+ .then(function (pResponse)
95
+ {
96
+ var tmpData = pResponse.data || {};
97
+ var tmpCounters = tmpData.counter || [];
98
+
99
+ if (tmpCounters.length > 0)
100
+ {
101
+ // Counter exists, increment it
102
+ var tmpCurrentSeq = tmpCounters[0]['MeadowCounter.sequence'] || 0;
103
+ var tmpNextSeq = tmpCurrentSeq + 1;
104
+ var tmpUid = tmpCounters[0].uid;
105
+
106
+ var tmpMutation = {
107
+ setJson: {
108
+ uid: tmpUid,
109
+ 'MeadowCounter.sequence': tmpNextSeq
110
+ }
111
+ };
112
+
113
+ return tmpTxn.mutate(tmpMutation)
114
+ .then(function ()
115
+ {
116
+ return tmpTxn.commit();
117
+ })
118
+ .then(function ()
119
+ {
120
+ return fCallback(null, tmpNextSeq);
121
+ });
122
+ }
123
+ else
124
+ {
125
+ // Create new counter with sequence=1
126
+ var tmpMutation = {
127
+ setJson: {
128
+ 'dgraph.type': 'MeadowCounter',
129
+ 'MeadowCounter.scope': tmpCounterKey,
130
+ 'MeadowCounter.sequence': 1
131
+ }
132
+ };
133
+
134
+ return tmpTxn.mutate(tmpMutation)
135
+ .then(function ()
136
+ {
137
+ return tmpTxn.commit();
138
+ })
139
+ .then(function ()
140
+ {
141
+ return fCallback(null, 1);
142
+ });
143
+ }
144
+ })
145
+ .catch(function (pError)
146
+ {
147
+ try { tmpTxn.discard(); } catch(e) {}
148
+ return fCallback(pError);
149
+ });
150
+ };
151
+
152
+ // The Meadow marshaller also passes in the Schema as the third parameter
153
+ var marshalRecordFromSourceToObject = function (pObject, pRecord)
154
+ {
155
+ for (var tmpColumn in pRecord)
156
+ {
157
+ // Skip DGraph internal fields
158
+ if (tmpColumn === 'uid' || tmpColumn === 'dgraph.type')
159
+ {
160
+ continue;
161
+ }
162
+ // Strip scope prefix from DGraph predicate names (e.g. "FableTest.IDAnimal" → "IDAnimal")
163
+ var tmpFieldName = tmpColumn;
164
+ var tmpDotIndex = tmpFieldName.indexOf('.');
165
+ if (tmpDotIndex >= 0)
166
+ {
167
+ tmpFieldName = tmpFieldName.substring(tmpDotIndex + 1);
168
+ }
169
+ pObject[tmpFieldName] = pRecord[tmpColumn];
170
+ }
171
+ };
172
+
173
+ var Create = function (pQuery, fCallback)
174
+ {
175
+ var tmpResult = pQuery.parameters.result;
176
+
177
+ pQuery.setDialect('DGraph').buildCreateQuery();
178
+
179
+ if (pQuery.logLevel > 0 ||
180
+ _GlobalLogLevel > 0)
181
+ {
182
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
183
+ }
184
+
185
+ var tmpClient = getClient();
186
+ if (!tmpClient)
187
+ {
188
+ tmpResult.error = new Error('No DGraph connection available.');
189
+ tmpResult.executed = true;
190
+ return fCallback();
191
+ }
192
+
193
+ var tmpOp = pQuery.query.parameters.dgraphOperation;
194
+ if (!tmpOp)
195
+ {
196
+ tmpResult.error = new Error('No DGraph operation generated.');
197
+ tmpResult.executed = true;
198
+ return fCallback();
199
+ }
200
+
201
+ var tmpDocument = replaceSentinels(JSON.parse(JSON.stringify(tmpOp.document)));
202
+
203
+ // Check for $$AUTOINCREMENT sentinel
204
+ var tmpAutoIncrementColumn = false;
205
+ for (var tmpKey in tmpDocument)
206
+ {
207
+ if (tmpDocument[tmpKey] === '$$AUTOINCREMENT')
208
+ {
209
+ tmpAutoIncrementColumn = tmpKey;
210
+ break;
211
+ }
212
+ }
213
+
214
+ if (tmpAutoIncrementColumn)
215
+ {
216
+ // Get next sequence, then insert
217
+ getNextSequence(tmpClient, tmpOp.type, tmpAutoIncrementColumn, function (pSeqError, pSeqValue)
218
+ {
219
+ if (pSeqError)
220
+ {
221
+ tmpResult.error = pSeqError;
222
+ tmpResult.value = false;
223
+ tmpResult.executed = true;
224
+ return fCallback();
225
+ }
226
+
227
+ tmpDocument[tmpAutoIncrementColumn] = pSeqValue;
228
+
229
+ var tmpTxn = tmpClient.newTxn();
230
+ tmpTxn.mutate({ setJson: tmpDocument })
231
+ .then(function ()
232
+ {
233
+ return tmpTxn.commit();
234
+ })
235
+ .then(function ()
236
+ {
237
+ tmpResult.error = null;
238
+ tmpResult.value = pSeqValue;
239
+ tmpResult.executed = true;
240
+ return fCallback();
241
+ })
242
+ .catch(function (pError)
243
+ {
244
+ try { tmpTxn.discard(); } catch(e) {}
245
+ tmpResult.error = pError;
246
+ tmpResult.value = false;
247
+ tmpResult.executed = true;
248
+ return fCallback();
249
+ });
250
+ });
251
+ }
252
+ else
253
+ {
254
+ var tmpTxn = tmpClient.newTxn();
255
+ tmpTxn.mutate({ setJson: tmpDocument })
256
+ .then(function (pMutateResult)
257
+ {
258
+ return tmpTxn.commit()
259
+ .then(function ()
260
+ {
261
+ tmpResult.error = null;
262
+ // Return the assigned UID(s)
263
+ var tmpUids = pMutateResult.data && pMutateResult.data.uids;
264
+ tmpResult.value = tmpUids ? tmpUids[Object.keys(tmpUids)[0]] : true;
265
+ tmpResult.executed = true;
266
+ return fCallback();
267
+ });
268
+ })
269
+ .catch(function (pError)
270
+ {
271
+ try { tmpTxn.discard(); } catch(e) {}
272
+ tmpResult.error = pError;
273
+ tmpResult.value = false;
274
+ tmpResult.executed = true;
275
+ return fCallback();
276
+ });
277
+ }
278
+ };
279
+
280
+ var Read = function (pQuery, fCallback)
281
+ {
282
+ var tmpResult = pQuery.parameters.result;
283
+
284
+ pQuery.setDialect('DGraph').buildReadQuery();
285
+
286
+ if (pQuery.logLevel > 0 ||
287
+ _GlobalLogLevel > 0)
288
+ {
289
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
290
+ }
291
+
292
+ var tmpClient = getClient();
293
+ if (!tmpClient)
294
+ {
295
+ tmpResult.error = new Error('No DGraph connection available.');
296
+ tmpResult.executed = true;
297
+ return fCallback();
298
+ }
299
+
300
+ var tmpOp = pQuery.query.parameters.dgraphOperation;
301
+ var tmpTxn = tmpClient.newTxn({ readOnly: true });
302
+
303
+ tmpTxn.query(tmpOp.query)
304
+ .then(function (pResponse)
305
+ {
306
+ var tmpData = pResponse.data || {};
307
+ tmpResult.error = null;
308
+ tmpResult.value = tmpData[tmpOp.queryName] || [];
309
+ tmpResult.executed = true;
310
+ return fCallback();
311
+ })
312
+ .catch(function (pError)
313
+ {
314
+ tmpResult.error = pError;
315
+ tmpResult.value = false;
316
+ tmpResult.executed = true;
317
+ return fCallback();
318
+ });
319
+ };
320
+
321
+ var Update = function (pQuery, fCallback)
322
+ {
323
+ var tmpResult = pQuery.parameters.result;
324
+
325
+ pQuery.setDialect('DGraph').buildUpdateQuery();
326
+
327
+ if (pQuery.logLevel > 0 ||
328
+ _GlobalLogLevel > 0)
329
+ {
330
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
331
+ }
332
+
333
+ var tmpClient = getClient();
334
+ if (!tmpClient)
335
+ {
336
+ tmpResult.error = new Error('No DGraph connection available.');
337
+ tmpResult.executed = true;
338
+ return fCallback();
339
+ }
340
+
341
+ var tmpOp = pQuery.query.parameters.dgraphOperation;
342
+ if (!tmpOp)
343
+ {
344
+ tmpResult.error = new Error('No DGraph operation generated.');
345
+ tmpResult.executed = true;
346
+ return fCallback();
347
+ }
348
+
349
+ // First query for matching UIDs
350
+ var tmpReadTxn = tmpClient.newTxn({ readOnly: true });
351
+ tmpReadTxn.query(tmpOp.queryForUIDs)
352
+ .then(function (pResponse)
353
+ {
354
+ var tmpData = pResponse.data || {};
355
+ var tmpNodes = tmpData[tmpOp.queryName] || [];
356
+
357
+ if (tmpNodes.length === 0)
358
+ {
359
+ tmpResult.error = null;
360
+ tmpResult.value = 0;
361
+ tmpResult.executed = true;
362
+ return fCallback();
363
+ }
364
+
365
+ // Build mutation: set updated fields on each matching UID
366
+ var tmpUpdateDoc = replaceSentinels(JSON.parse(JSON.stringify(tmpOp.update)));
367
+ var tmpMutations = [];
368
+ for (var i = 0; i < tmpNodes.length; i++)
369
+ {
370
+ var tmpSetDoc = JSON.parse(JSON.stringify(tmpUpdateDoc));
371
+ tmpSetDoc.uid = tmpNodes[i].uid;
372
+ tmpMutations.push(tmpSetDoc);
373
+ }
374
+
375
+ var tmpWriteTxn = tmpClient.newTxn();
376
+ tmpWriteTxn.mutate({ setJson: tmpMutations })
377
+ .then(function ()
378
+ {
379
+ return tmpWriteTxn.commit();
380
+ })
381
+ .then(function ()
382
+ {
383
+ tmpResult.error = null;
384
+ tmpResult.value = tmpMutations;
385
+ tmpResult.executed = true;
386
+ return fCallback();
387
+ })
388
+ .catch(function (pError)
389
+ {
390
+ try { tmpWriteTxn.discard(); } catch(e) {}
391
+ tmpResult.error = pError;
392
+ tmpResult.value = false;
393
+ tmpResult.executed = true;
394
+ return fCallback();
395
+ });
396
+ })
397
+ .catch(function (pError)
398
+ {
399
+ tmpResult.error = pError;
400
+ tmpResult.value = false;
401
+ tmpResult.executed = true;
402
+ return fCallback();
403
+ });
404
+ };
405
+
406
+ var Delete = function (pQuery, fCallback)
407
+ {
408
+ var tmpResult = pQuery.parameters.result;
409
+
410
+ pQuery.setDialect('DGraph').buildDeleteQuery();
411
+
412
+ if (pQuery.logLevel > 0 ||
413
+ _GlobalLogLevel > 0)
414
+ {
415
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
416
+ }
417
+
418
+ var tmpClient = getClient();
419
+ if (!tmpClient)
420
+ {
421
+ tmpResult.error = new Error('No DGraph connection available.');
422
+ tmpResult.executed = true;
423
+ return fCallback();
424
+ }
425
+
426
+ var tmpOp = pQuery.query.parameters.dgraphOperation;
427
+
428
+ // First query for matching UIDs
429
+ var tmpReadTxn = tmpClient.newTxn({ readOnly: true });
430
+ tmpReadTxn.query(tmpOp.queryForUIDs)
431
+ .then(function (pResponse)
432
+ {
433
+ var tmpData = pResponse.data || {};
434
+ var tmpNodes = tmpData[tmpOp.queryName] || [];
435
+
436
+ if (tmpNodes.length === 0)
437
+ {
438
+ tmpResult.error = null;
439
+ tmpResult.value = 0;
440
+ tmpResult.executed = true;
441
+ return fCallback();
442
+ }
443
+
444
+ if (tmpOp.operation === 'upsert')
445
+ {
446
+ // Soft delete: update matching nodes with delete setters
447
+ var tmpUpdateDoc = replaceSentinels(JSON.parse(JSON.stringify(tmpOp.update)));
448
+ var tmpMutations = [];
449
+ for (var i = 0; i < tmpNodes.length; i++)
450
+ {
451
+ var tmpSetDoc = JSON.parse(JSON.stringify(tmpUpdateDoc));
452
+ tmpSetDoc.uid = tmpNodes[i].uid;
453
+ tmpMutations.push(tmpSetDoc);
454
+ }
455
+
456
+ var tmpWriteTxn = tmpClient.newTxn();
457
+ tmpWriteTxn.mutate({ setJson: tmpMutations })
458
+ .then(function ()
459
+ {
460
+ return tmpWriteTxn.commit();
461
+ })
462
+ .then(function ()
463
+ {
464
+ tmpResult.error = null;
465
+ tmpResult.value = tmpNodes.length;
466
+ tmpResult.executed = true;
467
+ return fCallback();
468
+ })
469
+ .catch(function (pError)
470
+ {
471
+ try { tmpWriteTxn.discard(); } catch(e) {}
472
+ tmpResult.error = pError;
473
+ tmpResult.value = false;
474
+ tmpResult.executed = true;
475
+ return fCallback();
476
+ });
477
+ }
478
+ else
479
+ {
480
+ // Hard delete: delete the nodes
481
+ var tmpDeleteDocs = [];
482
+ for (var j = 0; j < tmpNodes.length; j++)
483
+ {
484
+ tmpDeleteDocs.push({ uid: tmpNodes[j].uid });
485
+ }
486
+
487
+ var tmpWriteTxn = tmpClient.newTxn();
488
+ tmpWriteTxn.mutate({ deleteJson: tmpDeleteDocs })
489
+ .then(function ()
490
+ {
491
+ return tmpWriteTxn.commit();
492
+ })
493
+ .then(function ()
494
+ {
495
+ tmpResult.error = null;
496
+ tmpResult.value = tmpNodes.length;
497
+ tmpResult.executed = true;
498
+ return fCallback();
499
+ })
500
+ .catch(function (pError)
501
+ {
502
+ try { tmpWriteTxn.discard(); } catch(e) {}
503
+ tmpResult.error = pError;
504
+ tmpResult.value = false;
505
+ tmpResult.executed = true;
506
+ return fCallback();
507
+ });
508
+ }
509
+ })
510
+ .catch(function (pError)
511
+ {
512
+ tmpResult.error = pError;
513
+ tmpResult.value = false;
514
+ tmpResult.executed = true;
515
+ return fCallback();
516
+ });
517
+ };
518
+
519
+ var Undelete = function (pQuery, fCallback)
520
+ {
521
+ var tmpResult = pQuery.parameters.result;
522
+
523
+ pQuery.setDialect('DGraph').buildUndeleteQuery();
524
+
525
+ if (pQuery.logLevel > 0 ||
526
+ _GlobalLogLevel > 0)
527
+ {
528
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
529
+ }
530
+
531
+ var tmpClient = getClient();
532
+ if (!tmpClient)
533
+ {
534
+ tmpResult.error = new Error('No DGraph connection available.');
535
+ tmpResult.executed = true;
536
+ return fCallback();
537
+ }
538
+
539
+ var tmpOp = pQuery.query.parameters.dgraphOperation;
540
+ if (!tmpOp || tmpOp.operation === 'noop')
541
+ {
542
+ tmpResult.error = null;
543
+ tmpResult.value = 0;
544
+ tmpResult.executed = true;
545
+ return fCallback();
546
+ }
547
+
548
+ // Query for matching UIDs
549
+ var tmpReadTxn = tmpClient.newTxn({ readOnly: true });
550
+ tmpReadTxn.query(tmpOp.queryForUIDs)
551
+ .then(function (pResponse)
552
+ {
553
+ var tmpData = pResponse.data || {};
554
+ var tmpNodes = tmpData[tmpOp.queryName] || [];
555
+
556
+ if (tmpNodes.length === 0)
557
+ {
558
+ tmpResult.error = null;
559
+ tmpResult.value = 0;
560
+ tmpResult.executed = true;
561
+ return fCallback();
562
+ }
563
+
564
+ var tmpUpdateDoc = replaceSentinels(JSON.parse(JSON.stringify(tmpOp.update)));
565
+ var tmpMutations = [];
566
+ for (var i = 0; i < tmpNodes.length; i++)
567
+ {
568
+ var tmpSetDoc = JSON.parse(JSON.stringify(tmpUpdateDoc));
569
+ tmpSetDoc.uid = tmpNodes[i].uid;
570
+ tmpMutations.push(tmpSetDoc);
571
+ }
572
+
573
+ var tmpWriteTxn = tmpClient.newTxn();
574
+ tmpWriteTxn.mutate({ setJson: tmpMutations })
575
+ .then(function ()
576
+ {
577
+ return tmpWriteTxn.commit();
578
+ })
579
+ .then(function ()
580
+ {
581
+ tmpResult.error = null;
582
+ tmpResult.value = tmpNodes.length;
583
+ tmpResult.executed = true;
584
+ return fCallback();
585
+ })
586
+ .catch(function (pError)
587
+ {
588
+ try { tmpWriteTxn.discard(); } catch(e) {}
589
+ tmpResult.error = pError;
590
+ tmpResult.value = false;
591
+ tmpResult.executed = true;
592
+ return fCallback();
593
+ });
594
+ })
595
+ .catch(function (pError)
596
+ {
597
+ tmpResult.error = pError;
598
+ tmpResult.value = false;
599
+ tmpResult.executed = true;
600
+ return fCallback();
601
+ });
602
+ };
603
+
604
+ var Count = function (pQuery, fCallback)
605
+ {
606
+ var tmpResult = pQuery.parameters.result;
607
+
608
+ pQuery.setDialect('DGraph').buildCountQuery();
609
+
610
+ if (pQuery.logLevel > 0 ||
611
+ _GlobalLogLevel > 0)
612
+ {
613
+ _Fable.log.trace(pQuery.query.body, pQuery.query.parameters);
614
+ }
615
+
616
+ var tmpClient = getClient();
617
+ if (!tmpClient)
618
+ {
619
+ tmpResult.error = new Error('No DGraph connection available.');
620
+ tmpResult.executed = true;
621
+ return fCallback();
622
+ }
623
+
624
+ var tmpOp = pQuery.query.parameters.dgraphOperation;
625
+ var tmpTxn = tmpClient.newTxn({ readOnly: true });
626
+
627
+ tmpTxn.query(tmpOp.query)
628
+ .then(function (pResponse)
629
+ {
630
+ var tmpData = pResponse.data || {};
631
+ var tmpResults = tmpData[tmpOp.queryName] || [];
632
+ tmpResult.error = null;
633
+
634
+ if (tmpResults.length > 0 && typeof tmpResults[0].total !== 'undefined')
635
+ {
636
+ tmpResult.value = tmpResults[0].total;
637
+ }
638
+ else
639
+ {
640
+ tmpResult.value = 0;
641
+ }
642
+
643
+ tmpResult.executed = true;
644
+ return fCallback();
645
+ })
646
+ .catch(function (pError)
647
+ {
648
+ tmpResult.error = pError;
649
+ tmpResult.value = false;
650
+ tmpResult.executed = true;
651
+ return fCallback();
652
+ });
653
+ };
654
+
655
+ var tmpNewProvider = (
656
+ {
657
+ marshalRecordFromSourceToObject: marshalRecordFromSourceToObject,
658
+
659
+ Create: Create,
660
+ Read: Read,
661
+ Update: Update,
662
+ Delete: Delete,
663
+ Undelete: Undelete,
664
+ Count: Count,
665
+
666
+ getProvider: getProvider,
667
+ providerCreatesSupported: true,
668
+
669
+ new: createNew
670
+ });
671
+
672
+
673
+ return tmpNewProvider;
674
+ }
675
+
676
+ return createNew();
677
+ };
678
+
679
+ module.exports = new MeadowProvider();