@platformatic/sql-mapper 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/entity.js +78 -39
- package/lib/queries/mysql-shared.js +52 -29
- package/lib/queries/mysql.js +66 -18
- package/lib/queries/pg.js +40 -24
- package/lib/queries/shared.js +17 -9
- package/lib/queries/sqlite.js +48 -29
- package/lib/utils.js +39 -2
- package/mapper.d.ts +4 -0
- package/mapper.js +17 -11
- package/package.json +2 -2
- package/test/composite.test.js +162 -0
- package/test/entity.test.js +83 -4
- package/test/entity_transaction.test.js +0 -1
- package/test/helper.js +21 -0
- package/test/mapper.test.js +10 -86
- package/test/schema.test.js +320 -0
- package/test/where.test.js +304 -0
package/test/where.test.js
CHANGED
|
@@ -388,6 +388,170 @@ test('foreign keys', async ({ pass, teardown, same, equal }) => {
|
|
|
388
388
|
}
|
|
389
389
|
})
|
|
390
390
|
|
|
391
|
+
test('limit should be 10 by default 100 at max', async ({ pass, teardown, same, fail, match }) => {
|
|
392
|
+
const mapper = await connect({
|
|
393
|
+
...connInfo,
|
|
394
|
+
log: fakeLogger,
|
|
395
|
+
async onDatabaseLoad (db, sql) {
|
|
396
|
+
teardown(() => db.dispose())
|
|
397
|
+
pass('onDatabaseLoad called')
|
|
398
|
+
|
|
399
|
+
await clear(db, sql)
|
|
400
|
+
|
|
401
|
+
if (isSQLite) {
|
|
402
|
+
await db.query(sql`CREATE TABLE posts (
|
|
403
|
+
id INTEGER PRIMARY KEY,
|
|
404
|
+
title VARCHAR(42),
|
|
405
|
+
long_text TEXT,
|
|
406
|
+
counter INTEGER
|
|
407
|
+
);`)
|
|
408
|
+
} else {
|
|
409
|
+
await db.query(sql`CREATE TABLE posts (
|
|
410
|
+
id SERIAL PRIMARY KEY,
|
|
411
|
+
title VARCHAR(42),
|
|
412
|
+
long_text TEXT,
|
|
413
|
+
counter INTEGER
|
|
414
|
+
);`)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
})
|
|
418
|
+
|
|
419
|
+
const entity = mapper.entities.post
|
|
420
|
+
|
|
421
|
+
const posts = []
|
|
422
|
+
|
|
423
|
+
for (let i = 0; i <= 105; i++) {
|
|
424
|
+
posts.push({
|
|
425
|
+
title: 'Dog',
|
|
426
|
+
longText: 'Foo',
|
|
427
|
+
counter: i
|
|
428
|
+
})
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
await entity.insert({
|
|
432
|
+
inputs: posts
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
const defaultLimit = 10
|
|
436
|
+
const max = 100
|
|
437
|
+
|
|
438
|
+
same(await (await entity.find()).length, defaultLimit)
|
|
439
|
+
|
|
440
|
+
same(await (await entity.find({ limit: 1 })).length, 1)
|
|
441
|
+
|
|
442
|
+
same(await (await entity.find({ offset: 3 })).length, defaultLimit)
|
|
443
|
+
|
|
444
|
+
same(await (await entity.find({ limit: 1, offset: 0 })).length, 1)
|
|
445
|
+
|
|
446
|
+
same(await (await entity.find({ limit: 0 })).length, 0)
|
|
447
|
+
|
|
448
|
+
try {
|
|
449
|
+
await entity.find({ limit: -1 })
|
|
450
|
+
fail('Expected error for limit not allowed value')
|
|
451
|
+
} catch (e) {
|
|
452
|
+
match(e, new Error('Param limit=-1 not allowed. It must be not negative value.'))
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
same(await (await entity.find({ limit: 1, offset: 0 })).length, 1)
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
await entity.find({ limit: 1, offset: -1 })
|
|
459
|
+
fail('Expected error for offset not allowed value')
|
|
460
|
+
} catch (e) {
|
|
461
|
+
match(e, new Error('Param offset=-1 not allowed. It must be not negative value.'))
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
try {
|
|
465
|
+
await entity.find({ limit: 200 })
|
|
466
|
+
fail('Expected error for limit exceeding max allowed value')
|
|
467
|
+
} catch (e) {
|
|
468
|
+
match(e, new Error(`Param limit=200 not allowed. Max accepted value ${max}.`))
|
|
469
|
+
}
|
|
470
|
+
})
|
|
471
|
+
|
|
472
|
+
test('limit must accept custom configuration', async ({ pass, teardown, same, fail, match }) => {
|
|
473
|
+
const customLimitConf = {
|
|
474
|
+
default: 1,
|
|
475
|
+
max: 5
|
|
476
|
+
}
|
|
477
|
+
const mapper = await connect({
|
|
478
|
+
...connInfo,
|
|
479
|
+
log: fakeLogger,
|
|
480
|
+
async onDatabaseLoad (db, sql) {
|
|
481
|
+
teardown(() => db.dispose())
|
|
482
|
+
pass('onDatabaseLoad called')
|
|
483
|
+
|
|
484
|
+
await clear(db, sql)
|
|
485
|
+
|
|
486
|
+
if (isSQLite) {
|
|
487
|
+
await db.query(sql`CREATE TABLE posts (
|
|
488
|
+
id INTEGER PRIMARY KEY,
|
|
489
|
+
title VARCHAR(42),
|
|
490
|
+
long_text TEXT,
|
|
491
|
+
counter INTEGER
|
|
492
|
+
);`)
|
|
493
|
+
} else {
|
|
494
|
+
await db.query(sql`CREATE TABLE posts (
|
|
495
|
+
id SERIAL PRIMARY KEY,
|
|
496
|
+
title VARCHAR(42),
|
|
497
|
+
long_text TEXT,
|
|
498
|
+
counter INTEGER
|
|
499
|
+
);`)
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
limit: customLimitConf
|
|
503
|
+
})
|
|
504
|
+
|
|
505
|
+
const entity = mapper.entities.post
|
|
506
|
+
|
|
507
|
+
const posts = []
|
|
508
|
+
|
|
509
|
+
for (let i = 0; i <= 10; i++) {
|
|
510
|
+
posts.push({
|
|
511
|
+
title: 'Dog',
|
|
512
|
+
longText: 'Foo',
|
|
513
|
+
counter: i
|
|
514
|
+
})
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
await entity.insert({
|
|
518
|
+
inputs: posts
|
|
519
|
+
})
|
|
520
|
+
|
|
521
|
+
same(await (await entity.find()).length, customLimitConf.default)
|
|
522
|
+
|
|
523
|
+
same(await (await entity.find({ limit: 1 })).length, 1)
|
|
524
|
+
|
|
525
|
+
same(await (await entity.find({ offset: 3 })).length, customLimitConf.default)
|
|
526
|
+
|
|
527
|
+
same(await (await entity.find({ limit: 1, offset: 0 })).length, 1)
|
|
528
|
+
|
|
529
|
+
same(await (await entity.find({ limit: 0 })).length, 0)
|
|
530
|
+
|
|
531
|
+
try {
|
|
532
|
+
await entity.find({ limit: -1 })
|
|
533
|
+
fail('Expected error for limit not allowed value')
|
|
534
|
+
} catch (e) {
|
|
535
|
+
match(e, new Error('Param limit=-1 not allowed. It must be not negative value.'))
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
same(await (await entity.find({ limit: 1, offset: 0 })).length, 1)
|
|
539
|
+
|
|
540
|
+
try {
|
|
541
|
+
await entity.find({ limit: 1, offset: -1 })
|
|
542
|
+
fail('Expected error for offset not allowed value')
|
|
543
|
+
} catch (e) {
|
|
544
|
+
match(e, new Error('Param offset=-1 not allowed. It must be not negative value.'))
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
try {
|
|
548
|
+
await entity.find({ limit: 200 })
|
|
549
|
+
fail('Expected error for limit exceeding max allowed value')
|
|
550
|
+
} catch (e) {
|
|
551
|
+
match(e, new Error(`Param limit=200 not allowed. Max accepted value ${customLimitConf.max}.`))
|
|
552
|
+
}
|
|
553
|
+
})
|
|
554
|
+
|
|
391
555
|
test('is NULL', async ({ pass, teardown, same, equal }) => {
|
|
392
556
|
const mapper = await connect({
|
|
393
557
|
...connInfo,
|
|
@@ -434,3 +598,143 @@ test('is NULL', async ({ pass, teardown, same, equal }) => {
|
|
|
434
598
|
title: 'Dog'
|
|
435
599
|
}])
|
|
436
600
|
})
|
|
601
|
+
|
|
602
|
+
test('LIKE', async ({ pass, teardown, same, equal }) => {
|
|
603
|
+
const mapper = await connect({
|
|
604
|
+
...connInfo,
|
|
605
|
+
log: fakeLogger,
|
|
606
|
+
async onDatabaseLoad (db, sql) {
|
|
607
|
+
teardown(() => db.dispose())
|
|
608
|
+
pass('onDatabaseLoad called')
|
|
609
|
+
|
|
610
|
+
await clear(db, sql)
|
|
611
|
+
|
|
612
|
+
if (isSQLite) {
|
|
613
|
+
await db.query(sql`CREATE TABLE posts (
|
|
614
|
+
id INTEGER PRIMARY KEY,
|
|
615
|
+
title VARCHAR(42),
|
|
616
|
+
long_text TEXT,
|
|
617
|
+
counter INTEGER
|
|
618
|
+
);`)
|
|
619
|
+
} else {
|
|
620
|
+
await db.query(sql`CREATE TABLE posts (
|
|
621
|
+
id SERIAL PRIMARY KEY,
|
|
622
|
+
title VARCHAR(42),
|
|
623
|
+
long_text TEXT,
|
|
624
|
+
counter INTEGER
|
|
625
|
+
);`)
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
})
|
|
629
|
+
|
|
630
|
+
const entity = mapper.entities.post
|
|
631
|
+
|
|
632
|
+
const posts = [
|
|
633
|
+
{
|
|
634
|
+
title: 'Dog',
|
|
635
|
+
longText: 'The Dog barks',
|
|
636
|
+
counter: 1
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
title: 'Cat',
|
|
640
|
+
longText: 'The Cat meows',
|
|
641
|
+
counter: 2
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
title: 'Potato',
|
|
645
|
+
longText: 'The Potato is vegetable',
|
|
646
|
+
counter: 3
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
title: 'atmosphere',
|
|
650
|
+
longText: 'The atmosphere is not a sphere',
|
|
651
|
+
counter: 4
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
title: 'planet',
|
|
655
|
+
longText: 'The planet have atmosphere',
|
|
656
|
+
counter: 14
|
|
657
|
+
}
|
|
658
|
+
]
|
|
659
|
+
|
|
660
|
+
await entity.insert({
|
|
661
|
+
inputs: posts
|
|
662
|
+
})
|
|
663
|
+
|
|
664
|
+
same(await entity.find({ where: { title: { like: '%at' } } }), [{
|
|
665
|
+
id: '2',
|
|
666
|
+
title: 'Cat',
|
|
667
|
+
longText: 'The Cat meows',
|
|
668
|
+
counter: 2
|
|
669
|
+
}], 'where: { title: { like: \'%at\' } }')
|
|
670
|
+
|
|
671
|
+
same(await entity.find({ where: { title: { like: '%at%' } } }), [{
|
|
672
|
+
id: '2',
|
|
673
|
+
title: 'Cat',
|
|
674
|
+
longText: 'The Cat meows',
|
|
675
|
+
counter: 2
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
id: '3',
|
|
679
|
+
title: 'Potato',
|
|
680
|
+
longText: 'The Potato is vegetable',
|
|
681
|
+
counter: 3
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
id: '4',
|
|
685
|
+
title: 'atmosphere',
|
|
686
|
+
longText: 'The atmosphere is not a sphere',
|
|
687
|
+
counter: 4
|
|
688
|
+
}], 'where: { title: { like: \'%at%\' } }')
|
|
689
|
+
|
|
690
|
+
same(await entity.find({ where: { title: { like: 'at%' } } }), [{
|
|
691
|
+
id: '4',
|
|
692
|
+
title: 'atmosphere',
|
|
693
|
+
longText: 'The atmosphere is not a sphere',
|
|
694
|
+
counter: 4
|
|
695
|
+
}], 'where: { title: { like: \'at%\' } }')
|
|
696
|
+
|
|
697
|
+
same(await entity.find({ where: { longText: { like: '%is%' } } }), [{
|
|
698
|
+
id: '3',
|
|
699
|
+
title: 'Potato',
|
|
700
|
+
longText: 'The Potato is vegetable',
|
|
701
|
+
counter: 3
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
id: '4',
|
|
705
|
+
title: 'atmosphere',
|
|
706
|
+
longText: 'The atmosphere is not a sphere',
|
|
707
|
+
counter: 4
|
|
708
|
+
}], 'where: { longText: { like: \'%is%\' } }')
|
|
709
|
+
|
|
710
|
+
same(await entity.find({ where: { longText: { like: null } } }), [], 'where: { longText: { like: null } }')
|
|
711
|
+
|
|
712
|
+
same(await entity.find({ where: { counter: { like: 4 } } }), [{
|
|
713
|
+
id: '4',
|
|
714
|
+
title: 'atmosphere',
|
|
715
|
+
longText: 'The atmosphere is not a sphere',
|
|
716
|
+
counter: 4
|
|
717
|
+
}], 'where: { counter: { like: 4 } }')
|
|
718
|
+
|
|
719
|
+
same(await entity.find({ where: { counter: { like: '%4' } } }), [{
|
|
720
|
+
id: '4',
|
|
721
|
+
title: 'atmosphere',
|
|
722
|
+
longText: 'The atmosphere is not a sphere',
|
|
723
|
+
counter: 4
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
id: '5',
|
|
727
|
+
title: 'planet',
|
|
728
|
+
longText: 'The planet have atmosphere',
|
|
729
|
+
counter: 14
|
|
730
|
+
}], 'where: { counter: { like: \'%4\' } }')
|
|
731
|
+
|
|
732
|
+
same(await entity.find({ where: { counter: { like: '4%' } } }), [{
|
|
733
|
+
id: '4',
|
|
734
|
+
title: 'atmosphere',
|
|
735
|
+
longText: 'The atmosphere is not a sphere',
|
|
736
|
+
counter: 4
|
|
737
|
+
}], 'where: { counter: { like: \'4%\' } }')
|
|
738
|
+
|
|
739
|
+
same(await entity.find({ where: { counter: { like: null } } }), [], 'where: { counter: { like: null } }')
|
|
740
|
+
})
|