meadow 2.0.4 → 2.0.6

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.
@@ -0,0 +1,1194 @@
1
+ /**
2
+ * Unit tests for the Meadow "MSSQL" Provider
3
+ *
4
+ * These tests expect a MSSQL 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
+ var libMSSQL = require('mssql');
15
+ var libAsyncWaterfall = require('async/waterfall');
16
+
17
+ var tmpFableSettings = (
18
+ {
19
+ "Product": "MeadowMSSQLTestBookstore",
20
+ "ProductVersion": "1.0.0",
21
+
22
+ "UUID":
23
+ {
24
+ "DataCenter": 0,
25
+ "Worker": 0
26
+ },
27
+ "LogStreams":
28
+ [
29
+ {
30
+ "streamtype": "console"
31
+ }
32
+ ],
33
+
34
+ "MSSQL":
35
+ {
36
+ "server": "127.0.0.1",
37
+ "port": 3306,
38
+ "user": "sa",
39
+ "password": "1234567890abc.",
40
+ "database": "bookstore",
41
+ "ConnectionPoolLimit": 20
42
+ }
43
+ });
44
+
45
+ var libFable = new (require('fable'))(tmpFableSettings);
46
+
47
+ var _SQLConnectionPool = false;
48
+
49
+
50
+ var _AnimalJsonSchema = (
51
+ {
52
+ title: "Animal",
53
+ description: "A creature that lives in a meadow.",
54
+ type: "object",
55
+ properties: {
56
+ IDAnimal: {
57
+ description: "The unique identifier for an animal",
58
+ type: "integer"
59
+ },
60
+ Name: {
61
+ description: "The animal's name",
62
+ type: "string"
63
+ },
64
+ Type: {
65
+ description: "The type of the animal",
66
+ type: "string"
67
+ }
68
+ },
69
+ required: ["IDAnimal", "Name", "CreatingIDUser"]
70
+ });
71
+ var _AnimalSchema = (
72
+ [
73
+ { Column: "IDAnimal", Type: "AutoIdentity" },
74
+ { Column: "GUIDAnimal", Type: "AutoGUID" },
75
+ { Column: "CreateDate", Type: "CreateDate" },
76
+ { Column: "CreatingIDUser", Type: "CreateIDUser" },
77
+ { Column: "UpdateDate", Type: "UpdateDate" },
78
+ { Column: "UpdatingIDUser", Type: "UpdateIDUser" },
79
+ { Column: "Deleted", Type: "Deleted" },
80
+ { Column: "DeletingIDUser", Type: "DeleteIDUser" },
81
+ { Column: "DeleteDate", Type: "DeleteDate" }
82
+ ]);
83
+ var _AnimalDefault = (
84
+ {
85
+ IDAnimal: null,
86
+ GUIDAnimal: '',
87
+
88
+ CreateDate: false,
89
+ CreatingIDUser: 0,
90
+ UpdateDate: false,
91
+ UpdatingIDUser: 0,
92
+ Deleted: 0,
93
+ DeleteDate: false,
94
+ DeletingIDUser: 0,
95
+
96
+ Name: 'Unknown',
97
+ Type: 'Unclassified'
98
+ });
99
+
100
+ suite
101
+ (
102
+ 'Meadow-Provider-MSSQL',
103
+ function ()
104
+ {
105
+ var _SpooledUp = false;
106
+
107
+ var getAnimalInsert = function (pName, pType)
108
+ {
109
+ return "INSERT INTO `FableTest` (`IDAnimal`, `GUIDAnimal`, `CreateDate`, `CreatingIDUser`, `UpdateDate`, `UpdatingIDUser`, `Deleted`, `DeleteDate`, `DeletingIDUser`, `Name`, `Type`) VALUES (NULL, '00000000-0000-0000-0000-000000000000', NOW(), 1, NOW(), 1, 0, NULL, 0, '" + pName + "', '" + pType + "'); ";
110
+ };
111
+
112
+ var newMeadow = function ()
113
+ {
114
+ return require('../source/Meadow.js')
115
+ .new(libFable, 'FableTest')
116
+ .setProvider('MSSQL')
117
+ .setSchema(_AnimalSchema)
118
+ .setJsonSchema(_AnimalJsonSchema)
119
+ .setDefaultIdentifier('IDAnimal')
120
+ .setDefault(_AnimalDefault)
121
+ };
122
+
123
+ suiteSetup
124
+ (
125
+ function (fDone)
126
+ {
127
+ // Only do this for the first test.
128
+ if (!_SpooledUp)
129
+ {
130
+ _SQLConnectionPool = libMSSQL.createPool
131
+ (
132
+ {
133
+ connectionLimit: tmpFableSettings.MSSQL.ConnectionPoolLimit,
134
+ host: tmpFableSettings.MSSQL.Server,
135
+ port: tmpFableSettings.MSSQL.Port,
136
+ user: tmpFableSettings.MSSQL.User,
137
+ password: tmpFableSettings.MSSQL.Password,
138
+ database: tmpFableSettings.MSSQL.Database
139
+ }
140
+ );
141
+
142
+ // Tear down previous test data
143
+ libAsyncWaterfall(
144
+ [
145
+ function (fCallBack)
146
+ {
147
+ _SQLConnectionPool.query('DROP TABLE IF EXISTS FableTest',
148
+ function (pErrorUpdate, pResponse) { fCallBack(null); });
149
+ },
150
+ function (fCallBack)
151
+ {
152
+ _SQLConnectionPool.query("CREATE TABLE IF NOT EXISTS FableTest (IDAnimal INT UNSIGNED NOT NULL AUTO_INCREMENT, GUIDAnimal CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', CreateDate DATETIME, CreatingIDUser INT NOT NULL DEFAULT '0', UpdateDate DATETIME, UpdatingIDUser INT NOT NULL DEFAULT '0', Deleted TINYINT NOT NULL DEFAULT '0', DeleteDate DATETIME, DeletingIDUser INT NOT NULL DEFAULT '0', Name CHAR(128) NOT NULL DEFAULT '', Type CHAR(128) NOT NULL DEFAULT '', PRIMARY KEY (IDAnimal) );",
153
+ function (pErrorUpdate, pResponse) { fCallBack(null); });
154
+ },
155
+ function (fCallBack)
156
+ {
157
+ _SQLConnectionPool.query(getAnimalInsert('Foo Foo', 'Bunny'),
158
+ function (pErrorUpdate, pResponse) { fCallBack(null); });
159
+ },
160
+ function (fCallBack)
161
+ {
162
+ _SQLConnectionPool.query(getAnimalInsert('Red Riding Hood', 'Girl'),
163
+ function (pErrorUpdate, pResponse) { fCallBack(null); });
164
+ },
165
+ function (fCallBack)
166
+ {
167
+ _SQLConnectionPool.query(getAnimalInsert('Red', 'Dog'),
168
+ function (pErrorUpdate, pResponse) { fCallBack(null); });
169
+ },
170
+ function (fCallBack)
171
+ {
172
+ _SQLConnectionPool.query(getAnimalInsert('Spot', 'Dog'),
173
+ function (pErrorUpdate, pResponse) { fCallBack(null); });
174
+ },
175
+ function (fCallBack)
176
+ {
177
+ _SQLConnectionPool.query(getAnimalInsert('Gertrude', 'Frog'),
178
+ function (pErrorUpdate, pResponse) { fCallBack(null); });
179
+ }
180
+ ],
181
+ function (pError, pResult)
182
+ {
183
+ // Now continue the tests.
184
+ _SpooledUp = true;
185
+ fDone();
186
+ }
187
+ );
188
+ }
189
+ else
190
+ {
191
+ fDone();
192
+ }
193
+ }
194
+ );
195
+
196
+ suiteTeardown((fDone) =>
197
+ {
198
+ _SQLConnectionPool.end(fDone);
199
+ }
200
+ );
201
+
202
+ suite
203
+ (
204
+ 'Object Sanity',
205
+ function ()
206
+ {
207
+ test
208
+ (
209
+ 'The MSSQL class should initialize itself into a happy little object.',
210
+ function ()
211
+ {
212
+ var testMeadow = require('../source/Meadow.js').new(libFable).setProvider('MSSQL');
213
+ Expect(testMeadow).to.be.an('object', 'Meadow should initialize as an object directly from the require statement.');
214
+ }
215
+ );
216
+ }
217
+ );
218
+ suite
219
+ (
220
+ 'Query Processing',
221
+ function ()
222
+ {
223
+ test
224
+ (
225
+ 'Create a record in the database',
226
+ function (fDone)
227
+ {
228
+ var testMeadow = newMeadow().setIDUser(90210);
229
+
230
+ // Ensure this query is "slow"...
231
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1;
232
+
233
+ var tmpQuery = testMeadow.query.clone().setLogLevel(5)
234
+ .addRecord({ Name: 'Blastoise', Type: 'Pokemon' });
235
+
236
+ testMeadow.doCreate(tmpQuery,
237
+ function (pError, pQuery, pQueryRead, pRecord)
238
+ {
239
+ // We should have a record ....
240
+ Expect(pRecord.Name)
241
+ .to.equal('Blastoise');
242
+ Expect(pRecord.CreatingIDUser)
243
+ .to.equal(90210);
244
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
245
+ fDone();
246
+ }
247
+ )
248
+ }
249
+ );
250
+ test
251
+ (
252
+ 'New provider format',
253
+ function (fDone)
254
+ {
255
+ let _FableClass = require('fable');
256
+ let _Fable = new _FableClass({
257
+ MSSQL:
258
+ {
259
+ // This is queued up for Travis defaults.
260
+ Server: "localhost",
261
+ Port: 3306,
262
+ User: "root",
263
+ Password: "123456789",
264
+ Database: "FableTest",
265
+ ConnectionPoolLimit: 20
266
+ },
267
+ MeadowConnectionMSSQLAutoConnect: true
268
+ });
269
+ _Fable.serviceManager.addAndInstantiateServiceType('MeadowMSSQLProvider', require('meadow-connection-mssql'));
270
+
271
+ var testMeadow = require('../source/Meadow.js')
272
+ .new(_Fable, 'FableTest')
273
+ .setProvider('MSSQL')
274
+ .setSchema(_AnimalSchema)
275
+ .setJsonSchema(_AnimalJsonSchema)
276
+ .setDefaultIdentifier('IDAnimal')
277
+ .setDefault(_AnimalDefault);
278
+
279
+ testMeadow.setIDUser(90210);
280
+
281
+ var tmpQuery = testMeadow.query.addFilter('IDAnimal', 1);
282
+
283
+ testMeadow.doRead(tmpQuery,
284
+ function (pError, pQuery, pRecord)
285
+ {
286
+ // We should have a record ....
287
+ Expect(pRecord.IDAnimal)
288
+ .to.equal(1);
289
+ Expect(pRecord.Name)
290
+ .to.equal('Foo Foo');
291
+
292
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
293
+
294
+ fDone();
295
+ }
296
+ )
297
+ }
298
+ );
299
+ test
300
+ (
301
+ 'Create a record in the database with Deleted bit already set',
302
+ function (fDone)
303
+ {
304
+ var testMeadow = newMeadow().setIDUser(90210);
305
+
306
+ var tmpQuery = testMeadow.query.clone().setLogLevel(5)
307
+ .setDisableDeleteTracking(true)
308
+ .addRecord({ Name: 'Blastoise', Type: 'Pokemon', Deleted: true });
309
+
310
+ testMeadow.doCreate(tmpQuery,
311
+ function (pError, pQuery, pQueryRead, pRecord)
312
+ {
313
+ // We should have a record ....
314
+ Expect(pRecord.Name)
315
+ .to.equal('Blastoise');
316
+ Expect(pRecord.CreatingIDUser)
317
+ .to.equal(90210);
318
+ fDone();
319
+ }
320
+ )
321
+ }
322
+ );
323
+ test
324
+ (
325
+ 'Read a record from the database',
326
+ function (fDone)
327
+ {
328
+ var testMeadow = newMeadow();
329
+
330
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1;
331
+
332
+ var tmpQuery = testMeadow.query
333
+ .addFilter('IDAnimal', 1);
334
+
335
+ testMeadow.doRead(tmpQuery,
336
+ function (pError, pQuery, pRecord)
337
+ {
338
+ // We should have a record ....
339
+ Expect(pRecord.IDAnimal)
340
+ .to.equal(1);
341
+ Expect(pRecord.Name)
342
+ .to.equal('Foo Foo');
343
+
344
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
345
+
346
+ fDone();
347
+ }
348
+ )
349
+ }
350
+ );
351
+ test
352
+ (
353
+ 'Read all records from the database',
354
+ function (fDone)
355
+ {
356
+ var testMeadow = newMeadow();
357
+
358
+ testMeadow.doReads(testMeadow.query,
359
+ function (pError, pQuery, pRecords)
360
+ {
361
+ // We should have a record ....
362
+ Expect(pRecords[0].IDAnimal)
363
+ .to.equal(1);
364
+ Expect(pRecords[0].Name)
365
+ .to.equal('Foo Foo');
366
+ Expect(pRecords[1].IDAnimal)
367
+ .to.equal(2);
368
+ Expect(pRecords[1].Name)
369
+ .to.equal('Red Riding Hood');
370
+ Expect(pRecords[1].Type)
371
+ .to.equal('Girl');
372
+ fDone();
373
+ }
374
+ )
375
+ }
376
+ );
377
+ test
378
+ (
379
+ 'Update a record in the database',
380
+ function (fDone)
381
+ {
382
+ var testMeadow = newMeadow();
383
+
384
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1;
385
+
386
+ var tmpQuery = testMeadow.query
387
+ .addRecord({ IDAnimal: 2, Type: 'Human' });
388
+
389
+ testMeadow.doUpdate(tmpQuery,
390
+ function (pError, pQuery, pQueryRead, pRecord)
391
+ {
392
+ // We should have a record ....
393
+ Expect(pRecord.Type)
394
+ .to.equal('Human');
395
+
396
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
397
+
398
+ fDone();
399
+ }
400
+ )
401
+ }
402
+ );
403
+ test
404
+ (
405
+ 'Delete a record in the database',
406
+ function (fDone)
407
+ {
408
+ var testMeadow = newMeadow();
409
+
410
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1;
411
+ var tmpQuery = testMeadow.query.addFilter('IDAnimal', 3);
412
+
413
+ testMeadow.doDelete(tmpQuery,
414
+ function (pError, pQuery, pRecord)
415
+ {
416
+ // It returns the number of rows deleted
417
+ Expect(pRecord)
418
+ .to.equal(1);
419
+
420
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
421
+
422
+ fDone();
423
+ }
424
+ )
425
+ }
426
+ );
427
+ test
428
+ (
429
+ 'Undelete a record in the database',
430
+ function (fDone)
431
+ {
432
+ var testMeadow = newMeadow();
433
+
434
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1;
435
+ var tmpDeleteQuery = testMeadow.query.addFilter('IDAnimal', 5);
436
+
437
+ // Make sure the record is deleted!
438
+ testMeadow.doDelete(tmpDeleteQuery,
439
+ function (pDeleteError, pDeleteQuery, pDeleteRecord)
440
+ {
441
+ var tmpQuery = testMeadow.query.addFilter('IDAnimal', 5);
442
+ testMeadow.doUndelete(tmpQuery,
443
+ function (pError, pQuery, pRecord)
444
+ {
445
+ // It returns the number of rows deleted
446
+ Expect(pRecord)
447
+ .to.equal(1);
448
+
449
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
450
+
451
+ fDone();
452
+ });
453
+ });
454
+ }
455
+ );
456
+ test
457
+ (
458
+ 'Count all records from the database',
459
+ function (fDone)
460
+ {
461
+ var testMeadow = newMeadow();
462
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1;
463
+
464
+ Expect(testMeadow.query.parameters.result.executed)
465
+ .to.equal(false);
466
+ testMeadow.doCount(testMeadow.query,
467
+ function (pError, pQuery, pRecord)
468
+ {
469
+ // There should be 5 records
470
+ Expect(pRecord)
471
+ .to.equal(5);
472
+ Expect(pQuery.parameters.result.executed)
473
+ .to.equal(true);
474
+ testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
475
+ fDone();
476
+ }
477
+ )
478
+ }
479
+ );
480
+ test
481
+ (
482
+ 'Perform operations with a schema-based instantiation',
483
+ function (fDone)
484
+ {
485
+ var testMeadow = require('../source/Meadow.js').new(libFable)
486
+ .loadFromPackage(__dirname + '/Animal.json').setProvider('MSSQL');
487
+
488
+ // Make sure the authentication stuff got loaded
489
+ Expect(testMeadow.schemaFull.authorizer.User)
490
+ .to.be.an('object');
491
+ Expect(testMeadow.schemaFull.authorizer.User.Create)
492
+ .to.equal('Allow');
493
+
494
+ var tmpQuery = testMeadow.query
495
+ .addRecord({ Name: 'Grommet', Type: 'Dog' });
496
+
497
+ testMeadow.doCreate(tmpQuery,
498
+ function (pError, pQuery, pQueryRead, pRecord)
499
+ {
500
+ // We should have a record ....
501
+ Expect(pRecord.Name)
502
+ .to.equal('Grommet');
503
+ fDone();
504
+ }
505
+ )
506
+ }
507
+ );
508
+ }
509
+ );
510
+ suite
511
+ (
512
+ 'Logged Query Processing',
513
+ function ()
514
+ {
515
+ test
516
+ (
517
+ 'Create a record in the database',
518
+ function (fDone)
519
+ {
520
+ var testMeadow = newMeadow();
521
+
522
+ var tmpQuery = testMeadow.query
523
+ .setLogLevel(5)
524
+ .addRecord({ Name: 'MewTwo', Type: 'Pokemon' });
525
+
526
+ testMeadow.doCreate(tmpQuery,
527
+ function (pError, pQuery, pQueryRead, pRecord)
528
+ {
529
+ // We should have a record ....
530
+ Expect(pRecord.Name)
531
+ .to.equal('MewTwo');
532
+ fDone();
533
+ }
534
+ )
535
+ }
536
+ );
537
+ test
538
+ (
539
+ 'Create a record in the database with a predefined GUID',
540
+ function (fDone)
541
+ {
542
+ var testMeadow = newMeadow();
543
+
544
+ var tmpQuery = testMeadow.query
545
+ .setLogLevel(5)
546
+ .addRecord({ Name: 'MewThree', GUIDAnimal: '0x12345', Type: 'Pokemon' });
547
+
548
+ testMeadow.doCreate(tmpQuery,
549
+ function (pError, pQuery, pQueryRead, pRecord)
550
+ {
551
+ // We should have a record ....
552
+ Expect(pRecord.Name)
553
+ .to.equal('MewThree');
554
+ fDone();
555
+ }
556
+ )
557
+ }
558
+ );
559
+ test
560
+ (
561
+ 'Create a record in the database with a previously predefined GUID -- expect failure',
562
+ function (fDone)
563
+ {
564
+ var testMeadow = newMeadow();
565
+
566
+ var tmpQuery = testMeadow.query
567
+ .setLogLevel(5)
568
+ .addRecord({ Name: 'MewThree', GUIDAnimal: '0x12345', Type: 'Pokemon' });
569
+
570
+ testMeadow.doCreate(tmpQuery,
571
+ function (pError, pQuery, pQueryRead, pRecord)
572
+ {
573
+ Expect(pError)
574
+ .to.equal("Record with GUID 0x12345 already exists!");
575
+ fDone();
576
+ }
577
+ )
578
+ }
579
+ );
580
+ test
581
+ (
582
+ 'Read a record from the database',
583
+ function (fDone)
584
+ {
585
+ var testMeadow = newMeadow();
586
+
587
+ var tmpQuery = testMeadow.query
588
+ .setLogLevel(5)
589
+ .addFilter('IDAnimal', 1);
590
+
591
+ testMeadow.doRead(tmpQuery,
592
+ function (pError, pQuery, pRecord)
593
+ {
594
+ // We should have a record ....
595
+ Expect(pRecord.IDAnimal)
596
+ .to.equal(1);
597
+ Expect(pRecord.Name)
598
+ .to.equal('Foo Foo');
599
+ fDone();
600
+ }
601
+ )
602
+ }
603
+ );
604
+ test
605
+ (
606
+ 'Read all records from the database',
607
+ function (fDone)
608
+ {
609
+ var testMeadow = newMeadow();
610
+
611
+ testMeadow.doReads(testMeadow.query.setLogLevel(5),
612
+ function (pError, pQuery, pRecords)
613
+ {
614
+ // We should have a record ....
615
+ Expect(pRecords[0].IDAnimal)
616
+ .to.equal(1);
617
+ Expect(pRecords[0].Name)
618
+ .to.equal('Foo Foo');
619
+ Expect(pRecords[1].IDAnimal)
620
+ .to.equal(2);
621
+ Expect(pRecords[1].Name)
622
+ .to.equal('Red Riding Hood');
623
+ Expect(pRecords[1].Type)
624
+ .to.equal('Human');
625
+ fDone();
626
+ }
627
+ )
628
+ }
629
+ );
630
+ test
631
+ (
632
+ 'Update a record in the database',
633
+ function (fDone)
634
+ {
635
+ var testMeadow = newMeadow();
636
+
637
+ var tmpQuery = testMeadow.query
638
+ .setLogLevel(5)
639
+ .addRecord({ IDAnimal: 2, Type: 'HumanGirl' });
640
+
641
+ testMeadow.doUpdate(tmpQuery,
642
+ function (pError, pQuery, pQueryRead, pRecord)
643
+ {
644
+ // We should have a record ....
645
+ Expect(pRecord.Type)
646
+ .to.equal('HumanGirl');
647
+ fDone();
648
+ }
649
+ )
650
+ }
651
+ );
652
+ test
653
+ (
654
+ 'Delete a record in the database',
655
+ function (fDone)
656
+ {
657
+ var testMeadow = newMeadow();
658
+
659
+ var tmpQuery = testMeadow.query
660
+ .setLogLevel(5)
661
+ .addFilter('IDAnimal', 4);
662
+
663
+ testMeadow.doDelete(tmpQuery,
664
+ function (pError, pQuery, pRecord)
665
+ {
666
+ // It returns the number of rows deleted
667
+ Expect(pRecord)
668
+ .to.equal(1);
669
+ fDone();
670
+ }
671
+ )
672
+ }
673
+ );
674
+ test
675
+ (
676
+ 'Count all records from the database',
677
+ function (fDone)
678
+ {
679
+ var testMeadow = newMeadow();
680
+
681
+ testMeadow.doCount(testMeadow.query.setLogLevel(5),
682
+ function (pError, pQuery, pRecord)
683
+ {
684
+ // There should be 7 records
685
+ Expect(pRecord)
686
+ .to.equal(7);
687
+ fDone();
688
+ }
689
+ )
690
+ }
691
+ );
692
+ test
693
+ (
694
+ 'Read a record from the database that had a defined GUID',
695
+ function (fDone)
696
+ {
697
+ var testMeadow = newMeadow();
698
+
699
+ var tmpQuery = testMeadow.query
700
+ .addFilter('GUIDAnimal', '0x12345');
701
+
702
+ testMeadow.doRead(tmpQuery,
703
+ function (pError, pQuery, pRecord)
704
+ {
705
+ // We should have a record ....
706
+ Expect(pRecord.IDAnimal)
707
+ .to.equal(10);
708
+ Expect(pRecord.Name)
709
+ .to.equal('MewThree');
710
+ fDone();
711
+ }
712
+ )
713
+ }
714
+ );
715
+ test
716
+ (
717
+ 'Create a record in the database with a defined creating user',
718
+ function (fDone)
719
+ {
720
+ var testMeadow = newMeadow();
721
+ var tmpQuery = testMeadow.query
722
+ .setIDUser(800)
723
+ .addRecord({ Name: 'MewSix', GUIDAnimal: '0x123456', Type: 'Pokemon' });
724
+
725
+ testMeadow.doCreate(tmpQuery,
726
+ function (pError, pQuery, pQueryRead, pRecord)
727
+ {
728
+ // We should have a record ....
729
+ Expect(pRecord.Name)
730
+ .to.equal('MewSix');
731
+ Expect(pRecord.CreatingIDUser)
732
+ .to.equal(800);
733
+ fDone();
734
+ }
735
+ )
736
+ }
737
+ );
738
+ }
739
+ );
740
+ suite
741
+ (
742
+ 'The Bad Kind of Query Processing',
743
+ function ()
744
+ {
745
+ test
746
+ (
747
+ 'Count all records from the database from a nonexistent table',
748
+ function (fDone)
749
+ {
750
+ var testMeadow = newMeadow();
751
+
752
+ testMeadow.doCount(testMeadow.query.setScope('BadTable'),
753
+ function (pError, pQuery, pRecord)
754
+ {
755
+ Expect(pError.code)
756
+ .to.equal("ER_NO_SUCH_TABLE");
757
+ fDone();
758
+ }
759
+ )
760
+ }
761
+ );
762
+ test
763
+ (
764
+ 'Create a record in the database with an invalid default identifier',
765
+ function (fDone)
766
+ {
767
+ var testMeadow = newMeadow().setDefaultIdentifier('BadIdentifier');
768
+
769
+ var tmpQuery = testMeadow.query
770
+ .addRecord({ Name: 'Scaley', Type: 'Chameleon' });
771
+
772
+ testMeadow.doCreate(tmpQuery,
773
+ function (pError, pQuery, pQueryRead, pRecord)
774
+ {
775
+ // We should have no record because the default id is IDFableTest and our tables identity is IDAnimal
776
+ Expect(pError.code)
777
+ .to.equal('ER_BAD_FIELD_ERROR');
778
+ fDone();
779
+ }
780
+ )
781
+ }
782
+ );
783
+ test
784
+ (
785
+ 'Create a record in the database with the wrong default identifier',
786
+ function (fDone)
787
+ {
788
+ var testMeadow = newMeadow().setDefaultIdentifier('Type');
789
+
790
+ var tmpQuery = testMeadow.query
791
+ .addRecord({ Name: 'Tina', Type: 'Chameleon' });
792
+
793
+ testMeadow.doCreate(tmpQuery,
794
+ function (pError, pQuery, pQueryRead, pRecord)
795
+ {
796
+ // We should have no record because the default id is IDFableTest and our tables identity is IDAnimal
797
+ Expect(pError)
798
+ .to.equal('No record found after create.');
799
+ fDone();
800
+ }
801
+ )
802
+ }
803
+ );
804
+ test
805
+ (
806
+ 'Create a record in the database with no record',
807
+ function (fDone)
808
+ {
809
+ var testMeadow = newMeadow().setDefaultIdentifier('Type');
810
+
811
+ testMeadow.doCreate(testMeadow.query,
812
+ function (pError, pQuery, pQueryRead, pRecord)
813
+ {
814
+ // We should have no record because the default id is IDFableTest and our tables identity is IDAnimal
815
+ Expect(pError)
816
+ .to.equal('No record submitted');
817
+ fDone();
818
+ }
819
+ )
820
+ }
821
+ );
822
+ test
823
+ (
824
+ 'Read a record from the database with no data returned',
825
+ function (fDone)
826
+ {
827
+ var testMeadow = newMeadow();
828
+
829
+ var tmpQuery = testMeadow.query
830
+ .addFilter('IDAnimal', 5000);
831
+ testMeadow.doRead(tmpQuery,
832
+ function (pError, pQuery, pRecord)
833
+ {
834
+ Expect(pRecord)
835
+ .to.equal(false);
836
+ fDone();
837
+ }
838
+ )
839
+ }
840
+ );
841
+ test
842
+ (
843
+ 'Read records from the database with no data returned',
844
+ function (fDone)
845
+ {
846
+ var testMeadow = newMeadow();
847
+
848
+ var tmpQuery = testMeadow.query
849
+ .addFilter('IDAnimal', 5000);
850
+
851
+ testMeadow.doReads(tmpQuery,
852
+ function (pError, pQuery, pRecord)
853
+ {
854
+ Expect(pRecord.length)
855
+ .to.equal(0);
856
+ fDone();
857
+ }
858
+ )
859
+ }
860
+ );
861
+ test
862
+ (
863
+ 'Read records from the database with an invalid query',
864
+ function (fDone)
865
+ {
866
+ var testMeadow = newMeadow();
867
+
868
+ var tmpQuery = testMeadow.query
869
+ .addFilter('IDAnimalFarmGeorge', 5000);
870
+
871
+ testMeadow.doReads(tmpQuery,
872
+ function (pError, pQuery, pRecord)
873
+ {
874
+ Expect(pError.code)
875
+ .to.equal('ER_BAD_FIELD_ERROR');
876
+ fDone();
877
+ }
878
+ )
879
+ }
880
+ );
881
+ test
882
+ (
883
+ 'Read a single record from the database with an invalid query',
884
+ function (fDone)
885
+ {
886
+ var testMeadow = newMeadow();
887
+
888
+ var tmpQuery = testMeadow.query
889
+ .addFilter('IDAnimalFarmGeorge', 5000);
890
+
891
+ testMeadow.doRead(tmpQuery,
892
+ function (pError, pQuery, pRecord)
893
+ {
894
+ Expect(pError.code)
895
+ .to.equal('ER_BAD_FIELD_ERROR');
896
+ fDone();
897
+ }
898
+ )
899
+ }
900
+ );
901
+ test
902
+ (
903
+ 'Delete with a bad query',
904
+ function (fDone)
905
+ {
906
+ var testMeadow = newMeadow();
907
+
908
+ var tmpQuery = testMeadow.query
909
+ .addFilter('IDAnimalHouse', 4);
910
+
911
+ testMeadow.doDelete(tmpQuery,
912
+ function (pError, pQuery, pRecord)
913
+ {
914
+ Expect(pError.code)
915
+ .to.equal('ER_BAD_FIELD_ERROR');
916
+ fDone();
917
+ }
918
+ )
919
+ }
920
+ );
921
+ test
922
+ (
923
+ 'Update a record in the database with a bad filter',
924
+ function (fDone)
925
+ {
926
+ var testMeadow = newMeadow();
927
+
928
+ var tmpQuery = testMeadow.query
929
+ .setLogLevel(5)
930
+ .addRecord({ IDAnimal: undefined, Type: 'HumanGirl' });
931
+
932
+ testMeadow.doUpdate(tmpQuery,
933
+ function (pError, pQuery, pQueryRead, pRecord)
934
+ {
935
+ // We should have a record ....
936
+ Expect(pError)
937
+ .to.equal('Automated update missing filters... aborting!');
938
+ fDone();
939
+ }
940
+ )
941
+ }
942
+ );
943
+ test
944
+ (
945
+ 'Update a record in the database without passing a record in',
946
+ function (fDone)
947
+ {
948
+ var testMeadow = newMeadow();
949
+
950
+ testMeadow.doUpdate(testMeadow.query,
951
+ function (pError, pQuery, pQueryRead, pRecord)
952
+ {
953
+ Expect(pError)
954
+ .to.equal('No record submitted');
955
+ fDone();
956
+ }
957
+ )
958
+ }
959
+ );
960
+ test
961
+ (
962
+ 'Update a record in the database without passing a record in',
963
+ function (fDone)
964
+ {
965
+ var testMeadow = newMeadow();
966
+
967
+ testMeadow.doUpdate(testMeadow.query,
968
+ function (pError, pQuery, pQueryRead, pRecord)
969
+ {
970
+ Expect(pError)
971
+ .to.equal('No record submitted');
972
+ fDone();
973
+ }
974
+ )
975
+ }
976
+ );
977
+ test
978
+ (
979
+ 'Update a record in the database with a bad record passed in (no default identifier)',
980
+ function (fDone)
981
+ {
982
+ var testMeadow = newMeadow();
983
+
984
+ var tmpQuery = testMeadow.query
985
+ .addRecord({ Name: 'Bill' });
986
+
987
+ testMeadow.doUpdate(tmpQuery,
988
+ function (pError, pQuery, pQueryRead, pRecord)
989
+ {
990
+ Expect(pError)
991
+ .to.equal('Automated update missing default identifier');
992
+ fDone();
993
+ }
994
+ )
995
+ }
996
+ );
997
+ test
998
+ (
999
+ 'Update a record in the database that does not exist',
1000
+ function (fDone)
1001
+ {
1002
+ var testMeadow = newMeadow();
1003
+
1004
+ var tmpQuery = testMeadow.query
1005
+ .addRecord({ IDAnimal: 983924 });
1006
+
1007
+ testMeadow.doUpdate(tmpQuery,
1008
+ function (pError, pQuery, pQueryRead, pRecord)
1009
+ {
1010
+ Expect(pError)
1011
+ .to.equal('No record found to update!');
1012
+ fDone();
1013
+ }
1014
+ )
1015
+ }
1016
+ );
1017
+ test
1018
+ (
1019
+ 'Set a raw Query',
1020
+ function (fDone)
1021
+ {
1022
+ var testMeadow = newMeadow();
1023
+ testMeadow.rawQueries.setQuery('Read', 'SELECT Something from SomethingElse;');
1024
+
1025
+ Expect(testMeadow.rawQueries.getQuery('Read'))
1026
+ .to.equal('SELECT Something from SomethingElse;');
1027
+ fDone();
1028
+ }
1029
+ );
1030
+ test
1031
+ (
1032
+ 'Load a raw Query',
1033
+ function (fDone)
1034
+ {
1035
+ var testMeadow = newMeadow();
1036
+
1037
+ testMeadow.rawQueries.loadQuery('Read', __dirname + '/Meadow-Provider-MSSQL-AnimalReadQuery.sql',
1038
+ function (pSuccess)
1039
+ {
1040
+ Expect(testMeadow.rawQueries.getQuery('Read'))
1041
+ .to.contain('SELECT');
1042
+ fDone();
1043
+ });
1044
+ }
1045
+ );
1046
+ test
1047
+ (
1048
+ 'Load a bad raw Query',
1049
+ function (fDone)
1050
+ {
1051
+ var testMeadow = newMeadow();
1052
+
1053
+ testMeadow.rawQueries.loadQuery('Read', __dirname + '/Meadow-Provider-MSSQL-BADAnimalReadQuery.sql',
1054
+ function (pSuccess)
1055
+ {
1056
+ Expect(testMeadow.rawQueries.getQuery('Read'))
1057
+ .to.equal('');
1058
+ fDone();
1059
+ });
1060
+ }
1061
+ );
1062
+ test
1063
+ (
1064
+ 'Load a raw query with no callback',
1065
+ function ()
1066
+ {
1067
+ var testMeadow = newMeadow();
1068
+
1069
+ testMeadow.rawQueries.loadQuery('Read', __dirname + '/Meadow-Provider-MSSQL-AnimalReadQuery.sql');
1070
+ }
1071
+ );
1072
+ test
1073
+ (
1074
+ 'Check for a query that is not there',
1075
+ function ()
1076
+ {
1077
+ var testMeadow = newMeadow();
1078
+ Expect(testMeadow.rawQueries.getQuery('Read'))
1079
+ .to.equal(false);
1080
+ }
1081
+ );
1082
+ test
1083
+ (
1084
+ 'Read a record from a custom query',
1085
+ function (fDone)
1086
+ {
1087
+ var testMeadow = newMeadow();
1088
+
1089
+ testMeadow.rawQueries.loadQuery('Read', __dirname + '/Meadow-Provider-MSSQL-AnimalReadQuery.sql',
1090
+ function (pSuccess)
1091
+ {
1092
+ // Now try to read the record
1093
+ testMeadow.doRead(testMeadow.query.addFilter('IDAnimal', 2),
1094
+ function (pError, pQuery, pRecord)
1095
+ {
1096
+ Expect(pRecord.AnimalTypeCustom)
1097
+ .to.equal('Bunny');
1098
+ fDone();
1099
+ }
1100
+ )
1101
+ });
1102
+ }
1103
+ );
1104
+ test
1105
+ (
1106
+ 'Read records from a custom query, then delete one, then read them again then update and create.',
1107
+ function (fDone)
1108
+ {
1109
+ var testMeadow = newMeadow();
1110
+ testMeadow.setDefaultIdentifier('IDAnimal');
1111
+ testMeadow.rawQueries.setQuery('Delete', 'DELETE FROM FableTest WHERE IDAnimal = 1;')
1112
+ testMeadow.rawQueries.setQuery('Count', 'SELECT 1337 AS RowCount;')
1113
+ testMeadow.rawQueries.setQuery('Read', 'SELECT IDAnimal, Type AS AnimalTypeCustom FROM FableTest <%= Where %>')
1114
+ testMeadow.rawQueries.setQuery('Update', "UPDATE FableTest SET Type = 'FrogLeg' <%= Where %>")
1115
+
1116
+ // And this, my friends, is why we use async.js
1117
+ testMeadow.rawQueries.loadQuery('Reads', __dirname + '/Meadow-Provider-MSSQL-AnimalReadQuery.sql',
1118
+ function (pSuccess)
1119
+ {
1120
+ // Now try to read the record
1121
+ testMeadow.doReads(testMeadow.query.addFilter('IDAnimal', 2),
1122
+ function (pError, pQuery, pRecords)
1123
+ {
1124
+ Expect(pRecords[1].AnimalTypeCustom)
1125
+ .to.equal('HumanGirl');
1126
+ testMeadow.doDelete(testMeadow.query.addFilter('IDAnimal', 2),
1127
+ function (pError, pQuery, pRecord)
1128
+ {
1129
+ // It returns the number of rows deleted
1130
+ Expect(pRecord)
1131
+ .to.equal(1);
1132
+ testMeadow.doCount(testMeadow.query.addFilter('IDAnimal', 2),
1133
+ function (pError, pQuery, pRecord)
1134
+ {
1135
+ // It returns the number of rows deleted
1136
+ Expect(pRecord)
1137
+ .to.equal(1337);
1138
+ var tmpQuery = testMeadow.query
1139
+ .addRecord({ IDAnimal: 5, Type: 'Bartfast' });
1140
+
1141
+ testMeadow.doUpdate(tmpQuery,
1142
+ function (pError, pQuery, pQueryRead, pRecord)
1143
+ {
1144
+ // We should have a record ....
1145
+ Expect(pRecord.AnimalTypeCustom)
1146
+ .to.equal('Bartfast');
1147
+ var tmpQuery = testMeadow.query
1148
+ .addRecord({ Name: 'Bambi', Type: 'CustomSheep' });
1149
+
1150
+ testMeadow.doCreate(tmpQuery,
1151
+ function (pError, pQuery, pQueryRead, pRecord)
1152
+ {
1153
+ // We should have a record ....
1154
+ Expect(pRecord.AnimalTypeCustom)
1155
+ .to.equal('CustomSheep');
1156
+ fDone();
1157
+ }
1158
+ )
1159
+ }
1160
+ )
1161
+ }
1162
+ )
1163
+ }
1164
+ )
1165
+ }
1166
+ )
1167
+ }
1168
+ );
1169
+ }
1170
+ );
1171
+ test
1172
+ (
1173
+ 'Create a record in the database with bad fields',
1174
+ function (fDone)
1175
+ {
1176
+ var testMeadow = newMeadow();
1177
+ // NOTE: Bad fields passed in are polluting the schema forever.
1178
+ var tmpQuery = testMeadow.query
1179
+ .addRecord({ Name: 'Tina', TypeWriter: 'Chameleon' });
1180
+
1181
+ testMeadow.doCreate(tmpQuery,
1182
+ function (pError, pQuery, pQueryRead, pRecord)
1183
+ {
1184
+ Expect(pError.code)
1185
+ .to.equal('ER_BAD_FIELD_ERROR');
1186
+ fDone();
1187
+ }
1188
+ )
1189
+ }
1190
+ );
1191
+ }
1192
+ );
1193
+ }
1194
+ );