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.
- package/README.md +110 -141
- package/docs/README.md +34 -230
- package/docs/_cover.md +14 -0
- package/docs/_sidebar.md +44 -12
- package/docs/_topbar.md +5 -0
- package/docs/api/doCount.md +109 -0
- package/docs/api/doCreate.md +132 -0
- package/docs/api/doDelete.md +101 -0
- package/docs/api/doRead.md +122 -0
- package/docs/api/doReads.md +136 -0
- package/docs/api/doUndelete.md +98 -0
- package/docs/api/doUpdate.md +129 -0
- package/docs/api/getRoleName.md +84 -0
- package/docs/api/loadFromPackage.md +153 -0
- package/docs/api/marshalRecordFromSourceToObject.md +92 -0
- package/docs/api/query.md +133 -0
- package/docs/api/rawQueries.md +197 -0
- package/docs/api/reference.md +117 -0
- package/docs/api/setAuthorizer.md +103 -0
- package/docs/api/setDefault.md +90 -0
- package/docs/api/setDefaultIdentifier.md +84 -0
- package/docs/api/setDomain.md +56 -0
- package/docs/api/setIDUser.md +91 -0
- package/docs/api/setJsonSchema.md +92 -0
- package/docs/api/setProvider.md +87 -0
- package/docs/api/setSchema.md +107 -0
- package/docs/api/setScope.md +68 -0
- package/docs/api/validateObject.md +119 -0
- package/docs/architecture.md +316 -0
- package/docs/audit-tracking.md +226 -0
- package/docs/configuration.md +317 -0
- package/docs/providers/meadow-endpoints.md +306 -0
- package/docs/providers/mongodb.md +319 -0
- package/docs/providers/postgresql.md +312 -0
- package/docs/providers/rocksdb.md +297 -0
- package/docs/query-dsl.md +269 -0
- package/docs/quick-start.md +384 -0
- package/docs/raw-queries.md +193 -0
- package/docs/retold-catalog.json +61 -1
- package/docs/retold-keyword-index.json +15860 -4839
- package/docs/soft-deletes.md +224 -0
- package/package.json +44 -27
- package/scripts/bookstore-seed-postgresql.sql +135 -0
- package/scripts/dgraph-test-db.sh +144 -0
- package/scripts/meadow-test-cleanup.sh +5 -1
- package/scripts/mongodb-test-db.sh +98 -0
- package/scripts/postgresql-test-db.sh +124 -0
- package/scripts/solr-test-db.sh +135 -0
- package/source/Meadow.js +5 -0
- package/source/providers/Meadow-Provider-DGraph.js +679 -0
- package/source/providers/Meadow-Provider-MongoDB.js +527 -0
- package/source/providers/Meadow-Provider-PostgreSQL.js +361 -0
- package/source/providers/Meadow-Provider-RocksDB.js +1300 -0
- package/source/providers/Meadow-Provider-Solr.js +726 -0
- package/test/Meadow-Provider-DGraph_tests.js +741 -0
- package/test/Meadow-Provider-MongoDB_tests.js +661 -0
- package/test/Meadow-Provider-PostgreSQL_tests.js +787 -0
- package/test/Meadow-Provider-RocksDB_tests.js +887 -0
- 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
|
+
);
|