meadow 2.0.22 → 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 +44 -27
  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,661 @@
1
+ /**
2
+ * Unit tests for the Meadow "MongoDB" Provider
3
+ *
4
+ * These tests expect a MongoDB database.....
5
+ *
6
+ * @license MIT
7
+ *
8
+ * @author Steven Velozo <steven@velozo.com>
9
+ */
10
+
11
+ var Chai = require("chai");
12
+ var Expect = Chai.expect;
13
+
14
+ const libMeadowConnectionMongoDB = require('meadow-connection-mongodb');
15
+
16
+ var tmpFableSettings = (
17
+ {
18
+ "Product": "MeadowMongoDBTestBookstore",
19
+ "ProductVersion": "1.0.0",
20
+
21
+ "UUID":
22
+ {
23
+ "DataCenter": 0,
24
+ "Worker": 0
25
+ },
26
+ "LogStreams":
27
+ [
28
+ {
29
+ "streamtype": "console"
30
+ }
31
+ ],
32
+
33
+ "MongoDB":
34
+ {
35
+ "Server": "127.0.0.1",
36
+ "Port": 37017,
37
+ "Database": "meadow_test",
38
+ "ConnectionPoolLimit": 20
39
+ }
40
+ });
41
+
42
+ var libFable = new (require('fable'))(tmpFableSettings);
43
+
44
+ libFable.serviceManager.addServiceType('MeadowMongoDBProvider', libMeadowConnectionMongoDB);
45
+ libFable.serviceManager.instantiateServiceProvider('MeadowMongoDBProvider');
46
+
47
+ var _AnimalJsonSchema = (
48
+ {
49
+ title: "Animal",
50
+ description: "A creature that lives in a meadow.",
51
+ type: "object",
52
+ properties: {
53
+ IDAnimal: {
54
+ description: "The unique identifier for an animal",
55
+ type: "integer"
56
+ },
57
+ Name: {
58
+ description: "The animal's name",
59
+ type: "string"
60
+ },
61
+ Type: {
62
+ description: "The type of the animal",
63
+ type: "string"
64
+ }
65
+ },
66
+ required: ["IDAnimal", "Name", "CreatingIDUser"]
67
+ });
68
+ var _AnimalSchema = (
69
+ [
70
+ { Column: "IDAnimal", Type: "AutoIdentity" },
71
+ { Column: "GUIDAnimal", Type: "AutoGUID" },
72
+ { Column: "CreateDate", Type: "CreateDate" },
73
+ { Column: "CreatingIDUser", Type: "CreateIDUser" },
74
+ { Column: "UpdateDate", Type: "UpdateDate" },
75
+ { Column: "UpdatingIDUser", Type: "UpdateIDUser" },
76
+ { Column: "Deleted", Type: "Deleted" },
77
+ { Column: "DeletingIDUser", Type: "DeleteIDUser" },
78
+ { Column: "DeleteDate", Type: "DeleteDate" },
79
+ { Column: "Name", Type: "String" },
80
+ { Column: "Type", Type: "String" }
81
+ ]);
82
+ var _AnimalDefault = (
83
+ {
84
+ IDAnimal: null,
85
+ GUIDAnimal: '',
86
+
87
+ CreateDate: false,
88
+ CreatingIDUser: 0,
89
+ UpdateDate: false,
90
+ UpdatingIDUser: 0,
91
+ Deleted: 0,
92
+ DeleteDate: false,
93
+ DeletingIDUser: 0,
94
+
95
+ Name: 'Unknown',
96
+ Type: 'Unclassified'
97
+ });
98
+
99
+ suite
100
+ (
101
+ 'Meadow-Provider-MongoDB',
102
+ function ()
103
+ {
104
+ var _SpooledUp = false;
105
+
106
+ var newMeadow = function ()
107
+ {
108
+ return require('../source/Meadow.js')
109
+ .new(libFable, 'FableTest')
110
+ .setProvider('MongoDB')
111
+ .setSchema(_AnimalSchema)
112
+ .setJsonSchema(_AnimalJsonSchema)
113
+ .setDefaultIdentifier('IDAnimal')
114
+ .setDefault(_AnimalDefault)
115
+ };
116
+
117
+ suiteSetup
118
+ (
119
+ function (fDone)
120
+ {
121
+ this.timeout(30000);
122
+ if (!_SpooledUp)
123
+ {
124
+ libFable.MeadowMongoDBProvider.connectAsync(
125
+ (pError) =>
126
+ {
127
+ if (pError)
128
+ {
129
+ libFable.log.error(`Error connecting to MongoDB: ${pError}`);
130
+ return fDone(pError);
131
+ }
132
+
133
+ var tmpDB = libFable.MeadowMongoDBProvider.pool;
134
+
135
+ // Drop existing collections and seed data
136
+ tmpDB.collection('FableTest').drop()
137
+ .catch(() => { /* collection may not exist */ })
138
+ .then(() =>
139
+ {
140
+ return tmpDB.collection('_meadow_counters').drop()
141
+ .catch(() => { /* collection may not exist */ });
142
+ })
143
+ .then(() =>
144
+ {
145
+ // Seed the counter so auto-increment starts at 6
146
+ return tmpDB.collection('_meadow_counters').insertOne(
147
+ { _id: 'FableTest.IDAnimal', seq: 5 });
148
+ })
149
+ .then(() =>
150
+ {
151
+ var tmpNow = new Date();
152
+ // Seed 5 animals matching the standard test data
153
+ return tmpDB.collection('FableTest').insertMany([
154
+ { IDAnimal: 1, GUIDAnimal: '00000000-0000-0000-0000-000000000000', CreateDate: tmpNow, CreatingIDUser: 1, UpdateDate: tmpNow, UpdatingIDUser: 1, Deleted: 0, DeleteDate: null, DeletingIDUser: 0, Name: 'Foo Foo', Type: 'Bunny' },
155
+ { IDAnimal: 2, GUIDAnimal: '00000000-0000-0000-0000-000000000000', CreateDate: tmpNow, CreatingIDUser: 1, UpdateDate: tmpNow, UpdatingIDUser: 1, Deleted: 0, DeleteDate: null, DeletingIDUser: 0, Name: 'Red Riding Hood', Type: 'Girl' },
156
+ { IDAnimal: 3, GUIDAnimal: '00000000-0000-0000-0000-000000000000', CreateDate: tmpNow, CreatingIDUser: 1, UpdateDate: tmpNow, UpdatingIDUser: 1, Deleted: 0, DeleteDate: null, DeletingIDUser: 0, Name: 'Red', Type: 'Dog' },
157
+ { IDAnimal: 4, GUIDAnimal: '00000000-0000-0000-0000-000000000000', CreateDate: tmpNow, CreatingIDUser: 1, UpdateDate: tmpNow, UpdatingIDUser: 1, Deleted: 0, DeleteDate: null, DeletingIDUser: 0, Name: 'Spot', Type: 'Dog' },
158
+ { IDAnimal: 5, GUIDAnimal: '00000000-0000-0000-0000-000000000000', CreateDate: tmpNow, CreatingIDUser: 1, UpdateDate: tmpNow, UpdatingIDUser: 1, Deleted: 0, DeleteDate: null, DeletingIDUser: 0, Name: 'Gertrude', Type: 'Frog' }
159
+ ]);
160
+ })
161
+ .then(() =>
162
+ {
163
+ _SpooledUp = true;
164
+ fDone();
165
+ })
166
+ .catch(fDone);
167
+ }
168
+ );
169
+ }
170
+ else
171
+ {
172
+ fDone();
173
+ }
174
+ }
175
+ );
176
+
177
+ suiteTeardown((fDone) =>
178
+ {
179
+ if (libFable.MeadowMongoDBProvider && libFable.MeadowMongoDBProvider.client)
180
+ {
181
+ var tmpDB = libFable.MeadowMongoDBProvider.pool;
182
+ tmpDB.collection('FableTest').drop()
183
+ .catch(() => {})
184
+ .then(() => tmpDB.collection('_meadow_counters').drop().catch(() => {}))
185
+ .then(() => libFable.MeadowMongoDBProvider.client.close())
186
+ .then(() => fDone())
187
+ .catch(fDone);
188
+ }
189
+ else
190
+ {
191
+ fDone();
192
+ }
193
+ });
194
+
195
+ suite
196
+ (
197
+ 'Object Sanity',
198
+ function ()
199
+ {
200
+ test
201
+ (
202
+ 'The MongoDB class should initialize itself into a happy little object.',
203
+ function ()
204
+ {
205
+ var testMeadow = require('../source/Meadow.js').new(libFable).setProvider('MongoDB');
206
+ Expect(testMeadow).to.be.an('object', 'Meadow should initialize as an object directly from the require statement.');
207
+ }
208
+ );
209
+ }
210
+ );
211
+ suite
212
+ (
213
+ 'Query Processing',
214
+ function ()
215
+ {
216
+ test
217
+ (
218
+ 'Create a record in the database',
219
+ function (fDone)
220
+ {
221
+ var testMeadow = newMeadow().setIDUser(90210);
222
+
223
+ var tmpQuery = testMeadow.query.clone().setLogLevel(5)
224
+ .addRecord({ Name: 'Blastoise', Type: 'Pokemon' });
225
+
226
+ testMeadow.doCreate(tmpQuery,
227
+ function (pError, pQuery, pQueryRead, pRecord)
228
+ {
229
+ // We should have a record ....
230
+ Expect(pRecord.Name)
231
+ .to.equal('Blastoise');
232
+ Expect(pRecord.CreatingIDUser)
233
+ .to.equal(90210);
234
+ fDone();
235
+ }
236
+ )
237
+ }
238
+ );
239
+ test
240
+ (
241
+ 'Read a record from the database',
242
+ function (fDone)
243
+ {
244
+ var testMeadow = newMeadow();
245
+
246
+ var tmpQuery = testMeadow.query
247
+ .addFilter('IDAnimal', 1);
248
+
249
+ testMeadow.doRead(tmpQuery,
250
+ function (pError, pQuery, pRecord)
251
+ {
252
+ // We should have a record ....
253
+ Expect(pRecord.IDAnimal)
254
+ .to.equal(1);
255
+ Expect(pRecord.Name)
256
+ .to.equal('Foo Foo');
257
+ fDone();
258
+ }
259
+ )
260
+ }
261
+ );
262
+ test
263
+ (
264
+ 'Read all records from the database',
265
+ function (fDone)
266
+ {
267
+ var testMeadow = newMeadow();
268
+
269
+ testMeadow.doReads(testMeadow.query.addSort({Column: 'IDAnimal'}),
270
+ function (pError, pQuery, pRecords)
271
+ {
272
+ // We should have records ....
273
+ Expect(pRecords[0].IDAnimal)
274
+ .to.equal(1);
275
+ Expect(pRecords[0].Name)
276
+ .to.equal('Foo Foo');
277
+ Expect(pRecords[1].IDAnimal)
278
+ .to.equal(2);
279
+ Expect(pRecords[1].Name)
280
+ .to.equal('Red Riding Hood');
281
+ fDone();
282
+ }
283
+ )
284
+ }
285
+ );
286
+ test
287
+ (
288
+ 'Update a record in the database',
289
+ function (fDone)
290
+ {
291
+ var testMeadow = newMeadow();
292
+
293
+ var tmpQuery = testMeadow.query
294
+ .addRecord({ IDAnimal: 2, Type: 'Human' });
295
+
296
+ testMeadow.doUpdate(tmpQuery,
297
+ function (pError, pQuery, pQueryRead, pRecord)
298
+ {
299
+ // We should have a record ....
300
+ Expect(pRecord.Type)
301
+ .to.equal('Human');
302
+ fDone();
303
+ }
304
+ )
305
+ }
306
+ );
307
+ test
308
+ (
309
+ 'Delete a record in the database',
310
+ function (fDone)
311
+ {
312
+ var testMeadow = newMeadow();
313
+
314
+ var tmpQuery = testMeadow.query.addFilter('IDAnimal', 3);
315
+
316
+ testMeadow.doDelete(tmpQuery,
317
+ function (pError, pQuery, pRecord)
318
+ {
319
+ // It returns the number of rows deleted
320
+ Expect(pRecord)
321
+ .to.equal(1);
322
+ fDone();
323
+ }
324
+ )
325
+ }
326
+ );
327
+ test
328
+ (
329
+ 'Undelete a record in the database',
330
+ function (fDone)
331
+ {
332
+ var testMeadow = newMeadow();
333
+
334
+ var tmpDeleteQuery = testMeadow.query.addFilter('IDAnimal', 5);
335
+
336
+ // Make sure the record is deleted!
337
+ testMeadow.doDelete(tmpDeleteQuery,
338
+ function (pDeleteError, pDeleteQuery, pDeleteRecord)
339
+ {
340
+ var tmpQuery = testMeadow.query.addFilter('IDAnimal', 5);
341
+ testMeadow.doUndelete(tmpQuery,
342
+ function (pError, pQuery, pRecord)
343
+ {
344
+ // It returns the number of rows undeleted
345
+ Expect(pRecord)
346
+ .to.equal(1);
347
+ fDone();
348
+ });
349
+ });
350
+ }
351
+ );
352
+ test
353
+ (
354
+ 'Count all records from the database',
355
+ function (fDone)
356
+ {
357
+ var testMeadow = newMeadow();
358
+
359
+ Expect(testMeadow.query.parameters.result.executed)
360
+ .to.equal(false);
361
+ testMeadow.doCount(testMeadow.query,
362
+ function (pError, pQuery, pRecord)
363
+ {
364
+ // There should be 5 records (5 seeded + 1 created - 1 deleted = 5 non-deleted)
365
+ Expect(pRecord)
366
+ .to.equal(5);
367
+ Expect(pQuery.parameters.result.executed)
368
+ .to.equal(true);
369
+ fDone();
370
+ }
371
+ )
372
+ }
373
+ );
374
+ }
375
+ );
376
+ suite
377
+ (
378
+ 'Logged Query Processing',
379
+ function ()
380
+ {
381
+ test
382
+ (
383
+ 'Create a record in the database',
384
+ function (fDone)
385
+ {
386
+ var testMeadow = newMeadow();
387
+
388
+ var tmpQuery = testMeadow.query
389
+ .setLogLevel(5)
390
+ .addRecord({ Name: 'MewTwo', Type: 'Pokemon' });
391
+
392
+ testMeadow.doCreate(tmpQuery,
393
+ function (pError, pQuery, pQueryRead, pRecord)
394
+ {
395
+ // We should have a record ....
396
+ Expect(pRecord.Name)
397
+ .to.equal('MewTwo');
398
+ fDone();
399
+ }
400
+ )
401
+ }
402
+ );
403
+ test
404
+ (
405
+ 'Read a record from the database',
406
+ function (fDone)
407
+ {
408
+ var testMeadow = newMeadow();
409
+
410
+ var tmpQuery = testMeadow.query
411
+ .setLogLevel(5)
412
+ .addFilter('IDAnimal', 1);
413
+
414
+ testMeadow.doRead(tmpQuery,
415
+ function (pError, pQuery, pRecord)
416
+ {
417
+ // We should have a record ....
418
+ Expect(pRecord.IDAnimal)
419
+ .to.equal(1);
420
+ Expect(pRecord.Name)
421
+ .to.equal('Foo Foo');
422
+ fDone();
423
+ }
424
+ )
425
+ }
426
+ );
427
+ test
428
+ (
429
+ 'Read all records from the database',
430
+ function (fDone)
431
+ {
432
+ var testMeadow = newMeadow();
433
+
434
+ testMeadow.doReads(testMeadow.query.setLogLevel(5).addSort({Column: 'IDAnimal'}),
435
+ function (pError, pQuery, pRecords)
436
+ {
437
+ // We should have records ....
438
+ Expect(pRecords[0].IDAnimal)
439
+ .to.equal(1);
440
+ Expect(pRecords[0].Name)
441
+ .to.equal('Foo Foo');
442
+ Expect(pRecords[1].IDAnimal)
443
+ .to.equal(2);
444
+ Expect(pRecords[1].Name)
445
+ .to.equal('Red Riding Hood');
446
+ Expect(pRecords[1].Type)
447
+ .to.equal('Human');
448
+ fDone();
449
+ }
450
+ )
451
+ }
452
+ );
453
+ test
454
+ (
455
+ 'Update a record in the database',
456
+ function (fDone)
457
+ {
458
+ var testMeadow = newMeadow();
459
+
460
+ var tmpQuery = testMeadow.query
461
+ .setLogLevel(5)
462
+ .addRecord({ IDAnimal: 2, Type: 'HumanGirl' });
463
+
464
+ testMeadow.doUpdate(tmpQuery,
465
+ function (pError, pQuery, pQueryRead, pRecord)
466
+ {
467
+ // We should have a record ....
468
+ Expect(pRecord.Type)
469
+ .to.equal('HumanGirl');
470
+ fDone();
471
+ }
472
+ )
473
+ }
474
+ );
475
+ test
476
+ (
477
+ 'Delete a record in the database',
478
+ function (fDone)
479
+ {
480
+ var testMeadow = newMeadow();
481
+
482
+ var tmpQuery = testMeadow.query
483
+ .setLogLevel(5)
484
+ .addFilter('IDAnimal', 4);
485
+
486
+ testMeadow.doDelete(tmpQuery,
487
+ function (pError, pQuery, pRecord)
488
+ {
489
+ // It returns the number of rows deleted
490
+ Expect(pRecord)
491
+ .to.equal(1);
492
+ fDone();
493
+ }
494
+ )
495
+ }
496
+ );
497
+ test
498
+ (
499
+ 'Count all records from the database',
500
+ function (fDone)
501
+ {
502
+ var testMeadow = newMeadow();
503
+
504
+ testMeadow.doCount(testMeadow.query.setLogLevel(5),
505
+ function (pError, pQuery, pRecord)
506
+ {
507
+ // MongoDB auto-filters Deleted=0, so count is non-deleted records only
508
+ Expect(pRecord)
509
+ .to.equal(5);
510
+ fDone();
511
+ }
512
+ )
513
+ }
514
+ );
515
+ test
516
+ (
517
+ 'Create a record in the database with a defined creating user',
518
+ function (fDone)
519
+ {
520
+ var testMeadow = newMeadow();
521
+ var tmpQuery = testMeadow.query
522
+ .setIDUser(800)
523
+ .addRecord({ Name: 'MewSix', GUIDAnimal: '0x123456', Type: 'Pokemon' });
524
+
525
+ testMeadow.doCreate(tmpQuery,
526
+ function (pError, pQuery, pQueryRead, pRecord)
527
+ {
528
+ // We should have a record ....
529
+ Expect(pRecord.Name)
530
+ .to.equal('MewSix');
531
+ Expect(pRecord.CreatingIDUser)
532
+ .to.equal(800);
533
+ fDone();
534
+ }
535
+ )
536
+ }
537
+ );
538
+ }
539
+ );
540
+ suite
541
+ (
542
+ 'The Bad Kind of Query Processing',
543
+ function ()
544
+ {
545
+ test
546
+ (
547
+ 'Create a record in the database with no record',
548
+ function (fDone)
549
+ {
550
+ var testMeadow = newMeadow().setDefaultIdentifier('Type');
551
+
552
+ testMeadow.doCreate(testMeadow.query,
553
+ function (pError, pQuery, pQueryRead, pRecord)
554
+ {
555
+ Expect(pError)
556
+ .to.equal('No record submitted');
557
+ fDone();
558
+ }
559
+ )
560
+ }
561
+ );
562
+ test
563
+ (
564
+ 'Read a record from the database with no data returned',
565
+ function (fDone)
566
+ {
567
+ var testMeadow = newMeadow();
568
+
569
+ var tmpQuery = testMeadow.query
570
+ .addFilter('IDAnimal', 5000);
571
+ testMeadow.doRead(tmpQuery,
572
+ function (pError, pQuery, pRecord)
573
+ {
574
+ Expect(pRecord)
575
+ .to.equal(false);
576
+ fDone();
577
+ }
578
+ )
579
+ }
580
+ );
581
+ test
582
+ (
583
+ 'Read records from the database with no data returned',
584
+ function (fDone)
585
+ {
586
+ var testMeadow = newMeadow();
587
+
588
+ var tmpQuery = testMeadow.query
589
+ .addFilter('IDAnimal', 5000);
590
+
591
+ testMeadow.doReads(tmpQuery,
592
+ function (pError, pQuery, pRecord)
593
+ {
594
+ Expect(pRecord.length)
595
+ .to.equal(0);
596
+ fDone();
597
+ }
598
+ )
599
+ }
600
+ );
601
+ test
602
+ (
603
+ 'Update a record in the database without passing a record in',
604
+ function (fDone)
605
+ {
606
+ var testMeadow = newMeadow();
607
+
608
+ testMeadow.doUpdate(testMeadow.query,
609
+ function (pError, pQuery, pQueryRead, pRecord)
610
+ {
611
+ Expect(pError)
612
+ .to.equal('No record submitted');
613
+ fDone();
614
+ }
615
+ )
616
+ }
617
+ );
618
+ test
619
+ (
620
+ 'Update a record in the database with a bad record passed in (no default identifier)',
621
+ function (fDone)
622
+ {
623
+ var testMeadow = newMeadow();
624
+
625
+ var tmpQuery = testMeadow.query
626
+ .addRecord({ Name: 'Bill' });
627
+
628
+ testMeadow.doUpdate(tmpQuery,
629
+ function (pError, pQuery, pQueryRead, pRecord)
630
+ {
631
+ Expect(pError)
632
+ .to.equal('Automated update missing default identifier');
633
+ fDone();
634
+ }
635
+ )
636
+ }
637
+ );
638
+ test
639
+ (
640
+ 'Update a record in the database that does not exist',
641
+ function (fDone)
642
+ {
643
+ var testMeadow = newMeadow();
644
+
645
+ var tmpQuery = testMeadow.query
646
+ .addRecord({ IDAnimal: 983924 });
647
+
648
+ testMeadow.doUpdate(tmpQuery,
649
+ function (pError, pQuery, pQueryRead, pRecord)
650
+ {
651
+ Expect(pError)
652
+ .to.equal('No record found to update!');
653
+ fDone();
654
+ }
655
+ )
656
+ }
657
+ );
658
+ }
659
+ );
660
+ }
661
+ );