foxhound 2.0.10 → 2.0.11

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,901 @@
1
+ /**
2
+ * Unit tests for FoxHound
3
+ *
4
+ * @license MIT
5
+ *
6
+ * @author Steven Velozo <steven@velozo.com>
7
+ */
8
+
9
+ var Chai = require('chai');
10
+ var Expect = Chai.expect;
11
+ var Assert = Chai.assert;
12
+
13
+ var libFable = require('fable');
14
+ const _Fable = new libFable({Product:'FoxhoundTestsSQLite'});
15
+ var libFoxHound = require('../source/FoxHound.js');
16
+
17
+ var _AnimalSchema = (
18
+ [
19
+ { Column: "IDAnimal", Type:"AutoIdentity" },
20
+ { Column: "GUIDAnimal", Type:"AutoGUID" },
21
+ { Column: "CreateDate", Type:"CreateDate" },
22
+ { Column: "CreatingIDUser", Type:"CreateIDUser" },
23
+ { Column: "UpdateDate", Type:"UpdateDate" },
24
+ { Column: "UpdatingIDUser", Type:"UpdateIDUser" },
25
+ { Column: "Deleted", Type:"Deleted" },
26
+ { Column: "DeletingIDUser", Type:"DeleteIDUser" },
27
+ { Column: "DeleteDate", Type:"DeleteDate" }
28
+ ]);
29
+
30
+ var _AnimalSchemaWithoutDeleted = (
31
+ [
32
+ { Column: "IDAnimal", Type:"AutoIdentity" },
33
+ { Column: "GUIDAnimal", Type:"AutoGUID" },
34
+ { Column: "CreateDate", Type:"CreateDate" },
35
+ { Column: "CreatingIDUser", Type:"CreateIDUser" },
36
+ { Column: "UpdateDate", Type:"UpdateDate" },
37
+ { Column: "UpdatingIDUser", Type:"UpdateIDUser" }
38
+ ]);
39
+
40
+ suite
41
+ (
42
+ 'FoxHound-Dialect-SQLite',
43
+ function()
44
+ {
45
+ setup
46
+ (
47
+ function()
48
+ {
49
+ }
50
+ );
51
+
52
+ suite
53
+ (
54
+ 'Object Sanity',
55
+ function()
56
+ {
57
+ test
58
+ (
59
+ 'initialize should build a happy little object',
60
+ function()
61
+ {
62
+ var testFoxHound = libFoxHound.new(_Fable).setDialect('SQLite');
63
+ Expect(testFoxHound.dialect.name)
64
+ .to.equal('SQLite');
65
+ Expect(testFoxHound)
66
+ .to.be.an('object', 'FoxHound with SQLite should initialize as an object directly from the require statement.');
67
+ }
68
+ );
69
+ }
70
+ );
71
+
72
+ suite
73
+ (
74
+ 'Basic Query Generation',
75
+ function()
76
+ {
77
+ test
78
+ (
79
+ 'Create Query',
80
+ function()
81
+ {
82
+ var tmpQuery = libFoxHound.new(_Fable)
83
+ .setLogLevel(5)
84
+ .setDialect('SQLite')
85
+ .setScope('Animal')
86
+ .addRecord({IDAnimal:null, Name:'Foo Foo', Age:15});
87
+ // Build the query
88
+ tmpQuery.buildCreateQuery();
89
+ // This is the query generated by the SQLite dialect
90
+ _Fable.log.trace('Create Query', tmpQuery.query);
91
+ Expect(tmpQuery.query.body)
92
+ .to.equal("INSERT INTO Animal ( `IDAnimal`, `Name`, `Age`) VALUES ( :IDAnimal_0, :Name_1, :Age_2);");
93
+ }
94
+ );
95
+ test
96
+ (
97
+ 'Bad Create Query',
98
+ function()
99
+ {
100
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite');
101
+ // Build the query
102
+ tmpQuery.buildCreateQuery();
103
+ tmpQuery.addRecord({});
104
+ tmpQuery.buildCreateQuery();
105
+ // This is the query generated by the SQLite dialect
106
+ _Fable.log.trace('Create Query', tmpQuery.query);
107
+ Expect(tmpQuery.query.body)
108
+ .to.equal(false);
109
+ }
110
+ );
111
+ test
112
+ (
113
+ 'Read Query',
114
+ function()
115
+ {
116
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite').setScope('Animal');
117
+ tmpQuery.addSort({Column:'Cost',Direction:'Descending'});
118
+ // Build the query
119
+ tmpQuery.buildReadQuery();
120
+ // This is the query generated by the SQLite dialect
121
+ _Fable.log.trace('Simple Select Query', tmpQuery.query);
122
+ Expect(tmpQuery.query.body)
123
+ .to.equal('SELECT * FROM Animal ORDER BY `Cost` DESC;');
124
+ }
125
+ );
126
+ test
127
+ (
128
+ 'Read Query with Distinct',
129
+ function()
130
+ {
131
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite').setScope('Animal');
132
+ tmpQuery.addSort({Column:'Cost',Direction:'Descending'})
133
+ .setDistinct(true);
134
+ // Build the query
135
+ tmpQuery.buildReadQuery();
136
+ // This is the query generated by the SQLite dialect
137
+ _Fable.log.trace('Simple Select Query', tmpQuery.query);
138
+ Expect(tmpQuery.query.body)
139
+ .to.equal('SELECT DISTINCT * FROM Animal ORDER BY `Cost` DESC;');
140
+ }
141
+ );
142
+ test
143
+ (
144
+ 'Complex Read Query',
145
+ function()
146
+ {
147
+ var tmpQuery = libFoxHound.new(_Fable)
148
+ .setDialect('SQLite')
149
+ .setScope('Animal')
150
+ .setCap(10)
151
+ .setBegin(0)
152
+ .setDataElements(['Name', 'Age', 'Cost'])
153
+ .setSort([{Column:'Age',Direction:'Ascending'}])
154
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
155
+ tmpQuery.addSort('Cost');
156
+ // Build the query
157
+ tmpQuery.buildReadQuery();
158
+ // This is the query generated by the SQLite dialect
159
+ _Fable.log.trace('Select Query', tmpQuery.query);
160
+ Expect(tmpQuery.query.body)
161
+ .to.equal('SELECT `Name`, `Age`, `Cost` FROM Animal WHERE `Age` = :Age_w0 ORDER BY `Age`, `Cost` LIMIT 10 FETCH 0;');
162
+ }
163
+ );
164
+ test
165
+ (
166
+ 'Complex Read Query with Distinct',
167
+ function()
168
+ {
169
+ var tmpQuery = libFoxHound.new(_Fable)
170
+ .setDialect('SQLite')
171
+ .setScope('Animal')
172
+ .setCap(10)
173
+ .setBegin(0)
174
+ .setDataElements(['Name', 'Age', 'Cost'])
175
+ .setSort([{Column:'Age',Direction:'Ascending'}])
176
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'})
177
+ .setDistinct(true);
178
+ tmpQuery.addSort('Cost');
179
+ // Build the query
180
+ tmpQuery.buildReadQuery();
181
+ // This is the query generated by the SQLite dialect
182
+ _Fable.log.trace('Select Query', tmpQuery.query);
183
+ Expect(tmpQuery.query.body)
184
+ .to.equal('SELECT DISTINCT `Name`, `Age`, `Cost` FROM Animal WHERE `Age` = :Age_w0 ORDER BY `Age`, `Cost` LIMIT 10 FETCH 0;');
185
+ }
186
+ );
187
+ test
188
+ (
189
+ 'Complex Read Query 2',
190
+ function()
191
+ {
192
+ var tmpQuery = libFoxHound.new(_Fable)
193
+ .setDialect('SQLite')
194
+ .setScope('Animal')
195
+ .setDataElements(['Name', 'Age', 'Cost'])
196
+ .setCap(100)
197
+ .addFilter('Age', '25')
198
+ .addFilter('', '', '(')
199
+ .addFilter('Color', 'Red')
200
+ .addFilter('Color', 'Green', '=', 'OR')
201
+ .addFilter('', '', ')')
202
+ .addFilter('Description', '', 'IS NOT NULL')
203
+ .addFilter('IDOffice', [10, 11, 15, 18, 22], 'IN');
204
+ tmpQuery.setLogLevel(3).addSort('Age');
205
+ // Build the query
206
+ tmpQuery.buildReadQuery();
207
+ // This is the query generated by the SQLite dialect
208
+ _Fable.log.trace('Select Query', tmpQuery.query);
209
+ Expect(tmpQuery.query.body)
210
+ .to.equal('SELECT `Name`, `Age`, `Cost` FROM Animal WHERE `Age` = :Age_w0 AND ( `Color` = :Color_w2 OR `Color` = :Color_w3 ) AND `Description` IS NOT NULL AND `IDOffice` IN ( :IDOffice_w6 ) ORDER BY `Age` LIMIT 100;');
211
+ }
212
+ );
213
+ test
214
+ (
215
+ 'Custom Read Query',
216
+ function()
217
+ {
218
+ var tmpQuery = libFoxHound.new(_Fable)
219
+ .setDialect('SQLite')
220
+ .setScope('Animal')
221
+ .setCap(10)
222
+ .setBegin(0)
223
+ .setDataElements(['Name', 'Age', 'Cost'])
224
+ .setSort([{Column:'Age',Direction:'Ascending'},{Column:'Cost',Direction:'Descending'}])
225
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
226
+ tmpQuery.parameters.queryOverride = 'SELECT `Name`, `Age` * 5, `Cost` FROM <%= TableName %> <%= Where %> <%= Limit %>;';
227
+ // Build the query
228
+ tmpQuery.buildReadQuery();
229
+ // This is the query generated by the SQLite dialect
230
+ _Fable.log.trace('Custom Select Query', tmpQuery.query);
231
+ Expect(tmpQuery.query.body)
232
+ .to.equal('SELECT `Name`, `Age` * 5, `Cost` FROM Animal WHERE `Age` = :Age_w0 LIMIT 10 FETCH 0;');
233
+ }
234
+ );
235
+ test
236
+ (
237
+ 'Custom Read Query with Custom Parameters',
238
+ function()
239
+ {
240
+ var tmpQuery = libFoxHound.new(_Fable)
241
+ .setDialect('SQLite')
242
+ .setScope('Animal')
243
+ .setCap(10)
244
+ .setBegin(0)
245
+ .setDataElements(['Name', 'Age', 'Cost'])
246
+ .setSort([{Column:'Age',Direction:'Ascending'},{Column:'Cost',Direction:'Descending'}])
247
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
248
+ tmpQuery.parameters.CustomFields = '`Name`, `Age` * 5, `Cost`';
249
+ tmpQuery.parameters.queryOverride = 'SELECT <%= _Params.CustomFields %> FROM <%= TableName %> <%= Where %> <%= Limit %>;';
250
+ // Build the query
251
+ tmpQuery.buildReadQuery();
252
+ // This is the query generated by the SQLite dialect
253
+ _Fable.log.trace('Custom Select Query', tmpQuery.query);
254
+ Expect(tmpQuery.query.body)
255
+ .to.equal('SELECT `Name`, `Age` * 5, `Cost` FROM Animal WHERE `Age` = :Age_w0 LIMIT 10 FETCH 0;');
256
+ }
257
+ );
258
+ test
259
+ (
260
+ 'Bad Custom Read Query',
261
+ function()
262
+ {
263
+ var tmpQuery = libFoxHound.new(_Fable)
264
+ .setDialect('SQLite')
265
+ .setScope('Animal')
266
+ .setCap(10)
267
+ .setBegin(0)
268
+ .setDataElements(['Name', 'Age', 'Cost'])
269
+ .setSort([{Column:'Age',Direction:'Ascending'}])
270
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
271
+ tmpQuery.parameters.queryOverride = 'SELECT `Name`, `Age` * 5, `Cost` FROM <%= TableName <%= Where %> <%= Limit ;';
272
+ // Build the query
273
+ tmpQuery.buildReadQuery();
274
+ // This is the query generated by the SQLite dialect
275
+ _Fable.log.trace('Custom Select Query', tmpQuery.query);
276
+ Expect(tmpQuery.query.body)
277
+ .to.equal(false);
278
+ }
279
+ );
280
+ test
281
+ (
282
+ 'Bad Custom Count Query',
283
+ function()
284
+ {
285
+ var tmpQuery = libFoxHound.new(_Fable)
286
+ .setDialect('SQLite')
287
+ .setScope('Animal')
288
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
289
+ tmpQuery.parameters.queryOverride = 'SELECT COUNT(*) AS RowCount FROM <%= TableName <%= TableName %> <%= Where;';
290
+ // Build the query
291
+ tmpQuery.buildCountQuery();
292
+ // This is the query generated by the SQLite dialect
293
+ _Fable.log.trace('Custom Count Query', tmpQuery.query);
294
+ Expect(tmpQuery.query.body)
295
+ .to.equal(false);
296
+ }
297
+ );
298
+ test
299
+ (
300
+ 'Custom Count Query',
301
+ function()
302
+ {
303
+ var tmpQuery = libFoxHound.new(_Fable)
304
+ .setDialect('SQLite')
305
+ .setScope('Animal')
306
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
307
+ tmpQuery.parameters.queryOverride = 'SELECT COUNT(*) AS RowCount FROM <%= TableName %> <%= Where %>;';
308
+ // Build the query
309
+ tmpQuery.buildCountQuery();
310
+ // This is the query generated by the SQLite dialect
311
+ _Fable.log.trace('Custom Count Query', tmpQuery.query);
312
+ Expect(tmpQuery.query.body)
313
+ .to.equal('SELECT COUNT(*) AS RowCount FROM Animal WHERE `Age` = :Age_w0;');
314
+ }
315
+ );
316
+ test
317
+ (
318
+ 'Custom Count Query with Custom Parameters',
319
+ function()
320
+ {
321
+ var tmpQuery = libFoxHound.new(_Fable)
322
+ .setDialect('SQLite')
323
+ .setScope('Animal')
324
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
325
+ tmpQuery.parameters.CountAlias = 'RowCount';
326
+ tmpQuery.parameters.queryOverride = 'SELECT COUNT(*) AS <%= _Params.CountAlias %> FROM <%= TableName %> <%= Where %>;';
327
+ // Build the query
328
+ tmpQuery.buildCountQuery();
329
+ // This is the query generated by the SQLite dialect
330
+ _Fable.log.trace('Custom Count Query', tmpQuery.query);
331
+ Expect(tmpQuery.query.body)
332
+ .to.equal('SELECT COUNT(*) AS RowCount FROM Animal WHERE `Age` = :Age_w0;');
333
+ }
334
+ );
335
+ test
336
+ (
337
+ 'Count Query with Field Overrides',
338
+ function()
339
+ {
340
+ var tmpQuery = libFoxHound.new(_Fable)
341
+ .setDialect('SQLite')
342
+ .setScope('Animal')
343
+ .setCap(10)
344
+ .setBegin(0)
345
+ .setDataElements(['Name', 'Age', 'Cost'])
346
+ .setSort([{Column:'Age',Direction:'Ascending'},{Column:'Cost',Direction:'Descending'}])
347
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'});
348
+ // Build the query
349
+ tmpQuery.buildCountQuery();
350
+ // This is the query generated by the SQLite dialect
351
+ _Fable.log.trace('Custom Select Query', tmpQuery.query);
352
+ Expect(tmpQuery.query.body)
353
+ .to.equal('SELECT COUNT(*) AS RowCount FROM Animal WHERE `Age` = :Age_w0;');
354
+ }
355
+ );
356
+ test
357
+ (
358
+ 'Count Query with Field Overrides and Distinct',
359
+ function()
360
+ {
361
+ var tmpQuery = libFoxHound.new(_Fable)
362
+ .setDialect('SQLite')
363
+ .setScope('Animal')
364
+ .setCap(10)
365
+ .setBegin(0)
366
+ .setDataElements(['Name', 'Age', 'Cost'])
367
+ .setSort([{Column:'Age',Direction:'Ascending'},{Column:'Cost',Direction:'Descending'}])
368
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'})
369
+ .setDistinct(true);
370
+ // Build the query
371
+ tmpQuery.buildCountQuery();
372
+ // This is the query generated by the SQLite dialect
373
+ _Fable.log.trace('Custom Select Query', tmpQuery.query);
374
+ Expect(tmpQuery.query.body)
375
+ .to.equal('SELECT COUNT(DISTINCT `Name`, `Age`, `Cost`) AS RowCount FROM Animal WHERE `Age` = :Age_w0;');
376
+ }
377
+ );
378
+ test
379
+ (
380
+ 'Custom Count Query with Distinct',
381
+ function()
382
+ {
383
+ var tmpQuery = libFoxHound.new(_Fable)
384
+ .setDialect('SQLite')
385
+ .setScope('Animal')
386
+ .setFilter({Column:'Age',Operator:'=',Value:'15',Connector:'AND',Parameter:'Age'})
387
+ .setDistinct(true);
388
+ // Build the query
389
+ tmpQuery.buildCountQuery();
390
+ // This is the query generated by the SQLite dialect
391
+ _Fable.log.trace('Custom Count Query', tmpQuery.query);
392
+ Expect(tmpQuery.query.body)
393
+ .to.equal('SELECT COUNT(*) AS RowCount FROM Animal WHERE `Age` = :Age_w0;');
394
+ }
395
+ );
396
+ test
397
+ (
398
+ 'Update Query',
399
+ function()
400
+ {
401
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
402
+ .setLogLevel(5)
403
+ .setScope('Animal')
404
+ .addFilter('IDAnimal', 9)
405
+ .addRecord({Age:15,Color:'Brown'});
406
+
407
+ // Build the query
408
+ tmpQuery.buildUpdateQuery();
409
+ // This is the query generated by the SQLite dialect
410
+ _Fable.log.trace('Update Query', tmpQuery.query);
411
+ Expect(tmpQuery.query.body)
412
+ .to.equal('UPDATE Animal SET `Age` = :Age_0, `Color` = :Color_1 WHERE `IDAnimal` = :IDAnimal_w0;');
413
+ }
414
+ );
415
+ test
416
+ (
417
+ 'Bad Update Query',
418
+ function()
419
+ {
420
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite');
421
+
422
+ // Build the query
423
+ tmpQuery.buildUpdateQuery();
424
+ tmpQuery.addRecord({});
425
+ tmpQuery.buildUpdateQuery();
426
+ // This is the query generated by the SQLite dialect
427
+ _Fable.log.trace('Update Query', tmpQuery.query);
428
+ Expect(tmpQuery.query.body)
429
+ .to.equal(false);
430
+ }
431
+ );
432
+ test
433
+ (
434
+ 'Delete Query',
435
+ function()
436
+ {
437
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
438
+ .setScope('Animal')
439
+ .addFilter('IDAnimal', 10);
440
+
441
+ // Build the query
442
+ tmpQuery.buildDeleteQuery();
443
+ // This is the query generated by the SQLite dialect
444
+ _Fable.log.trace('Delete Query', tmpQuery.query);
445
+ Expect(tmpQuery.query.body)
446
+ .to.equal('DELETE FROM Animal WHERE `IDAnimal` = :IDAnimal_w0;');
447
+ }
448
+ );
449
+ test
450
+ (
451
+ 'Count Query',
452
+ function()
453
+ {
454
+ var tmpQuery = libFoxHound.new(_Fable)
455
+ .setDialect('SQLite')
456
+ .setScope('Animal');
457
+
458
+ // Build the query
459
+ tmpQuery.buildCountQuery();
460
+ // This is the query generated by the SQLite dialect
461
+ _Fable.log.trace('Count Query', tmpQuery.query);
462
+ Expect(tmpQuery.query.body)
463
+ .to.equal('SELECT COUNT(*) AS RowCount FROM Animal;');
464
+ }
465
+ );
466
+ test
467
+ (
468
+ 'Count Query with Distinct',
469
+ function()
470
+ {
471
+ var tmpQuery = libFoxHound.new(_Fable)
472
+ .setDialect('SQLite')
473
+ .setScope('Animal')
474
+ .setDistinct(true);
475
+
476
+ // Build the query
477
+ tmpQuery.buildCountQuery();
478
+ // This is the query generated by the SQLite dialect
479
+ _Fable.log.trace('Count Query', tmpQuery.query);
480
+ Expect(tmpQuery.query.body)
481
+ .to.equal('SELECT COUNT(*) AS RowCount FROM Animal;');
482
+ }
483
+ );
484
+ test
485
+ (
486
+ 'Count Query with Schema and Distinct',
487
+ function()
488
+ {
489
+ var tmpQuery = libFoxHound.new(_Fable)
490
+ .setDialect('SQLite')
491
+ .setScope('Animal')
492
+ .setDistinct(true);
493
+ tmpQuery.query.schema = _AnimalSchema;
494
+
495
+ // Build the query
496
+ tmpQuery.buildCountQuery();
497
+ // This is the query generated by the SQLite dialect
498
+ _Fable.log.trace('Count Query', tmpQuery.query);
499
+ Expect(tmpQuery.query.body)
500
+ .to.equal('SELECT COUNT(DISTINCT IDAnimal) AS RowCount FROM Animal WHERE `Deleted` = :Deleted_w0;');
501
+ }
502
+ );
503
+ }
504
+ );
505
+
506
+ suite
507
+ (
508
+ 'Complex Query Generation - Schemas',
509
+ function()
510
+ {
511
+ test
512
+ (
513
+ 'Create Query',
514
+ function()
515
+ {
516
+ var tmpQuery = libFoxHound.new(_Fable)
517
+ .setLogLevel(5)
518
+ .setDialect('SQLite')
519
+ .setScope('Animal')
520
+ .addRecord(
521
+ {
522
+ IDAnimal:false,
523
+ GUIDAnimal:false,
524
+ CreateDate:false,
525
+ CreatingIDUser:false,
526
+ UpdateDate:false,
527
+ UpdatingIDUser:false,
528
+ Deleted:false,
529
+ DeletingIDUser:false,
530
+ DeleteDate:false,
531
+ Name:'Froo Froo',
532
+ Age:18
533
+ });
534
+ tmpQuery.query.schema = _AnimalSchema;
535
+ // Build the query
536
+ tmpQuery.buildCreateQuery();
537
+ // This is the query generated by the SQLite dialect
538
+ _Fable.log.trace('Create Query', tmpQuery.query);
539
+ Expect(tmpQuery.query.body)
540
+ .to.equal("INSERT INTO Animal ( `IDAnimal`, `GUIDAnimal`, `CreateDate`, `CreatingIDUser`, `UpdateDate`, `UpdatingIDUser`, `Deleted`, `Name`, `Age`) VALUES ( NULL, :GUIDAnimal_1, NOW(), :CreatingIDUser_3, NOW(), :UpdatingIDUser_5, :Deleted_6, :Name_7, :Age_8);");
541
+ }
542
+ );
543
+ test
544
+ (
545
+ 'Create Query -- with GUID specified',
546
+ function()
547
+ {
548
+ var tmpQuery = libFoxHound.new(_Fable)
549
+ .setLogLevel(5)
550
+ .setDialect('SQLite')
551
+ .setScope('Animal')
552
+ .addRecord(
553
+ {
554
+ IDAnimal:false,
555
+ GUIDAnimal:'0xabcdef',
556
+ CreateDate:false,
557
+ CreatingIDUser:false,
558
+ UpdateDate:false,
559
+ UpdatingIDUser:false,
560
+ Deleted:false,
561
+ DeletingIDUser:false,
562
+ DeleteDate:false,
563
+ Name:'Froo Froo',
564
+ Age:18
565
+ });
566
+ tmpQuery.query.schema = _AnimalSchema;
567
+ // Build the query
568
+ tmpQuery.buildCreateQuery();
569
+ // This is the query generated by the SQLite dialect
570
+ _Fable.log.trace('Create Query', tmpQuery.query);
571
+ Expect(tmpQuery.query.body)
572
+ .to.equal("INSERT INTO Animal ( `IDAnimal`, `GUIDAnimal`, `CreateDate`, `CreatingIDUser`, `UpdateDate`, `UpdatingIDUser`, `Deleted`, `Name`, `Age`) VALUES ( NULL, :GUIDAnimal_1, NOW(), :CreatingIDUser_3, NOW(), :UpdatingIDUser_5, :Deleted_6, :Name_7, :Age_8);");
573
+ }
574
+ );
575
+ test
576
+ (
577
+ 'Create Query - with AutoIdentity disabled',
578
+ function()
579
+ {
580
+ var tmpQuery = libFoxHound.new(_Fable)
581
+ .setLogLevel(5)
582
+ .setDialect('SQLite')
583
+ .setScope('Animal')
584
+ .setDisableAutoIdentity(true)
585
+ .setDisableDeleteTracking(true)
586
+ .setDisableAutoDateStamp(true)
587
+ .setDisableAutoUserStamp(true)
588
+ .addRecord(
589
+ {
590
+ IDAnimal:false,
591
+ GUIDAnimal:false,
592
+ CreateDate:false,
593
+ CreatingIDUser:false,
594
+ UpdateDate:false,
595
+ UpdatingIDUser:false,
596
+ Deleted:false,
597
+ DeletingIDUser:false,
598
+ DeleteDate:false,
599
+ Name:'Froo Froo',
600
+ Age:18
601
+ });
602
+ tmpQuery.query.schema = _AnimalSchema;
603
+ // Build the query
604
+ tmpQuery.buildCreateQuery();
605
+ // This is the query generated by the SQLite dialect
606
+ _Fable.log.trace('Create Query (AutoIdentity disabled)', tmpQuery.query);
607
+ Expect(tmpQuery.query.body)
608
+ .to.equal("INSERT INTO Animal ( `IDAnimal`, `GUIDAnimal`, `CreateDate`, `CreatingIDUser`, `UpdateDate`, `UpdatingIDUser`, `Deleted`, `DeletingIDUser`, `DeleteDate`, `Name`, `Age`) VALUES ( :IDAnimal_0, :GUIDAnimal_1, :CreateDate_2, :CreatingIDUser_3, :UpdateDate_4, :UpdatingIDUser_5, :Deleted_6, :DeletingIDUser_7, :DeleteDate_8, :Name_9, :Age_10);");
609
+ }
610
+ );
611
+ test
612
+ (
613
+ 'Complex Read Query 2, verify checking Deleted bit with no filters',
614
+ function()
615
+ {
616
+ var tmpQuery = libFoxHound.new(_Fable)
617
+ .setDialect('SQLite')
618
+ .setScope('Animal')
619
+ .setDataElements(['Name', 'Age', 'Cost'])
620
+ .setCap(100);
621
+
622
+ //Use a schema that already defines a deleted bit
623
+ tmpQuery.query.schema = _AnimalSchema;
624
+ // Build the query
625
+ tmpQuery.buildReadQuery();
626
+ // This is the query generated by the SQLite dialect
627
+ _Fable.log.trace('Select Query', tmpQuery.query);
628
+ Expect(tmpQuery.query.body)
629
+ .to.equal('SELECT `Name`, `Age`, `Cost` FROM Animal WHERE `Deleted` = :Deleted_w0 LIMIT 100;');
630
+ }
631
+ );
632
+ test
633
+ (
634
+ 'Complex Read Query 2, manually checking Deleted bit with Schema that has one',
635
+ function()
636
+ {
637
+ var tmpQuery = libFoxHound.new(_Fable)
638
+ .setDialect('SQLite')
639
+ .setScope('Animal')
640
+ .setDataElements(['Name', 'Age', 'Cost'])
641
+ .setCap(100)
642
+ .addFilter('Age', '25')
643
+ .addFilter('', '', '(')
644
+ .addFilter('Color', 'Red')
645
+ .addFilter('Color', 'Green', '=', 'OR')
646
+ .addFilter('', '', ')')
647
+ .addFilter('Description', '', 'IS NOT NULL')
648
+ .addFilter('IDOffice', [10, 11, 15, 18, 22], 'IN')
649
+ .addFilter('Deleted', '1');
650
+
651
+ //Use a schema that already defines a deleted bit
652
+ tmpQuery.query.schema = _AnimalSchema;
653
+ // Build the query
654
+ tmpQuery.buildReadQuery();
655
+ // This is the query generated by the SQLite dialect
656
+ _Fable.log.trace('Select Query', tmpQuery.query);
657
+ Expect(tmpQuery.query.body)
658
+ .to.equal('SELECT `Name`, `Age`, `Cost` FROM Animal WHERE `Age` = :Age_w0 AND ( `Color` = :Color_w2 OR `Color` = :Color_w3 ) AND `Description` IS NOT NULL AND `IDOffice` IN ( :IDOffice_w6 ) AND `Deleted` = :Deleted_w7 LIMIT 100;');
659
+ }
660
+ );
661
+ test
662
+ (
663
+ 'Complex Read Query 2, delete tracking disabled',
664
+ function()
665
+ {
666
+ var tmpQuery = libFoxHound.new(_Fable)
667
+ .setDialect('SQLite')
668
+ .setScope('Animal')
669
+ .setDisableDeleteTracking(true)
670
+ .setDataElements(['Name', 'Age', 'Cost'])
671
+ .setCap(100);
672
+
673
+ //Use a schema that already defines a deleted bit
674
+ tmpQuery.query.schema = _AnimalSchema;
675
+ // Build the query
676
+ tmpQuery.buildReadQuery();
677
+ // This is the query generated by the SQLite dialect
678
+ _Fable.log.trace('Select Query', tmpQuery.query);
679
+ Expect(tmpQuery.query.body)
680
+ .to.equal('SELECT `Name`, `Age`, `Cost` FROM Animal LIMIT 100;');
681
+ }
682
+ );
683
+ test
684
+ (
685
+ 'Delete Query with Filters',
686
+ function()
687
+ {
688
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
689
+ .setScope('Animal')
690
+ .addFilter('IDAnimal', 10);
691
+ //Perform delete with no record specified, but has a Deleted bit in the schema
692
+
693
+ //Use a schema that already defines a deleted bit
694
+ tmpQuery.query.schema = _AnimalSchema;
695
+
696
+ // Build the query
697
+ tmpQuery.buildDeleteQuery();
698
+ // This is the query generated by the SQLite dialect
699
+ _Fable.log.trace('Delete Query', tmpQuery.query);
700
+ Expect(tmpQuery.query.body)
701
+ .to.equal('UPDATE Animal SET `UpdateDate` = NOW(), `Deleted` = 1, `DeletingIDUser` = :DeletingIDUser_2, `DeleteDate` = NOW() WHERE `IDAnimal` = :IDAnimal_w0 AND `Deleted` = :Deleted_w1;');
702
+ }
703
+ );
704
+ test
705
+ (
706
+ 'Undelete Query with Deleted Bit',
707
+ function()
708
+ {
709
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
710
+ .setScope('Animal')
711
+ .addFilter('IDAnimal', 10);
712
+
713
+ //Use a schema that already defines a deleted bit
714
+ tmpQuery.query.schema = _AnimalSchema;
715
+
716
+ // Build the query
717
+ tmpQuery.buildUndeleteQuery();
718
+ // This is the query generated by the SQLite dialect
719
+ _Fable.log.trace('Undelete Query', tmpQuery.query);
720
+ Expect(tmpQuery.query.body)
721
+ .to.equal('UPDATE Animal SET `UpdateDate` = NOW(), `UpdatingIDUser` = :UpdatingIDUser_1, `Deleted` = 0 WHERE `IDAnimal` = :IDAnimal_w0;');
722
+ }
723
+ );
724
+ test
725
+ (
726
+ 'Undelete Query without Deleted Bit',
727
+ function()
728
+ {
729
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
730
+ .setScope('Animal')
731
+ .addFilter('IDAnimal', 10);
732
+
733
+ // Build the query
734
+ tmpQuery.buildUndeleteQuery();
735
+ // This is the query generated by the SQLite dialect
736
+ _Fable.log.trace('Undelete Query', tmpQuery.query);
737
+ Expect(tmpQuery.query.body)
738
+ .to.equal('SELECT NULL;');
739
+ }
740
+ );
741
+ test
742
+ (
743
+ 'Update Query -- without Deleted',
744
+ function()
745
+ {
746
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
747
+ .setLogLevel(5)
748
+ .setScope('Animal')
749
+ .addFilter('IDAnimal', 9)
750
+ .addRecord({
751
+ IDAnimal:82,
752
+ GUIDAnimal:'1111-2222-3333-4444-5555-6666-7777',
753
+ CreateDate:false,
754
+ CreatingIDUser:false,
755
+ UpdateDate:false,
756
+ UpdatingIDUser:false,
757
+ Name:'Froo Froo',
758
+ Age:18
759
+ });
760
+ tmpQuery.query.schema = _AnimalSchemaWithoutDeleted;
761
+ // Build the query
762
+ tmpQuery.buildUpdateQuery();
763
+ // This is the query generated by the SQLite dialect
764
+ _Fable.log.trace('Update Query', tmpQuery.query);
765
+ Expect(tmpQuery.query.body)
766
+ .to.equal('UPDATE Animal SET `GUIDAnimal` = :GUIDAnimal_0, `UpdateDate` = NOW(), `UpdatingIDUser` = :UpdatingIDUser_2, `Name` = :Name_3, `Age` = :Age_4 WHERE `IDAnimal` = :IDAnimal_w0;');
767
+ }
768
+ );
769
+ test
770
+ (
771
+ 'Update Query -- without Deleted, UpdateDate and UpdatingIDUser',
772
+ function()
773
+ {
774
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
775
+ .setLogLevel(5)
776
+ .setScope('Animal')
777
+ .addFilter('IDAnimal', 9)
778
+ .setDisableAutoUserStamp(true)
779
+ .setDisableAutoDateStamp(true)
780
+ .addRecord({
781
+ IDAnimal:82,
782
+ GUIDAnimal:'1111-2222-3333-4444-5555-6666-7777',
783
+ CreateDate:false,
784
+ CreatingIDUser:false,
785
+ UpdateDate:false,
786
+ UpdatingIDUser:false,
787
+ Name:'Froo Froo',
788
+ Age:18
789
+ });
790
+ tmpQuery.query.schema = _AnimalSchemaWithoutDeleted;
791
+ // Build the query
792
+ tmpQuery.buildUpdateQuery();
793
+ // This is the query generated by the SQLite dialect
794
+ _Fable.log.trace('Update Query', tmpQuery.query);
795
+ Expect(tmpQuery.query.body)
796
+ .to.equal('UPDATE Animal SET `GUIDAnimal` = :GUIDAnimal_0, `Name` = :Name_1, `Age` = :Age_2 WHERE `IDAnimal` = :IDAnimal_w0;');
797
+ }
798
+ );
799
+ test
800
+ (
801
+ 'Delete Query -- without Deleted',
802
+ function()
803
+ {
804
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
805
+ .setLogLevel(5)
806
+ .setScope('Animal')
807
+ .addFilter('IDAnimal', 9)
808
+ .addRecord({
809
+ IDAnimal:82,
810
+ GUIDAnimal:'1111-2222-3333-4444-5555-6666-7777'
811
+ });
812
+ tmpQuery.query.schema = _AnimalSchemaWithoutDeleted;
813
+ // Build the query
814
+ tmpQuery.buildDeleteQuery();
815
+ // This is the query generated by the SQLite dialect
816
+ _Fable.log.trace('Delete Query', tmpQuery.query);
817
+ Expect(tmpQuery.query.body)
818
+ .to.equal('DELETE FROM Animal WHERE `IDAnimal` = :IDAnimal_w0;');
819
+ }
820
+ );
821
+ test
822
+ (
823
+ 'Update Query',
824
+ function()
825
+ {
826
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
827
+ .setLogLevel(5)
828
+ .setScope('Animal')
829
+ .addFilter('IDAnimal', 9)
830
+ .addFilter('Deleted', 0) //cover case where this can be overridden instead of automatically added
831
+ .addRecord({
832
+ IDAnimal:82,
833
+ GUIDAnimal:'1111-2222-3333-4444-5555-6666-7777',
834
+ CreateDate:false,
835
+ CreatingIDUser:false,
836
+ UpdateDate:false,
837
+ UpdatingIDUser:false,
838
+ Deleted:false,
839
+ DeletingIDUser:false,
840
+ DeleteDate:false,
841
+ Name:'Froo Froo',
842
+ Age:18
843
+ });
844
+ tmpQuery.query.schema = _AnimalSchema;
845
+ // Build the query
846
+ tmpQuery.buildUpdateQuery();
847
+ // This is the query generated by the SQLite dialect
848
+ _Fable.log.trace('Update Query', tmpQuery.query);
849
+ Expect(tmpQuery.query.body)
850
+ .to.equal('UPDATE Animal SET `GUIDAnimal` = :GUIDAnimal_0, `UpdateDate` = NOW(), `UpdatingIDUser` = :UpdatingIDUser_2, `Deleted` = :Deleted_3, `Name` = :Name_4, `Age` = :Age_5 WHERE `IDAnimal` = :IDAnimal_w0 AND `Deleted` = :Deleted_w1;');
851
+ }
852
+ );
853
+ test
854
+ (
855
+ 'Delete Query',
856
+ function()
857
+ {
858
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
859
+ .setLogLevel(5)
860
+ .setScope('Animal')
861
+ .addFilter('IDAnimal', 9)
862
+ .addRecord({
863
+ IDAnimal:82,
864
+ GUIDAnimal:'1111-2222-3333-4444-5555-6666-7777'
865
+ });
866
+ tmpQuery.query.schema = _AnimalSchema;
867
+ // Build the query
868
+ tmpQuery.buildDeleteQuery();
869
+ // This is the query generated by the SQLite dialect
870
+ _Fable.log.trace('Delete Query', tmpQuery.query);
871
+ Expect(tmpQuery.query.body)
872
+ .to.equal('UPDATE Animal SET `UpdateDate` = NOW(), `Deleted` = 1, `DeletingIDUser` = :DeletingIDUser_2, `DeleteDate` = NOW() WHERE `IDAnimal` = :IDAnimal_w0 AND `Deleted` = :Deleted_w1;');
873
+ }
874
+ );
875
+ test
876
+ (
877
+ 'Delete Query with Delete Tracking Disabled',
878
+ function()
879
+ {
880
+ var tmpQuery = libFoxHound.new(_Fable).setDialect('SQLite')
881
+ .setLogLevel(5)
882
+ .setScope('Animal')
883
+ .setDisableDeleteTracking(true)
884
+ .addFilter('IDAnimal', 9)
885
+ .addRecord({
886
+ IDAnimal:82,
887
+ GUIDAnimal:'1111-2222-3333-4444-5555-6666-7777'
888
+ });
889
+ tmpQuery.query.schema = _AnimalSchema;
890
+ // Build the query
891
+ tmpQuery.buildDeleteQuery();
892
+ // This is the query generated by the SQLite dialect
893
+ _Fable.log.trace('Delete Query', tmpQuery.query);
894
+ Expect(tmpQuery.query.body)
895
+ .to.equal('DELETE FROM Animal WHERE `IDAnimal` = :IDAnimal_w0;');
896
+ }
897
+ );
898
+ }
899
+ );
900
+ }
901
+ );