@naturalcycles/db-lib 8.38.1 → 8.40.1
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/dist/adapter/inmemory/queryInMemory.js +1 -0
- package/dist/commondao/common.dao.js +44 -17
- package/dist/commondao/common.dao.model.d.ts +5 -0
- package/dist/db.model.d.ts +7 -0
- package/dist/query/dbQuery.d.ts +2 -2
- package/dist/query/dbQuery.js +1 -0
- package/package.json +2 -2
- package/src/adapter/inmemory/queryInMemory.ts +1 -0
- package/src/commondao/common.dao.model.ts +6 -0
- package/src/commondao/common.dao.ts +50 -18
- package/src/db.model.ts +8 -0
- package/src/query/dbQuery.ts +3 -1
|
@@ -28,6 +28,7 @@ class CommonDao {
|
|
|
28
28
|
logLevel: isGAE || isCI ? common_dao_model_1.CommonDaoLogLevel.NONE : common_dao_model_1.CommonDaoLogLevel.OPERATIONS,
|
|
29
29
|
idType: 'string',
|
|
30
30
|
createId: true,
|
|
31
|
+
assignGeneratedIds: false,
|
|
31
32
|
created: true,
|
|
32
33
|
updated: true,
|
|
33
34
|
logger: console,
|
|
@@ -450,7 +451,7 @@ class CommonDao {
|
|
|
450
451
|
*/
|
|
451
452
|
async save(bm, opt = {}) {
|
|
452
453
|
this.requireWriteAccess();
|
|
453
|
-
const idWasGenerated = !bm.id;
|
|
454
|
+
const idWasGenerated = !bm.id && this.cfg.createId;
|
|
454
455
|
this.assignIdCreatedUpdated(bm, opt); // mutates
|
|
455
456
|
const dbm = await this.bmToDBM(bm, opt);
|
|
456
457
|
const table = opt.table || this.cfg.table;
|
|
@@ -461,10 +462,16 @@ class CommonDao {
|
|
|
461
462
|
}
|
|
462
463
|
const op = `save(${dbm.id})`;
|
|
463
464
|
const started = this.logSaveStarted(op, bm, table);
|
|
465
|
+
const { excludeFromIndexes } = this.cfg;
|
|
466
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
|
|
464
467
|
await this.cfg.db.saveBatch(table, [dbm], {
|
|
465
|
-
excludeFromIndexes
|
|
468
|
+
excludeFromIndexes,
|
|
469
|
+
assignGeneratedIds,
|
|
466
470
|
...opt,
|
|
467
471
|
});
|
|
472
|
+
if (assignGeneratedIds) {
|
|
473
|
+
bm.id = dbm.id;
|
|
474
|
+
}
|
|
468
475
|
this.logSaveResult(started, op, table);
|
|
469
476
|
return bm;
|
|
470
477
|
}
|
|
@@ -495,24 +502,31 @@ class CommonDao {
|
|
|
495
502
|
const table = opt.table || this.cfg.table;
|
|
496
503
|
// assigning id in case it misses the id
|
|
497
504
|
// will override/set `updated` field, unless opts.preserveUpdated is set
|
|
505
|
+
let row = dbm;
|
|
498
506
|
if (!opt.raw) {
|
|
499
|
-
const idWasGenerated = !dbm.id;
|
|
507
|
+
const idWasGenerated = !dbm.id && this.cfg.createId;
|
|
500
508
|
this.assignIdCreatedUpdated(dbm, opt); // mutates
|
|
501
|
-
|
|
509
|
+
row = this.anyToDBM(dbm, opt);
|
|
502
510
|
if (opt.ensureUniqueId && idWasGenerated)
|
|
503
|
-
await this.ensureUniqueId(table,
|
|
511
|
+
await this.ensureUniqueId(table, row);
|
|
504
512
|
}
|
|
505
513
|
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
|
|
506
514
|
opt = { ...opt, saveMethod: 'insert' };
|
|
507
515
|
}
|
|
508
|
-
const op = `saveAsDBM(${
|
|
509
|
-
const started = this.logSaveStarted(op,
|
|
510
|
-
|
|
511
|
-
|
|
516
|
+
const op = `saveAsDBM(${row.id})`;
|
|
517
|
+
const started = this.logSaveStarted(op, row, table);
|
|
518
|
+
const { excludeFromIndexes } = this.cfg;
|
|
519
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
|
|
520
|
+
await this.cfg.db.saveBatch(table, [row], {
|
|
521
|
+
excludeFromIndexes,
|
|
522
|
+
assignGeneratedIds,
|
|
512
523
|
...opt,
|
|
513
524
|
});
|
|
525
|
+
if (assignGeneratedIds) {
|
|
526
|
+
dbm.id = row.id;
|
|
527
|
+
}
|
|
514
528
|
this.logSaveResult(started, op, table);
|
|
515
|
-
return
|
|
529
|
+
return row;
|
|
516
530
|
}
|
|
517
531
|
async saveBatch(bms, opt = {}) {
|
|
518
532
|
this.requireWriteAccess();
|
|
@@ -529,36 +543,49 @@ class CommonDao {
|
|
|
529
543
|
.map(bm => bm.id)
|
|
530
544
|
.join(', '), 50)})`;
|
|
531
545
|
const started = this.logSaveStarted(op, bms, table);
|
|
546
|
+
const { excludeFromIndexes } = this.cfg;
|
|
547
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
|
|
532
548
|
await this.cfg.db.saveBatch(table, dbms, {
|
|
533
|
-
excludeFromIndexes
|
|
549
|
+
excludeFromIndexes,
|
|
550
|
+
assignGeneratedIds,
|
|
534
551
|
...opt,
|
|
535
552
|
});
|
|
553
|
+
if (assignGeneratedIds) {
|
|
554
|
+
dbms.forEach((dbm, i) => (bms[i].id = dbm.id));
|
|
555
|
+
}
|
|
536
556
|
this.logSaveResult(started, op, table);
|
|
537
557
|
return bms;
|
|
538
558
|
}
|
|
539
559
|
async saveBatchAsDBM(dbms, opt = {}) {
|
|
540
560
|
this.requireWriteAccess();
|
|
541
561
|
const table = opt.table || this.cfg.table;
|
|
562
|
+
let rows = dbms;
|
|
542
563
|
if (!opt.raw) {
|
|
543
564
|
dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt)); // mutates
|
|
544
|
-
|
|
565
|
+
rows = this.anyToDBMs(dbms, opt);
|
|
545
566
|
if (opt.ensureUniqueId)
|
|
546
567
|
throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
|
|
547
568
|
}
|
|
548
569
|
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
|
|
549
570
|
opt = { ...opt, saveMethod: 'insert' };
|
|
550
571
|
}
|
|
551
|
-
const op = `saveBatchAsDBM ${
|
|
572
|
+
const op = `saveBatchAsDBM ${rows.length} row(s) (${(0, js_lib_1._truncate)(rows
|
|
552
573
|
.slice(0, 10)
|
|
553
574
|
.map(bm => bm.id)
|
|
554
575
|
.join(', '), 50)})`;
|
|
555
|
-
const started = this.logSaveStarted(op,
|
|
556
|
-
|
|
557
|
-
|
|
576
|
+
const started = this.logSaveStarted(op, rows, table);
|
|
577
|
+
const { excludeFromIndexes } = this.cfg;
|
|
578
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
|
|
579
|
+
await this.cfg.db.saveBatch(table, rows, {
|
|
580
|
+
excludeFromIndexes,
|
|
581
|
+
assignGeneratedIds,
|
|
558
582
|
...opt,
|
|
559
583
|
});
|
|
584
|
+
if (assignGeneratedIds) {
|
|
585
|
+
rows.forEach((row, i) => (dbms[i].id = row.id));
|
|
586
|
+
}
|
|
560
587
|
this.logSaveResult(started, op, table);
|
|
561
|
-
return
|
|
588
|
+
return rows;
|
|
562
589
|
}
|
|
563
590
|
async deleteById(id, opt = {}) {
|
|
564
591
|
if (!id)
|
|
@@ -86,6 +86,11 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
86
86
|
* Useful e.g when your DB is generating ids by itself (e.g mysql auto_increment).
|
|
87
87
|
*/
|
|
88
88
|
createId?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* See the same option in CommonDB.
|
|
91
|
+
* Defaults to false normally.
|
|
92
|
+
*/
|
|
93
|
+
assignGeneratedIds?: boolean;
|
|
89
94
|
/**
|
|
90
95
|
* Defaults to true
|
|
91
96
|
* Set to false to disable `created` field management.
|
package/dist/db.model.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ export interface CommonDBSaveOptions<ROW extends Partial<ObjectWithId> = AnyObje
|
|
|
19
19
|
* Default is `upsert`
|
|
20
20
|
*/
|
|
21
21
|
saveMethod?: CommonDBSaveMethod;
|
|
22
|
+
/**
|
|
23
|
+
* Only applicable to tables where id is "auto-generated by DB", e.g `auto_increment` in MySQL.
|
|
24
|
+
* By default it's false, so, auto-generated id will NOT be assigned/returned.
|
|
25
|
+
* Setting it to true will assign and return auto-generated id (on all rows, one by one).
|
|
26
|
+
* It's not true by default, because getting auto-generated id incurs an overhead of doing extra call (e.g LAST_INSERT_ID() in MySQL).
|
|
27
|
+
*/
|
|
28
|
+
assignGeneratedIds?: boolean;
|
|
22
29
|
}
|
|
23
30
|
export declare type CommonDBStreamOptions = CommonDBOptions;
|
|
24
31
|
export interface CommonDBCreateOptions extends CommonDBOptions {
|
package/dist/query/dbQuery.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ import { RunQueryResult } from '../db.model';
|
|
|
22
22
|
*
|
|
23
23
|
* You may also look at queryInMemory() for its implementation (it implements all those).
|
|
24
24
|
*/
|
|
25
|
-
export declare type DBQueryFilterOperator = '<' | '<=' | '==' | '>=' | '>' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
|
|
26
|
-
export declare const dbQueryFilterOperatorValues:
|
|
25
|
+
export declare type DBQueryFilterOperator = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
|
|
26
|
+
export declare const dbQueryFilterOperatorValues: DBQueryFilterOperator[];
|
|
27
27
|
export interface DBQueryFilter<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
28
28
|
name: keyof ROW;
|
|
29
29
|
op: DBQueryFilterOperator;
|
package/dist/query/dbQuery.js
CHANGED
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@naturalcycles/bench-lib": "^1.0.0",
|
|
13
13
|
"@naturalcycles/dev-lib": "^12.0.1",
|
|
14
14
|
"@types/node": "^17.0.0",
|
|
15
|
-
"jest": "^
|
|
15
|
+
"jest": "^28.0.3",
|
|
16
16
|
"weak-napi": "^2.0.2"
|
|
17
17
|
},
|
|
18
18
|
"files": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"engines": {
|
|
43
43
|
"node": ">=14.15"
|
|
44
44
|
},
|
|
45
|
-
"version": "8.
|
|
45
|
+
"version": "8.40.1",
|
|
46
46
|
"description": "Lowest Common Denominator API to supported Databases",
|
|
47
47
|
"keywords": [
|
|
48
48
|
"db",
|
|
@@ -4,6 +4,7 @@ import { DBQuery, DBQueryFilterOperator } from '../../query/dbQuery'
|
|
|
4
4
|
type FilterFn = (v: any, val: any) => boolean
|
|
5
5
|
const FILTER_FNS: Record<DBQueryFilterOperator, FilterFn> = {
|
|
6
6
|
'==': (v, val) => v === val,
|
|
7
|
+
'!=': (v, val) => v !== val,
|
|
7
8
|
'<': (v, val) => v < val,
|
|
8
9
|
'<=': (v, val) => v <= val,
|
|
9
10
|
'>': (v, val) => v > val,
|
|
@@ -119,6 +119,12 @@ export interface CommonDaoCfg<
|
|
|
119
119
|
*/
|
|
120
120
|
createId?: boolean
|
|
121
121
|
|
|
122
|
+
/**
|
|
123
|
+
* See the same option in CommonDB.
|
|
124
|
+
* Defaults to false normally.
|
|
125
|
+
*/
|
|
126
|
+
assignGeneratedIds?: boolean
|
|
127
|
+
|
|
122
128
|
/**
|
|
123
129
|
* Defaults to true
|
|
124
130
|
* Set to false to disable `created` field management.
|
|
@@ -73,6 +73,7 @@ export class CommonDao<
|
|
|
73
73
|
logLevel: isGAE || isCI ? CommonDaoLogLevel.NONE : CommonDaoLogLevel.OPERATIONS,
|
|
74
74
|
idType: 'string',
|
|
75
75
|
createId: true,
|
|
76
|
+
assignGeneratedIds: false,
|
|
76
77
|
created: true,
|
|
77
78
|
updated: true,
|
|
78
79
|
logger: console,
|
|
@@ -609,7 +610,7 @@ export class CommonDao<
|
|
|
609
610
|
*/
|
|
610
611
|
async save(bm: Unsaved<BM>, opt: CommonDaoSaveOptions<DBM> = {}): Promise<Saved<BM>> {
|
|
611
612
|
this.requireWriteAccess()
|
|
612
|
-
const idWasGenerated = !bm.id
|
|
613
|
+
const idWasGenerated = !bm.id && this.cfg.createId
|
|
613
614
|
this.assignIdCreatedUpdated(bm, opt) // mutates
|
|
614
615
|
const dbm = await this.bmToDBM(bm as BM, opt)
|
|
615
616
|
const table = opt.table || this.cfg.table
|
|
@@ -619,11 +620,18 @@ export class CommonDao<
|
|
|
619
620
|
}
|
|
620
621
|
const op = `save(${dbm.id})`
|
|
621
622
|
const started = this.logSaveStarted(op, bm, table)
|
|
623
|
+
const { excludeFromIndexes } = this.cfg
|
|
624
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
|
|
622
625
|
await this.cfg.db.saveBatch(table, [dbm], {
|
|
623
|
-
excludeFromIndexes
|
|
626
|
+
excludeFromIndexes,
|
|
627
|
+
assignGeneratedIds,
|
|
624
628
|
...opt,
|
|
625
629
|
})
|
|
626
630
|
|
|
631
|
+
if (assignGeneratedIds) {
|
|
632
|
+
bm.id = dbm.id as any
|
|
633
|
+
}
|
|
634
|
+
|
|
627
635
|
this.logSaveResult(started, op, table)
|
|
628
636
|
return bm as any
|
|
629
637
|
}
|
|
@@ -666,23 +674,32 @@ export class CommonDao<
|
|
|
666
674
|
|
|
667
675
|
// assigning id in case it misses the id
|
|
668
676
|
// will override/set `updated` field, unless opts.preserveUpdated is set
|
|
677
|
+
let row = dbm
|
|
669
678
|
if (!opt.raw) {
|
|
670
|
-
const idWasGenerated = !dbm.id
|
|
679
|
+
const idWasGenerated = !dbm.id && this.cfg.createId
|
|
671
680
|
this.assignIdCreatedUpdated(dbm, opt) // mutates
|
|
672
|
-
|
|
673
|
-
if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table,
|
|
681
|
+
row = this.anyToDBM(dbm, opt)
|
|
682
|
+
if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, row)
|
|
674
683
|
}
|
|
675
684
|
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
|
|
676
685
|
opt = { ...opt, saveMethod: 'insert' }
|
|
677
686
|
}
|
|
678
|
-
const op = `saveAsDBM(${
|
|
679
|
-
const started = this.logSaveStarted(op,
|
|
680
|
-
|
|
681
|
-
|
|
687
|
+
const op = `saveAsDBM(${row.id})`
|
|
688
|
+
const started = this.logSaveStarted(op, row, table)
|
|
689
|
+
const { excludeFromIndexes } = this.cfg
|
|
690
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
|
|
691
|
+
await this.cfg.db.saveBatch(table, [row], {
|
|
692
|
+
excludeFromIndexes,
|
|
693
|
+
assignGeneratedIds,
|
|
682
694
|
...opt,
|
|
683
695
|
})
|
|
696
|
+
|
|
697
|
+
if (assignGeneratedIds) {
|
|
698
|
+
dbm.id = row.id
|
|
699
|
+
}
|
|
700
|
+
|
|
684
701
|
this.logSaveResult(started, op, table)
|
|
685
|
-
return
|
|
702
|
+
return row
|
|
686
703
|
}
|
|
687
704
|
|
|
688
705
|
async saveBatch(bms: Unsaved<BM>[], opt: CommonDaoSaveOptions<DBM> = {}): Promise<Saved<BM>[]> {
|
|
@@ -703,12 +720,19 @@ export class CommonDao<
|
|
|
703
720
|
50,
|
|
704
721
|
)})`
|
|
705
722
|
const started = this.logSaveStarted(op, bms, table)
|
|
723
|
+
const { excludeFromIndexes } = this.cfg
|
|
724
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
|
|
706
725
|
|
|
707
726
|
await this.cfg.db.saveBatch(table, dbms, {
|
|
708
|
-
excludeFromIndexes
|
|
727
|
+
excludeFromIndexes,
|
|
728
|
+
assignGeneratedIds,
|
|
709
729
|
...opt,
|
|
710
730
|
})
|
|
711
731
|
|
|
732
|
+
if (assignGeneratedIds) {
|
|
733
|
+
dbms.forEach((dbm, i) => (bms[i]!.id = dbm.id as any))
|
|
734
|
+
}
|
|
735
|
+
|
|
712
736
|
this.logSaveResult(started, op, table)
|
|
713
737
|
|
|
714
738
|
return bms as any[]
|
|
@@ -717,30 +741,38 @@ export class CommonDao<
|
|
|
717
741
|
async saveBatchAsDBM(dbms: DBM[], opt: CommonDaoSaveOptions<DBM> = {}): Promise<DBM[]> {
|
|
718
742
|
this.requireWriteAccess()
|
|
719
743
|
const table = opt.table || this.cfg.table
|
|
744
|
+
let rows = dbms
|
|
720
745
|
if (!opt.raw) {
|
|
721
746
|
dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt)) // mutates
|
|
722
|
-
|
|
747
|
+
rows = this.anyToDBMs(dbms, opt)
|
|
723
748
|
if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
|
|
724
749
|
}
|
|
725
750
|
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
|
|
726
751
|
opt = { ...opt, saveMethod: 'insert' }
|
|
727
752
|
}
|
|
728
|
-
const op = `saveBatchAsDBM ${
|
|
729
|
-
|
|
753
|
+
const op = `saveBatchAsDBM ${rows.length} row(s) (${_truncate(
|
|
754
|
+
rows
|
|
730
755
|
.slice(0, 10)
|
|
731
756
|
.map(bm => bm.id)
|
|
732
757
|
.join(', '),
|
|
733
758
|
50,
|
|
734
759
|
)})`
|
|
735
|
-
const started = this.logSaveStarted(op,
|
|
760
|
+
const started = this.logSaveStarted(op, rows, table)
|
|
761
|
+
const { excludeFromIndexes } = this.cfg
|
|
762
|
+
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
|
|
736
763
|
|
|
737
|
-
await this.cfg.db.saveBatch(table,
|
|
738
|
-
excludeFromIndexes
|
|
764
|
+
await this.cfg.db.saveBatch(table, rows, {
|
|
765
|
+
excludeFromIndexes,
|
|
766
|
+
assignGeneratedIds,
|
|
739
767
|
...opt,
|
|
740
768
|
})
|
|
741
769
|
|
|
770
|
+
if (assignGeneratedIds) {
|
|
771
|
+
rows.forEach((row, i) => (dbms[i]!.id = row.id))
|
|
772
|
+
}
|
|
773
|
+
|
|
742
774
|
this.logSaveResult(started, op, table)
|
|
743
|
-
return
|
|
775
|
+
return rows
|
|
744
776
|
}
|
|
745
777
|
|
|
746
778
|
// DELETE
|
package/src/db.model.ts
CHANGED
|
@@ -24,6 +24,14 @@ export interface CommonDBSaveOptions<ROW extends Partial<ObjectWithId> = AnyObje
|
|
|
24
24
|
* Default is `upsert`
|
|
25
25
|
*/
|
|
26
26
|
saveMethod?: CommonDBSaveMethod
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Only applicable to tables where id is "auto-generated by DB", e.g `auto_increment` in MySQL.
|
|
30
|
+
* By default it's false, so, auto-generated id will NOT be assigned/returned.
|
|
31
|
+
* Setting it to true will assign and return auto-generated id (on all rows, one by one).
|
|
32
|
+
* It's not true by default, because getting auto-generated id incurs an overhead of doing extra call (e.g LAST_INSERT_ID() in MySQL).
|
|
33
|
+
*/
|
|
34
|
+
assignGeneratedIds?: boolean
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
export type CommonDBStreamOptions = CommonDBOptions
|
package/src/query/dbQuery.ts
CHANGED
|
@@ -27,6 +27,7 @@ export type DBQueryFilterOperator =
|
|
|
27
27
|
| '<'
|
|
28
28
|
| '<='
|
|
29
29
|
| '=='
|
|
30
|
+
| '!='
|
|
30
31
|
| '>='
|
|
31
32
|
| '>'
|
|
32
33
|
| 'in'
|
|
@@ -34,10 +35,11 @@ export type DBQueryFilterOperator =
|
|
|
34
35
|
| 'array-contains'
|
|
35
36
|
| 'array-contains-any'
|
|
36
37
|
|
|
37
|
-
export const dbQueryFilterOperatorValues = [
|
|
38
|
+
export const dbQueryFilterOperatorValues: DBQueryFilterOperator[] = [
|
|
38
39
|
'<',
|
|
39
40
|
'<=',
|
|
40
41
|
'==',
|
|
42
|
+
'!=',
|
|
41
43
|
'>=',
|
|
42
44
|
'>',
|
|
43
45
|
'in',
|