@platformatic/sql-mapper 0.45.1 → 0.46.2

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.
@@ -1,1125 +0,0 @@
1
- 'use strict'
2
-
3
- const { test } = require('tap')
4
- const { clear, connInfo, isSQLite, isMysql, isPg, isMysql8 } = require('./helper')
5
- const { connect } = require('..')
6
- const fakeLogger = {
7
- // trace: (...args) => { console.log(JSON.stringify(args, null, 2)) },
8
- trace: () => {},
9
- error: () => {}
10
- }
11
-
12
- test('entity fields', async ({ equal, not, same, teardown }) => {
13
- async function onDatabaseLoad (db, sql) {
14
- await clear(db, sql)
15
- teardown(() => db.dispose())
16
-
17
- if (isSQLite) {
18
- await db.query(sql`CREATE TABLE pages (
19
- id INTEGER PRIMARY KEY,
20
- title VARCHAR(42)
21
- );`)
22
- } else {
23
- await db.query(sql`CREATE TABLE pages (
24
- id SERIAL PRIMARY KEY,
25
- title VARCHAR(255) NOT NULL
26
- );`)
27
- }
28
- }
29
- const mapper = await connect({
30
- connectionString: connInfo.connectionString,
31
- log: fakeLogger,
32
- onDatabaseLoad,
33
- ignore: {},
34
- hooks: {}
35
- })
36
- const pageEntity = mapper.entities.page
37
- not(pageEntity, undefined)
38
- equal(pageEntity.name, 'Page')
39
- equal(pageEntity.singularName, 'page')
40
- equal(pageEntity.pluralName, 'pages')
41
- same(pageEntity.primaryKeys, new Set(['id']))
42
- equal(pageEntity.table, 'pages')
43
- equal(pageEntity.camelCasedFields.id.primaryKey, true)
44
- })
45
-
46
- test('entity API', async ({ equal, same, teardown, rejects }) => {
47
- async function onDatabaseLoad (db, sql) {
48
- await clear(db, sql)
49
- teardown(() => db.dispose())
50
- if (isSQLite) {
51
- await db.query(sql`CREATE TABLE pages (
52
- id INTEGER PRIMARY KEY,
53
- the_title VARCHAR(42),
54
- is_published BOOLEAN NOT NULL
55
- );`)
56
- } else {
57
- await db.query(sql`CREATE TABLE pages (
58
- id SERIAL PRIMARY KEY,
59
- the_title VARCHAR(255) NOT NULL,
60
- is_published BOOLEAN NOT NULL
61
- );`)
62
- }
63
- await db.query(sql`INSERT INTO pages (the_title, is_published) VALUES ('foo', true)`)
64
- await db.query(sql`INSERT INTO pages (the_title, is_published) VALUES ('bar', false)`)
65
- }
66
- const mapper = await connect({
67
- connectionString: connInfo.connectionString,
68
- log: fakeLogger,
69
- onDatabaseLoad,
70
- ignore: {},
71
- hooks: {}
72
- })
73
- const pageEntity = mapper.entities.page
74
- // fixInput
75
- const fixedInput = pageEntity.fixInput({ id: 42, theTitle: 'Fixme', isPublished: true })
76
- same(fixedInput, { id: 42, the_title: 'Fixme', is_published: true })
77
-
78
- // fixOutput
79
- const fixedOutput = pageEntity.fixOutput({
80
- id: 42,
81
- the_title: 'Fixme',
82
- is_published: true
83
- })
84
-
85
- same(fixedOutput, { id: 42, theTitle: 'Fixme', isPublished: true })
86
-
87
- // empty fixOutput
88
- same(pageEntity.fixOutput(undefined), undefined)
89
-
90
- // find
91
- const findResult = await pageEntity.find({ fields: ['theTitle'] })
92
- same(findResult, [{ theTitle: 'foo' }, { theTitle: 'bar' }])
93
-
94
- // count
95
- const countResult = await pageEntity.count({ fields: ['theTitle'] })
96
- same(countResult, 2)
97
-
98
- // insert - single
99
- const insertResult = await pageEntity.insert({
100
- inputs: [{ theTitle: 'foobar', isPublished: false }],
101
- fields: ['id', 'theTitle', 'isPublished']
102
- })
103
- same(insertResult, [{ id: '3', theTitle: 'foobar', isPublished: false }])
104
-
105
- // insert - multiple
106
- const insertMultipleResult = await pageEntity.insert({
107
- inputs: [
108
- { theTitle: 'platformatic', isPublished: false },
109
- { theTitle: 'foobar', isPublished: true }
110
- ],
111
- fields: ['id', 'theTitle', 'isPublished']
112
- })
113
- same(insertMultipleResult, [
114
- { id: '4', theTitle: 'platformatic', isPublished: false },
115
- { id: '5', theTitle: 'foobar', isPublished: true }
116
- ])
117
-
118
- // save - new record
119
- same(await pageEntity.save({
120
- input: { theTitle: 'fourth page', isPublished: false },
121
- fields: ['id', 'theTitle', 'isPublished']
122
- }), { id: 6, theTitle: 'fourth page', isPublished: false })
123
-
124
- // save - update record
125
- same(await pageEntity.save({
126
- input: { id: 4, theTitle: 'foofoo', isPublished: true },
127
- fields: ['id', 'theTitle', 'isPublished']
128
- }), { id: '4', theTitle: 'foofoo', isPublished: true })
129
-
130
- // save - empty object
131
- rejects(async () => {
132
- await pageEntity.save({})
133
- }, Error, 'Input not provided.')
134
-
135
- rejects(async () => {
136
- await pageEntity.save({ input: { fakeColumn: 'foobar' } })
137
- })
138
- // delete
139
- same(await pageEntity.delete({
140
- where: {
141
- id: {
142
- eq: 2
143
- }
144
- },
145
- fields: ['id', 'theTitle']
146
- }), [{ id: '2', theTitle: 'bar' }])
147
- })
148
-
149
- test('empty save', async ({ equal, same, teardown, rejects }) => {
150
- async function onDatabaseLoad (db, sql) {
151
- await clear(db, sql)
152
- teardown(() => db.dispose())
153
- if (isSQLite) {
154
- await db.query(sql`CREATE TABLE pages (
155
- id INTEGER PRIMARY KEY,
156
- the_title VARCHAR(42)
157
- );`)
158
- } else {
159
- await db.query(sql`CREATE TABLE pages (
160
- id SERIAL PRIMARY KEY,
161
- the_title VARCHAR(255)
162
- );`)
163
- }
164
- }
165
- const mapper = await connect({
166
- connectionString: connInfo.connectionString,
167
- log: fakeLogger,
168
- onDatabaseLoad,
169
- ignore: {},
170
- hooks: {}
171
- })
172
-
173
- const insertResult = await mapper.entities.page.save({
174
- input: {},
175
- fields: ['id', 'theTitle']
176
- })
177
- same(insertResult, { id: '1', theTitle: null })
178
- })
179
-
180
- test('insert with explicit integer PK value', async ({ same, teardown }) => {
181
- async function onDatabaseLoad (db, sql) {
182
- await clear(db, sql)
183
- teardown(() => db.dispose())
184
- await db.query(sql`CREATE TABLE pages (
185
- id INTEGER PRIMARY KEY,
186
- title varchar(255) NOT NULL
187
- );`)
188
- }
189
- const mapper = await connect({
190
- connectionString: connInfo.connectionString,
191
- log: fakeLogger,
192
- onDatabaseLoad,
193
- ignore: {},
194
- hooks: {}
195
- })
196
- const pageEntity = mapper.entities.page
197
- const [newPage] = await pageEntity.insert({
198
- fields: ['id', 'title'],
199
- inputs: [{ id: 13, title: '13th page with explicit id equal to 13' }]
200
- })
201
- same(newPage, {
202
- id: '13',
203
- title: '13th page with explicit id equal to 13'
204
- })
205
- })
206
-
207
- test('insert with explicit uuid PK value', { skip: !isSQLite }, async ({ same, teardown }) => {
208
- async function onDatabaseLoad (db, sql) {
209
- await clear(db, sql)
210
- teardown(() => db.dispose())
211
- await db.query(sql`CREATE TABLE pages (
212
- id uuid PRIMARY KEY,
213
- title varchar(255) NOT NULL
214
- );`)
215
- }
216
- const mapper = await connect({
217
- connectionString: connInfo.connectionString,
218
- log: fakeLogger,
219
- onDatabaseLoad,
220
- ignore: {},
221
- hooks: {}
222
- })
223
-
224
- const pageEntity = mapper.entities.page
225
- const [newPage] = await pageEntity.insert({
226
- fields: ['id', 'title'],
227
- inputs: [{
228
- id: '00000000-0000-0000-0000-000000000013',
229
- title: '13th page with explicit id equal to 13'
230
- }]
231
- })
232
- same(newPage, {
233
- id: '00000000-0000-0000-0000-000000000013',
234
- title: '13th page with explicit id equal to 13'
235
- })
236
- })
237
-
238
- test('insert with explicit uuid PK value without rowid', { skip: !isSQLite }, async ({ same, teardown }) => {
239
- async function onDatabaseLoad (db, sql) {
240
- await clear(db, sql)
241
- teardown(() => db.dispose())
242
- await db.query(sql`CREATE TABLE pages (
243
- id uuid PRIMARY KEY,
244
- title varchar(255) NOT NULL
245
- ) WITHOUT ROWID;`)
246
- }
247
- const mapper = await connect({
248
- connectionString: connInfo.connectionString,
249
- log: fakeLogger,
250
- onDatabaseLoad,
251
- ignore: {},
252
- hooks: {}
253
- })
254
-
255
- const pageEntity = mapper.entities.page
256
- const [newPage] = await pageEntity.insert({
257
- fields: ['id', 'title'],
258
- inputs: [{
259
- id: '00000000-0000-0000-0000-000000000013',
260
- title: '13th page with explicit id equal to 13'
261
- }]
262
- })
263
- same(newPage, {
264
- id: '00000000-0000-0000-0000-000000000013',
265
- title: '13th page with explicit id equal to 13'
266
- })
267
- })
268
-
269
- test('insert without fields to retrieve', { skip: !isSQLite }, async ({ same, teardown }) => {
270
- async function onDatabaseLoad (db, sql) {
271
- await clear(db, sql)
272
- teardown(() => db.dispose())
273
- await db.query(sql`CREATE TABLE pages (
274
- id INTEGER PRIMARY KEY,
275
- title varchar(255) NOT NULL
276
- );`)
277
- }
278
- const mapper = await connect({
279
- connectionString: connInfo.connectionString,
280
- log: fakeLogger,
281
- onDatabaseLoad,
282
- ignore: {},
283
- hooks: {}
284
- })
285
-
286
- const pageEntity = mapper.entities.page
287
- await pageEntity.insert({
288
- fields: [],
289
- inputs: [{
290
- id: '13',
291
- title: '13th page with explicit id equal to 13'
292
- }]
293
- })
294
-
295
- const [newPage] = await pageEntity.find({
296
- where: {
297
- id: {
298
- eq: '13'
299
- }
300
- }
301
- })
302
-
303
- same(newPage, {
304
- id: '13',
305
- title: '13th page with explicit id equal to 13'
306
- })
307
- })
308
-
309
- test('[SQLite] - UUID', { skip: !isSQLite }, async ({ pass, teardown, same, equal }) => {
310
- const mapper = await connect({
311
- connectionString: connInfo.connectionString,
312
- log: fakeLogger,
313
- ignore: {},
314
- hooks: {},
315
- async onDatabaseLoad (db, sql) {
316
- pass('onDatabaseLoad called')
317
-
318
- await clear(db, sql)
319
-
320
- await db.query(sql`
321
- CREATE TABLE pages (
322
- id uuid PRIMARY KEY,
323
- title VARCHAR(42)
324
- );`)
325
- }
326
- })
327
- teardown(() => mapper.db.dispose())
328
-
329
- const pageEntity = mapper.entities.page
330
-
331
- let id
332
- {
333
- const res = await pageEntity.save({ input: { title: 'Hello' } })
334
- id = res.id
335
- same(res, {
336
- id,
337
- title: 'Hello'
338
- })
339
- }
340
-
341
- {
342
- const res = await pageEntity.find({ where: { id: { eq: id } } })
343
- same(res, [{
344
- id,
345
- title: 'Hello'
346
- }])
347
- }
348
-
349
- {
350
- const res = await pageEntity.save({ input: { id, title: 'Hello World' } })
351
- same(res, {
352
- id,
353
- title: 'Hello World'
354
- })
355
- }
356
- })
357
-
358
- test('[SQLite] allows to have VARCHAR PK', { skip: !isSQLite }, async ({ same, teardown }) => {
359
- async function onDatabaseLoad (db, sql) {
360
- await clear(db, sql)
361
- teardown(() => db.dispose())
362
-
363
- await db.query(sql`CREATE TABLE pages (
364
- id varchar(255) PRIMARY KEY,
365
- title varchar(255) NOT NULL
366
- );`)
367
- }
368
- const mapper = await connect({
369
- connectionString: connInfo.connectionString,
370
- log: fakeLogger,
371
- onDatabaseLoad,
372
- ignore: {},
373
- hooks: {}
374
- })
375
- const pageEntity = mapper.entities.page
376
- const [newPage] = await pageEntity.insert({
377
- fields: ['id', 'title'],
378
- inputs: [{ id: 'varchar_id', title: '13th page with explicit id equal to 13' }]
379
- })
380
- same(newPage, {
381
- id: 'varchar_id',
382
- title: '13th page with explicit id equal to 13'
383
- })
384
- })
385
-
386
- test('mixing snake and camel case', async ({ pass, teardown, same, equal }) => {
387
- async function onDatabaseLoad (db, sql) {
388
- await clear(db, sql)
389
- teardown(() => db.dispose())
390
-
391
- if (isMysql) {
392
- await db.query(sql`
393
- CREATE TABLE categories (
394
- id SERIAL PRIMARY KEY,
395
- name VARCHAR(255)
396
- );
397
- CREATE TABLE pages (
398
- id SERIAL PRIMARY KEY,
399
- title VARCHAR(255),
400
- body_content TEXT,
401
- category_id BIGINT UNSIGNED,
402
- FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
403
- );
404
- `)
405
- } else if (isSQLite) {
406
- await db.query(sql`
407
- CREATE TABLE "categories" (
408
- "id" INTEGER PRIMARY KEY,
409
- "name" TEXT NOT NULL
410
- );
411
- `)
412
- await db.query(sql`
413
- CREATE TABLE "pages" (
414
- "id" INTEGER PRIMARY KEY,
415
- "title" TEXT NOT NULL,
416
- "body_content" TEXT
417
- );
418
- `)
419
- await db.query(sql`
420
- ALTER TABLE "pages" ADD COLUMN "category_id" REFERENCES "categories"("id");
421
- `)
422
- } else {
423
- await db.query(sql`
424
- CREATE TABLE categories (
425
- id SERIAL PRIMARY KEY,
426
- name varchar(255) NOT NULL
427
- );
428
-
429
- CREATE TABLE pages (
430
- id SERIAL PRIMARY KEY,
431
- title varchar(255) NOT NULL,
432
- body_content text,
433
- category_id int NOT NULL REFERENCES categories(id)
434
- );
435
- `)
436
- }
437
- }
438
-
439
- const mapper = await connect({
440
- connectionString: connInfo.connectionString,
441
- log: fakeLogger,
442
- onDatabaseLoad,
443
- ignore: {},
444
- hooks: {}
445
- })
446
-
447
- const pageEntity = mapper.entities.page
448
- const categoryEntity = mapper.entities.category
449
-
450
- const [newCategory] = await categoryEntity.insert({
451
- fields: ['id', 'name'],
452
- inputs: [{ name: 'fiction' }]
453
- })
454
-
455
- {
456
- const res = await pageEntity.insert({
457
- fields: ['id', 'title', 'categoryId'],
458
- inputs: [
459
- {
460
- title: 'A fiction', bodyContent: 'This is our first fiction', categoryId: newCategory.id
461
- },
462
- {
463
- title: 'A fiction', body_content: 'This is our first fiction', category_id: newCategory.id
464
- }
465
-
466
- ]
467
- })
468
- same(res, [{
469
- id: '1',
470
- title: 'A fiction',
471
- categoryId: newCategory.id
472
- }, {
473
- id: '2',
474
- title: 'A fiction',
475
- categoryId: newCategory.id
476
- }])
477
- }
478
-
479
- {
480
- const res = await pageEntity.save({
481
- fields: ['id', 'title', 'categoryId'],
482
- input: {
483
- title: 'A fiction', body_content: 'This is our first fiction', category_id: newCategory.id
484
- }
485
- })
486
- same(res, {
487
- id: '3',
488
- title: 'A fiction',
489
- categoryId: newCategory.id
490
- })
491
- }
492
- })
493
-
494
- test('only include wanted fields - with foreign', async ({ pass, teardown, same, equal }) => {
495
- async function onDatabaseLoad (db, sql) {
496
- await clear(db, sql)
497
- teardown(() => db.dispose())
498
-
499
- if (isMysql) {
500
- await db.query(sql`
501
- CREATE TABLE categories (
502
- id SERIAL PRIMARY KEY,
503
- name VARCHAR(255)
504
- );
505
- CREATE TABLE pages (
506
- id SERIAL PRIMARY KEY,
507
- title VARCHAR(255),
508
- body_content TEXT,
509
- category_id BIGINT UNSIGNED,
510
- FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
511
- );
512
- `)
513
- } else if (isSQLite) {
514
- await db.query(sql`
515
- CREATE TABLE "categories" (
516
- "id" INTEGER PRIMARY KEY,
517
- "name" TEXT NOT NULL
518
- );
519
- `)
520
- await db.query(sql`
521
- CREATE TABLE "pages" (
522
- "id" INTEGER PRIMARY KEY,
523
- "title" TEXT NOT NULL,
524
- "body_content" TEXT
525
- );
526
- `)
527
- await db.query(sql`
528
- ALTER TABLE "pages" ADD COLUMN "category_id" REFERENCES "categories"("id");
529
- `)
530
- } else {
531
- await db.query(sql`
532
- CREATE TABLE categories (
533
- id SERIAL PRIMARY KEY,
534
- name varchar(255) NOT NULL
535
- );
536
-
537
- CREATE TABLE pages (
538
- id SERIAL PRIMARY KEY,
539
- title varchar(255) NOT NULL,
540
- body_content text,
541
- category_id int NOT NULL REFERENCES categories(id)
542
- );
543
- `)
544
- }
545
- }
546
-
547
- const mapper = await connect({
548
- connectionString: connInfo.connectionString,
549
- log: fakeLogger,
550
- onDatabaseLoad,
551
- ignore: {},
552
- hooks: {}
553
- })
554
-
555
- const pageEntity = mapper.entities.page
556
- const categoryEntity = mapper.entities.category
557
-
558
- const [newCategory] = await categoryEntity.insert({
559
- fields: ['id', 'name'],
560
- inputs: [{ name: 'fiction' }]
561
- })
562
-
563
- {
564
- const fields = ['id', 'category_id']
565
- const res = await pageEntity.insert({
566
- fields,
567
- inputs: [
568
- {
569
- title: 'A fiction', bodyContent: 'This is our first fiction', categoryId: newCategory.id
570
- }
571
- ]
572
- })
573
- same(res, [{
574
- id: '1',
575
- categoryId: newCategory.id
576
- }])
577
- }
578
- })
579
-
580
- test('only include wanted fields - without foreign', async ({ pass, teardown, same, equal }) => {
581
- async function onDatabaseLoad (db, sql) {
582
- await clear(db, sql)
583
- teardown(() => db.dispose())
584
-
585
- if (isMysql) {
586
- await db.query(sql`
587
- CREATE TABLE categories (
588
- id SERIAL PRIMARY KEY,
589
- name VARCHAR(255)
590
- );
591
- CREATE TABLE pages (
592
- id SERIAL PRIMARY KEY,
593
- title VARCHAR(255),
594
- body_content TEXT,
595
- category_id BIGINT UNSIGNED,
596
- FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
597
- );
598
- `)
599
- } else if (isSQLite) {
600
- await db.query(sql`
601
- CREATE TABLE "categories" (
602
- "id" INTEGER PRIMARY KEY,
603
- "name" TEXT NOT NULL
604
- );
605
- `)
606
- await db.query(sql`
607
- CREATE TABLE "pages" (
608
- "id" INTEGER PRIMARY KEY,
609
- "title" TEXT NOT NULL,
610
- "body_content" TEXT
611
- );
612
- `)
613
- await db.query(sql`
614
- ALTER TABLE "pages" ADD COLUMN "category_id" REFERENCES "categories"("id");
615
- `)
616
- } else {
617
- await db.query(sql`
618
- CREATE TABLE categories (
619
- id SERIAL PRIMARY KEY,
620
- name varchar(255) NOT NULL
621
- );
622
-
623
- CREATE TABLE pages (
624
- id SERIAL PRIMARY KEY,
625
- title varchar(255) NOT NULL,
626
- body_content text,
627
- category_id int NOT NULL REFERENCES categories(id)
628
- );
629
- `)
630
- }
631
- }
632
-
633
- const mapper = await connect({
634
- connectionString: connInfo.connectionString,
635
- log: fakeLogger,
636
- onDatabaseLoad,
637
- ignore: {},
638
- hooks: {}
639
- })
640
-
641
- const pageEntity = mapper.entities.page
642
- const categoryEntity = mapper.entities.category
643
-
644
- const [newCategory] = await categoryEntity.insert({
645
- fields: ['id', 'name'],
646
- inputs: [{ name: 'fiction' }]
647
- })
648
-
649
- {
650
- const fields = ['id', 'title']
651
- const res = await pageEntity.insert({
652
- fields,
653
- inputs: [
654
- {
655
- title: 'A fiction', bodyContent: 'This is our first fiction', categoryId: newCategory.id
656
- }
657
- ]
658
- })
659
- same(res, [{
660
- id: '1',
661
- title: 'A fiction'
662
- }])
663
- }
664
- })
665
-
666
- test('include all fields', async ({ pass, teardown, same, equal }) => {
667
- async function onDatabaseLoad (db, sql) {
668
- await clear(db, sql)
669
- teardown(() => db.dispose())
670
-
671
- if (isMysql) {
672
- await db.query(sql`
673
- CREATE TABLE categories (
674
- id SERIAL PRIMARY KEY,
675
- name VARCHAR(255)
676
- );
677
- CREATE TABLE pages (
678
- id SERIAL PRIMARY KEY,
679
- title VARCHAR(255),
680
- body_content TEXT,
681
- category_id BIGINT UNSIGNED,
682
- FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
683
- );
684
- `)
685
- } else if (isSQLite) {
686
- await db.query(sql`
687
- CREATE TABLE "categories" (
688
- "id" INTEGER PRIMARY KEY,
689
- "name" TEXT NOT NULL
690
- );
691
- `)
692
- await db.query(sql`
693
- CREATE TABLE "pages" (
694
- "id" INTEGER PRIMARY KEY,
695
- "title" TEXT NOT NULL,
696
- "body_content" TEXT
697
- );
698
- `)
699
- await db.query(sql`
700
- ALTER TABLE "pages" ADD COLUMN "category_id" REFERENCES "categories"("id");
701
- `)
702
- } else {
703
- await db.query(sql`
704
- CREATE TABLE categories (
705
- id SERIAL PRIMARY KEY,
706
- name varchar(255) NOT NULL
707
- );
708
-
709
- CREATE TABLE pages (
710
- id SERIAL PRIMARY KEY,
711
- title varchar(255) NOT NULL,
712
- body_content text,
713
- category_id int NOT NULL REFERENCES categories(id)
714
- );
715
- `)
716
- }
717
- }
718
-
719
- const mapper = await connect({
720
- connectionString: connInfo.connectionString,
721
- log: fakeLogger,
722
- onDatabaseLoad,
723
- ignore: {},
724
- hooks: {}
725
- })
726
-
727
- const pageEntity = mapper.entities.page
728
- const categoryEntity = mapper.entities.category
729
-
730
- const [newCategory] = await categoryEntity.insert({
731
- fields: ['id', 'name'],
732
- inputs: [{ name: 'fiction' }]
733
- })
734
-
735
- {
736
- const res = await pageEntity.insert({
737
- inputs: [
738
- {
739
- title: 'A fiction', bodyContent: 'This is our first fiction', categoryId: newCategory.id
740
- }
741
- ]
742
- })
743
- same(res, [{
744
- id: '1',
745
- title: 'A fiction',
746
- bodyContent: 'This is our first fiction',
747
- categoryId: newCategory.id
748
- }])
749
- }
750
- })
751
-
752
- test('include possible values of enum columns', { skip: isSQLite }, async ({ same, teardown }) => {
753
- async function onDatabaseLoad (db, sql) {
754
- await clear(db, sql)
755
- teardown(() => db.dispose())
756
-
757
- if (isPg) {
758
- await db.query(sql`
759
- CREATE TYPE pagetype as enum ('blank', 'non-blank');
760
- CREATE TABLE pages (
761
- id INTEGER PRIMARY KEY,
762
- title VARCHAR(42),
763
- type pagetype
764
- );`)
765
- } else {
766
- await db.query(sql`CREATE TABLE pages (
767
- id INTEGER PRIMARY KEY,
768
- title VARCHAR(42),
769
- type ENUM ('blank', 'non-blank')
770
- );
771
- `)
772
- }
773
- }
774
- const mapper = await connect({
775
- connectionString: connInfo.connectionString,
776
- log: fakeLogger,
777
- onDatabaseLoad,
778
- ignore: {},
779
- hooks: {}
780
- })
781
- const pageEntity = mapper.entities.page
782
- const typeField = pageEntity.fields.type
783
- same(typeField.enum, ['blank', 'non-blank'])
784
- })
785
-
786
- test('JSON type', { skip: !(isPg || isMysql8) }, async ({ teardown, same, equal, pass }) => {
787
- async function onDatabaseLoad (db, sql) {
788
- await clear(db, sql)
789
- teardown(() => db.dispose())
790
-
791
- await db.query(sql`CREATE TABLE simple_types (
792
- id SERIAL PRIMARY KEY,
793
- config json NOT NULL
794
- );`)
795
- }
796
- const mapper = await connect({
797
- connectionString: connInfo.connectionString,
798
- log: fakeLogger,
799
- onDatabaseLoad,
800
- ignore: {},
801
- hooks: {}
802
- })
803
-
804
- const simpleType = mapper.entities.simpleType
805
-
806
- // save - new record
807
- same(await simpleType.save({
808
- input: { config: { foo: 'bar' } }
809
- }), { id: 1, config: { foo: 'bar' } })
810
-
811
- // save - update
812
- same(await simpleType.save({
813
- input: { id: 1, config: { foo: 'bar', bar: 'foo' } }
814
- }), { id: 1, config: { foo: 'bar', bar: 'foo' } })
815
-
816
- // insert
817
- same(await simpleType.insert({
818
- inputs: [{ config: { foo: 'bar' } }]
819
- }), [{ id: 2, config: { foo: 'bar' } }])
820
-
821
- // updateMany
822
- same(await simpleType.updateMany({
823
- where: {
824
- id: {
825
- eq: 2
826
- }
827
- },
828
- input: {
829
- config: {
830
- foo: 'bar',
831
- bar: 'foo'
832
- }
833
- }
834
- }), [{ id: 2, config: { foo: 'bar', bar: 'foo' } }])
835
- })
836
-
837
- test('stored and virtual generated columns should return for SQLite', { skip: !(isSQLite) }, async ({ teardown, same }) => {
838
- async function onDatabaseLoad (db, sql) {
839
- await clear(db, sql)
840
- teardown(() => db.dispose())
841
-
842
- await db.query(sql`CREATE TABLE generated_test (
843
- id INTEGER PRIMARY KEY,
844
- test INTEGER,
845
- test_stored INTEGER GENERATED ALWAYS AS (test*2) STORED,
846
- test_virtual INTEGER GENERATED ALWAYS AS (test*4) VIRTUAL
847
- );`)
848
- }
849
-
850
- const mapper = await connect({
851
- connectionString: connInfo.connectionString,
852
- log: fakeLogger,
853
- onDatabaseLoad,
854
- ignore: {},
855
- hooks: {}
856
- })
857
-
858
- const generatedTest = mapper.entities.generatedTest
859
-
860
- // save - new record
861
- same(await generatedTest.save({
862
- input: { test: 1 }
863
- }), { id: 1, test: 1, testStored: 2, testVirtual: 4 })
864
-
865
- // save - update
866
- same(await generatedTest.save({
867
- input: { id: 1, test: 2 }
868
- }), { id: 1, test: 2, testStored: 4, testVirtual: 8 })
869
-
870
- // insert
871
- same(await generatedTest.insert({
872
- inputs: [{ test: 4 }]
873
- }), [{ id: 2, test: 4, testStored: 8, testVirtual: 16 }])
874
-
875
- // updateMany
876
- same(await generatedTest.updateMany({
877
- where: {
878
- id: {
879
- eq: 2
880
- }
881
- },
882
- input: {
883
- test: 8
884
- }
885
- }), [{ id: 2, test: 8, testStored: 16, testVirtual: 32 }])
886
- })
887
-
888
- test('stored generated columns should return for pg', { skip: !(isPg) }, async ({ teardown, same }) => {
889
- async function onDatabaseLoad (db, sql) {
890
- await clear(db, sql)
891
- teardown(() => db.dispose())
892
-
893
- await db.query(sql`CREATE TABLE generated_test (
894
- id SERIAL PRIMARY KEY,
895
- test INTEGER,
896
- test_stored INTEGER GENERATED ALWAYS AS (test*2) STORED
897
- );`)
898
- }
899
-
900
- const mapper = await connect({
901
- connectionString: connInfo.connectionString,
902
- log: fakeLogger,
903
- onDatabaseLoad,
904
- ignore: {},
905
- hooks: {}
906
- })
907
-
908
- const generatedTest = mapper.entities.generatedTest
909
-
910
- // save - new record
911
- same(await generatedTest.save({
912
- input: { test: 1 }
913
- }), { id: 1, test: 1, testStored: 2 })
914
-
915
- // save - update
916
- same(await generatedTest.save({
917
- input: { id: 1, test: 2 }
918
- }), { id: 1, test: 2, testStored: 4 })
919
-
920
- // insert
921
- same(await generatedTest.insert({
922
- inputs: [{ test: 4 }]
923
- }), [{ id: 2, test: 4, testStored: 8 }])
924
-
925
- // updateMany
926
- same(await generatedTest.updateMany({
927
- where: {
928
- id: {
929
- eq: 2
930
- }
931
- },
932
- input: {
933
- test: 8
934
- }
935
- }), [{ id: 2, test: 8, testStored: 16 }])
936
- })
937
-
938
- test('stored and virtual generated columns should return for pg', { skip: (isPg || isSQLite) }, async ({ teardown, same }) => {
939
- async function onDatabaseLoad (db, sql) {
940
- await clear(db, sql)
941
- teardown(() => db.dispose())
942
-
943
- await db.query(sql`CREATE TABLE generated_test (
944
- id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
945
- test INTEGER,
946
- test_stored INTEGER GENERATED ALWAYS AS (test*2) STORED,
947
- test_virtual INTEGER GENERATED ALWAYS AS (test*4) VIRTUAL
948
- );`)
949
- }
950
-
951
- const mapper = await connect({
952
- connectionString: connInfo.connectionString,
953
- log: fakeLogger,
954
- onDatabaseLoad,
955
- ignore: {},
956
- hooks: {}
957
- })
958
-
959
- const generatedTest = mapper.entities.generatedTest
960
-
961
- // save - new record
962
- same(await generatedTest.save({
963
- input: { test: 1 }
964
- }), { id: 1, test: 1, testStored: 2, testVirtual: 4 })
965
-
966
- // save - update
967
- same(await generatedTest.save({
968
- input: { id: 1, test: 2 }
969
- }), { id: 1, test: 2, testStored: 4, testVirtual: 8 })
970
-
971
- // insert
972
- same(await generatedTest.insert({
973
- inputs: [{ test: 4 }]
974
- }), [{ id: 2, test: 4, testStored: 8, testVirtual: 16 }])
975
-
976
- // updateMany
977
- same(await generatedTest.updateMany({
978
- where: {
979
- id: {
980
- eq: 2
981
- }
982
- },
983
- input: {
984
- test: 8
985
- }
986
- }), [{ id: 2, test: 8, testStored: 16, testVirtual: 32 }])
987
- })
988
-
989
- test('nested transactions', async ({ equal, same, teardown, rejects }) => {
990
- async function onDatabaseLoad (db, sql) {
991
- await clear(db, sql)
992
- teardown(() => db.dispose())
993
- if (isSQLite) {
994
- await db.query(sql`CREATE TABLE pages (
995
- id INTEGER PRIMARY KEY,
996
- the_title VARCHAR(42)
997
- );`)
998
- } else {
999
- await db.query(sql`CREATE TABLE pages (
1000
- id SERIAL PRIMARY KEY,
1001
- the_title VARCHAR(255)
1002
- );`)
1003
- }
1004
- }
1005
- const mapper = await connect({
1006
- connectionString: connInfo.connectionString,
1007
- log: fakeLogger,
1008
- onDatabaseLoad,
1009
- ignore: {},
1010
- hooks: {}
1011
- })
1012
-
1013
- await mapper.db.tx(async (tx) => {
1014
- const insertResult = await mapper.entities.page.save({
1015
- input: {},
1016
- fields: ['id', 'theTitle'],
1017
- tx
1018
- })
1019
- same(insertResult, { id: '1', theTitle: null })
1020
- })
1021
- })
1022
-
1023
- test('array support (PG)', { skip: !(isPg) }, async ({ teardown, same, rejects }) => {
1024
- async function onDatabaseLoad (db, sql) {
1025
- await clear(db, sql)
1026
- teardown(() => db.dispose())
1027
-
1028
- await db.query(sql`CREATE TABLE generated_test (
1029
- id SERIAL PRIMARY KEY,
1030
- checkmark BOOLEAN NOT NULL DEFAULT true,
1031
- test INTEGER[]
1032
- );`)
1033
- }
1034
-
1035
- const mapper = await connect({
1036
- connectionString: connInfo.connectionString,
1037
- log: fakeLogger,
1038
- onDatabaseLoad,
1039
- ignore: {},
1040
- hooks: {}
1041
- })
1042
-
1043
- const generatedTest = mapper.entities.generatedTest
1044
-
1045
- // save - new record
1046
- same(await generatedTest.save({
1047
- input: { test: [1, 2, 3], checkmark: true }
1048
- }), { id: 1, test: [1, 2, 3], checkmark: true })
1049
-
1050
- // save - update
1051
- same(await generatedTest.save({
1052
- input: { id: 1, test: [4, 5, 6], checkmark: true }
1053
- }), { id: 1, test: [4, 5, 6], checkmark: true })
1054
-
1055
- // insert
1056
- same(await generatedTest.insert({
1057
- inputs: [{ test: [4], checkmark: true }]
1058
- }), [{ id: 2, test: [4], checkmark: true }])
1059
-
1060
- // where any
1061
- same(await generatedTest.find({
1062
- where: {
1063
- test: { any: 4 }
1064
- }
1065
- }), [{ id: 1, test: [4, 5, 6], checkmark: true }, { id: 2, test: [4], checkmark: true }])
1066
-
1067
- // where all
1068
- same(await generatedTest.find({
1069
- where: {
1070
- test: { all: 4 }
1071
- }
1072
- }), [{ id: 2, test: [4], checkmark: true }])
1073
-
1074
- // where contains
1075
- same(await generatedTest.find({
1076
- where: {
1077
- test: { contains: [4] }
1078
- }
1079
- }), [{ id: 1, test: [4, 5, 6], checkmark: true }, { id: 2, test: [4], checkmark: true }])
1080
-
1081
- // where contained
1082
- same(await generatedTest.find({
1083
- where: {
1084
- test: { contained: [4, 5, 6] }
1085
- }
1086
- }), [{ id: 1, test: [4, 5, 6], checkmark: true }, { id: 2, test: [4], checkmark: true }])
1087
-
1088
- // where overlaps
1089
- same(await generatedTest.find({
1090
- where: {
1091
- test: { overlaps: [4] }
1092
- }
1093
- }), [{ id: 1, test: [4, 5, 6], checkmark: true }, { id: 2, test: [4], checkmark: true }])
1094
-
1095
- // where eq
1096
- await rejects(generatedTest.find({
1097
- where: {
1098
- test: { eq: 4 }
1099
- }
1100
- }))
1101
-
1102
- // where any to non-array
1103
- await rejects(generatedTest.find({
1104
- where: {
1105
- checkmark: { any: 4 }
1106
- }
1107
- }))
1108
-
1109
- // where any to non-array
1110
- await rejects(generatedTest.find({
1111
- where: {
1112
- checkmark: { all: 4 }
1113
- }
1114
- }))
1115
-
1116
- // updateMany
1117
- same(await generatedTest.updateMany({
1118
- where: {
1119
- checkmark: { eq: true }
1120
- },
1121
- input: {
1122
- test: [8]
1123
- }
1124
- }), [{ id: 1, test: [8], checkmark: true }, { id: 2, test: [8], checkmark: true }])
1125
- })