@naturalcycles/db-lib 10.20.4 → 10.22.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.
|
@@ -175,10 +175,10 @@ export declare class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity
|
|
|
175
175
|
private static multiGetMapByTableById;
|
|
176
176
|
private static prepareMultiGetOutput;
|
|
177
177
|
/**
|
|
178
|
-
*
|
|
178
|
+
* @experimental.
|
|
179
179
|
*/
|
|
180
|
-
static
|
|
181
|
-
static multiSave(inputs: (DaoWithRows<
|
|
180
|
+
static multiDelete(inputs: (DaoWithId<AnyDao> | DaoWithIds<AnyDao>)[], opt?: CommonDaoOptions): Promise<NonNegativeInteger>;
|
|
181
|
+
static multiSave(inputs: (DaoWithRows<AnyDao> | DaoWithRow<AnyDao>)[], opt?: CommonDaoSaveBatchOptions<any>): Promise<void>;
|
|
182
182
|
createTransaction(opt?: CommonDBTransactionOptions): Promise<CommonDaoTransaction>;
|
|
183
183
|
runInTransaction<T = void>(fn: CommonDaoTransactionFn<T>, opt?: CommonDBTransactionOptions): Promise<T>;
|
|
184
184
|
private ensureRequired;
|
|
@@ -6,7 +6,7 @@ import { _deepJsonEquals } from '@naturalcycles/js-lib/object/deepEquals.js';
|
|
|
6
6
|
import { _filterUndefinedValues, _objectAssignExact, } from '@naturalcycles/js-lib/object/object.util.js';
|
|
7
7
|
import { pMap } from '@naturalcycles/js-lib/promise/pMap.js';
|
|
8
8
|
import { _stringMapEntries, _stringMapValues, } from '@naturalcycles/js-lib/types';
|
|
9
|
-
import { _passthroughPredicate, _typeCast
|
|
9
|
+
import { _passthroughPredicate, _typeCast } from '@naturalcycles/js-lib/types';
|
|
10
10
|
import { stringId } from '@naturalcycles/nodejs-lib';
|
|
11
11
|
import { transformFlatten, transformMapSync, } from '@naturalcycles/nodejs-lib/stream';
|
|
12
12
|
import { _pipeline, transformChunk, transformLogProgress, transformMap, transformNoOp, writableVoid, } from '@naturalcycles/nodejs-lib/stream';
|
|
@@ -454,12 +454,8 @@ export class CommonDao {
|
|
|
454
454
|
}
|
|
455
455
|
this.assignIdCreatedUpdated(bm, opt); // mutates
|
|
456
456
|
_typeCast(bm);
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
dbm = (await this.cfg.hooks.beforeSave(dbm));
|
|
460
|
-
if (dbm === null)
|
|
461
|
-
return bm;
|
|
462
|
-
}
|
|
457
|
+
const dbm = await this.bmToDBM(bm, opt); // validates BM
|
|
458
|
+
this.cfg.hooks.beforeSave?.(dbm);
|
|
463
459
|
const table = opt.table || this.cfg.table;
|
|
464
460
|
const saveOptions = this.prepareSaveOptions(opt);
|
|
465
461
|
await (opt.tx || this.cfg.db).saveBatch(table, [dbm], saveOptions);
|
|
@@ -471,12 +467,8 @@ export class CommonDao {
|
|
|
471
467
|
async saveAsDBM(dbm, opt = {}) {
|
|
472
468
|
this.requireWriteAccess();
|
|
473
469
|
this.assignIdCreatedUpdated(dbm, opt); // mutates
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
row = (await this.cfg.hooks.beforeSave(row));
|
|
477
|
-
if (row === null)
|
|
478
|
-
return dbm;
|
|
479
|
-
}
|
|
470
|
+
const row = this.anyToDBM(dbm, opt);
|
|
471
|
+
this.cfg.hooks.beforeSave?.(row);
|
|
480
472
|
const table = opt.table || this.cfg.table;
|
|
481
473
|
const saveOptions = this.prepareSaveOptions(opt);
|
|
482
474
|
await (opt.tx || this.cfg.db).saveBatch(table, [row], saveOptions);
|
|
@@ -490,9 +482,9 @@ export class CommonDao {
|
|
|
490
482
|
return [];
|
|
491
483
|
this.requireWriteAccess();
|
|
492
484
|
bms.forEach(bm => this.assignIdCreatedUpdated(bm, opt));
|
|
493
|
-
|
|
494
|
-
if (this.cfg.hooks.beforeSave
|
|
495
|
-
dbms
|
|
485
|
+
const dbms = await this.bmsToDBM(bms, opt);
|
|
486
|
+
if (this.cfg.hooks.beforeSave) {
|
|
487
|
+
dbms.forEach(dbm => this.cfg.hooks.beforeSave(dbm));
|
|
496
488
|
}
|
|
497
489
|
const table = opt.table || this.cfg.table;
|
|
498
490
|
const saveOptions = this.prepareSaveOptions(opt);
|
|
@@ -507,9 +499,9 @@ export class CommonDao {
|
|
|
507
499
|
return [];
|
|
508
500
|
this.requireWriteAccess();
|
|
509
501
|
dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt));
|
|
510
|
-
|
|
511
|
-
if (this.cfg.hooks.beforeSave
|
|
512
|
-
rows
|
|
502
|
+
const rows = this.anyToDBMs(dbms, opt);
|
|
503
|
+
if (this.cfg.hooks.beforeSave) {
|
|
504
|
+
rows.forEach(row => this.cfg.hooks.beforeSave(row));
|
|
513
505
|
}
|
|
514
506
|
const table = opt.table || this.cfg.table;
|
|
515
507
|
const saveOptions = this.prepareSaveOptions(opt);
|
|
@@ -550,13 +542,9 @@ export class CommonDao {
|
|
|
550
542
|
const { chunkSize = 500, chunkConcurrency = 32, errorMode } = opt;
|
|
551
543
|
return [
|
|
552
544
|
transformMap(async (bm) => {
|
|
553
|
-
this.assignIdCreatedUpdated(bm, opt);
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
dbm = (await beforeSave(dbm));
|
|
557
|
-
if (dbm === null)
|
|
558
|
-
return SKIP;
|
|
559
|
-
}
|
|
545
|
+
this.assignIdCreatedUpdated(bm, opt);
|
|
546
|
+
const dbm = await this.bmToDBM(bm, opt);
|
|
547
|
+
beforeSave?.(dbm);
|
|
560
548
|
return dbm;
|
|
561
549
|
}, {
|
|
562
550
|
errorMode,
|
|
@@ -866,17 +854,27 @@ export class CommonDao {
|
|
|
866
854
|
return bmsByProp;
|
|
867
855
|
}
|
|
868
856
|
/**
|
|
869
|
-
*
|
|
857
|
+
* @experimental.
|
|
870
858
|
*/
|
|
871
|
-
static async
|
|
859
|
+
static async multiDelete(inputs, opt = {}) {
|
|
872
860
|
if (!inputs.length)
|
|
873
861
|
return 0;
|
|
874
862
|
const { db } = inputs[0].dao.cfg;
|
|
875
863
|
const idsByTable = {};
|
|
876
|
-
for (const
|
|
877
|
-
|
|
864
|
+
for (const input of inputs) {
|
|
865
|
+
const { dao } = input;
|
|
866
|
+
const { table } = dao.cfg;
|
|
867
|
+
dao.requireWriteAccess();
|
|
868
|
+
dao.requireObjectMutability(opt);
|
|
869
|
+
idsByTable[table] ||= [];
|
|
870
|
+
if ('id' in input) {
|
|
871
|
+
idsByTable[table].push(input.id);
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
idsByTable[table].push(...input.ids);
|
|
875
|
+
}
|
|
878
876
|
}
|
|
879
|
-
return await db.multiDelete(idsByTable);
|
|
877
|
+
return await db.multiDelete(idsByTable, opt);
|
|
880
878
|
}
|
|
881
879
|
static async multiSave(inputs, opt = {}) {
|
|
882
880
|
if (!inputs.length)
|
|
@@ -901,12 +899,18 @@ export class CommonDao {
|
|
|
901
899
|
}
|
|
902
900
|
}
|
|
903
901
|
dao.assignIdCreatedUpdated(row, opt);
|
|
904
|
-
|
|
902
|
+
const dbm = await dao.bmToDBM(row, opt);
|
|
903
|
+
dao.cfg.hooks.beforeSave?.(dbm);
|
|
904
|
+
dbmsByTable[table].push(dbm);
|
|
905
905
|
}
|
|
906
906
|
else {
|
|
907
907
|
// Plural
|
|
908
908
|
input.rows.forEach(bm => dao.assignIdCreatedUpdated(bm, opt));
|
|
909
|
-
|
|
909
|
+
const dbms = await dao.bmsToDBM(input.rows, opt);
|
|
910
|
+
if (dao.cfg.hooks.beforeSave) {
|
|
911
|
+
dbms.forEach(dbm => dao.cfg.hooks.beforeSave(dbm));
|
|
912
|
+
}
|
|
913
|
+
dbmsByTable[table].push(...dbms);
|
|
910
914
|
}
|
|
911
915
|
});
|
|
912
916
|
await db.multiSave(dbmsByTable);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ValidationFunction } from '@naturalcycles/js-lib';
|
|
2
2
|
import type { AppError, ErrorMode } from '@naturalcycles/js-lib/error';
|
|
3
3
|
import type { CommonLogger } from '@naturalcycles/js-lib/log';
|
|
4
|
-
import type { BaseDBEntity,
|
|
4
|
+
import type { BaseDBEntity, UnixTimestamp } from '@naturalcycles/js-lib/types';
|
|
5
5
|
import type { TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib/stream';
|
|
6
6
|
import type { CommonDB } from '../commondb/common.db.js';
|
|
7
7
|
import type { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model.js';
|
|
8
|
-
export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntity, ID = BM['id']> {
|
|
8
|
+
export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntity, ID extends string = BM['id']> {
|
|
9
9
|
/**
|
|
10
10
|
* Allows to override the id generation function.
|
|
11
11
|
* By default it uses `stringId` from nodejs-lib
|
|
@@ -50,15 +50,10 @@ export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntit
|
|
|
50
50
|
*
|
|
51
51
|
* Normally does nothing.
|
|
52
52
|
*
|
|
53
|
-
* You can change the DBM as you want here: ok to mutate or not, but you need to return the DBM
|
|
54
|
-
* to pass it further.
|
|
55
|
-
*
|
|
56
|
-
* You can return `null` to prevent it from being saved, without throwing an error.
|
|
57
|
-
* `.save` method will then return the BM/DBM as it has entered the method (it **won't** return the null value!).
|
|
58
|
-
*
|
|
59
53
|
* You can do validations as needed here and throw errors, they will be propagated.
|
|
54
|
+
* Or, you can mutate the DBM if needed.
|
|
60
55
|
*/
|
|
61
|
-
beforeSave?: (dbm: DBM) =>
|
|
56
|
+
beforeSave?: (dbm: DBM) => void;
|
|
62
57
|
/**
|
|
63
58
|
* Called in:
|
|
64
59
|
* - dbmToBM (applied before DBM becomes BM)
|
|
@@ -95,7 +90,7 @@ export declare enum CommonDaoLogLevel {
|
|
|
95
90
|
*/
|
|
96
91
|
DATA_FULL = 30
|
|
97
92
|
}
|
|
98
|
-
export interface CommonDaoCfg<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, ID = BM['id']> {
|
|
93
|
+
export interface CommonDaoCfg<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, ID extends string = BM['id']> {
|
|
99
94
|
db: CommonDB;
|
|
100
95
|
table: string;
|
|
101
96
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ValidationFunction } from '@naturalcycles/js-lib'
|
|
2
2
|
import type { AppError, ErrorMode } from '@naturalcycles/js-lib/error'
|
|
3
3
|
import type { CommonLogger } from '@naturalcycles/js-lib/log'
|
|
4
|
-
import type { BaseDBEntity,
|
|
4
|
+
import type { BaseDBEntity, UnixTimestamp } from '@naturalcycles/js-lib/types'
|
|
5
5
|
import type {
|
|
6
6
|
TransformLogProgressOptions,
|
|
7
7
|
TransformMapOptions,
|
|
@@ -9,7 +9,11 @@ import type {
|
|
|
9
9
|
import type { CommonDB } from '../commondb/common.db.js'
|
|
10
10
|
import type { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model.js'
|
|
11
11
|
|
|
12
|
-
export interface CommonDaoHooks<
|
|
12
|
+
export interface CommonDaoHooks<
|
|
13
|
+
BM extends BaseDBEntity,
|
|
14
|
+
DBM extends BaseDBEntity,
|
|
15
|
+
ID extends string = BM['id'],
|
|
16
|
+
> {
|
|
13
17
|
/**
|
|
14
18
|
* Allows to override the id generation function.
|
|
15
19
|
* By default it uses `stringId` from nodejs-lib
|
|
@@ -61,15 +65,10 @@ export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntit
|
|
|
61
65
|
*
|
|
62
66
|
* Normally does nothing.
|
|
63
67
|
*
|
|
64
|
-
* You can change the DBM as you want here: ok to mutate or not, but you need to return the DBM
|
|
65
|
-
* to pass it further.
|
|
66
|
-
*
|
|
67
|
-
* You can return `null` to prevent it from being saved, without throwing an error.
|
|
68
|
-
* `.save` method will then return the BM/DBM as it has entered the method (it **won't** return the null value!).
|
|
69
|
-
*
|
|
70
68
|
* You can do validations as needed here and throw errors, they will be propagated.
|
|
69
|
+
* Or, you can mutate the DBM if needed.
|
|
71
70
|
*/
|
|
72
|
-
beforeSave?: (dbm: DBM) =>
|
|
71
|
+
beforeSave?: (dbm: DBM) => void
|
|
73
72
|
|
|
74
73
|
/**
|
|
75
74
|
* Called in:
|
|
@@ -113,7 +112,7 @@ export enum CommonDaoLogLevel {
|
|
|
113
112
|
export interface CommonDaoCfg<
|
|
114
113
|
BM extends BaseDBEntity,
|
|
115
114
|
DBM extends BaseDBEntity = BM,
|
|
116
|
-
ID = BM['id'],
|
|
115
|
+
ID extends string = BM['id'],
|
|
117
116
|
> {
|
|
118
117
|
db: CommonDB
|
|
119
118
|
table: string
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
type StringMap,
|
|
21
21
|
type Unsaved,
|
|
22
22
|
} from '@naturalcycles/js-lib/types'
|
|
23
|
-
import { _passthroughPredicate, _typeCast
|
|
23
|
+
import { _passthroughPredicate, _typeCast } from '@naturalcycles/js-lib/types'
|
|
24
24
|
import { stringId } from '@naturalcycles/nodejs-lib'
|
|
25
25
|
import {
|
|
26
26
|
type ReadableTyped,
|
|
@@ -616,13 +616,8 @@ export class CommonDao<
|
|
|
616
616
|
|
|
617
617
|
this.assignIdCreatedUpdated(bm, opt) // mutates
|
|
618
618
|
_typeCast<BM>(bm)
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
if (this.cfg.hooks!.beforeSave) {
|
|
622
|
-
dbm = (await this.cfg.hooks!.beforeSave(dbm))!
|
|
623
|
-
if (dbm === null) return bm
|
|
624
|
-
}
|
|
625
|
-
|
|
619
|
+
const dbm = await this.bmToDBM(bm, opt) // validates BM
|
|
620
|
+
this.cfg.hooks!.beforeSave?.(dbm)
|
|
626
621
|
const table = opt.table || this.cfg.table
|
|
627
622
|
const saveOptions = this.prepareSaveOptions(opt)
|
|
628
623
|
|
|
@@ -637,15 +632,9 @@ export class CommonDao<
|
|
|
637
632
|
|
|
638
633
|
async saveAsDBM(dbm: Unsaved<DBM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<DBM> {
|
|
639
634
|
this.requireWriteAccess()
|
|
640
|
-
|
|
641
635
|
this.assignIdCreatedUpdated(dbm, opt) // mutates
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
if (this.cfg.hooks!.beforeSave) {
|
|
645
|
-
row = (await this.cfg.hooks!.beforeSave(row))!
|
|
646
|
-
if (row === null) return dbm as DBM
|
|
647
|
-
}
|
|
648
|
-
|
|
636
|
+
const row = this.anyToDBM(dbm, opt)
|
|
637
|
+
this.cfg.hooks!.beforeSave?.(row)
|
|
649
638
|
const table = opt.table || this.cfg.table
|
|
650
639
|
const saveOptions = this.prepareSaveOptions(opt)
|
|
651
640
|
|
|
@@ -662,14 +651,10 @@ export class CommonDao<
|
|
|
662
651
|
if (!bms.length) return []
|
|
663
652
|
this.requireWriteAccess()
|
|
664
653
|
bms.forEach(bm => this.assignIdCreatedUpdated(bm, opt))
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.beforeSave!(dbm))).filter(
|
|
669
|
-
_isTruthy,
|
|
670
|
-
)
|
|
654
|
+
const dbms = await this.bmsToDBM(bms as BM[], opt)
|
|
655
|
+
if (this.cfg.hooks!.beforeSave) {
|
|
656
|
+
dbms.forEach(dbm => this.cfg.hooks!.beforeSave!(dbm))
|
|
671
657
|
}
|
|
672
|
-
|
|
673
658
|
const table = opt.table || this.cfg.table
|
|
674
659
|
const saveOptions = this.prepareSaveOptions(opt)
|
|
675
660
|
|
|
@@ -689,14 +674,10 @@ export class CommonDao<
|
|
|
689
674
|
if (!dbms.length) return []
|
|
690
675
|
this.requireWriteAccess()
|
|
691
676
|
dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt))
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
rows = (await pMap(rows, async row => await this.cfg.hooks!.beforeSave!(row))).filter(
|
|
696
|
-
_isTruthy,
|
|
697
|
-
)
|
|
677
|
+
const rows = this.anyToDBMs(dbms as DBM[], opt)
|
|
678
|
+
if (this.cfg.hooks!.beforeSave) {
|
|
679
|
+
rows.forEach(row => this.cfg.hooks!.beforeSave!(row))
|
|
698
680
|
}
|
|
699
|
-
|
|
700
681
|
const table = opt.table || this.cfg.table
|
|
701
682
|
const saveOptions = this.prepareSaveOptions(opt)
|
|
702
683
|
|
|
@@ -752,15 +733,9 @@ export class CommonDao<
|
|
|
752
733
|
return [
|
|
753
734
|
transformMap<BM, DBM>(
|
|
754
735
|
async bm => {
|
|
755
|
-
this.assignIdCreatedUpdated(bm, opt)
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
if (beforeSave) {
|
|
760
|
-
dbm = (await beforeSave(dbm))!
|
|
761
|
-
if (dbm === null) return SKIP
|
|
762
|
-
}
|
|
763
|
-
|
|
736
|
+
this.assignIdCreatedUpdated(bm, opt)
|
|
737
|
+
const dbm = await this.bmToDBM(bm, opt)
|
|
738
|
+
beforeSave?.(dbm)
|
|
764
739
|
return dbm
|
|
765
740
|
},
|
|
766
741
|
{
|
|
@@ -1164,24 +1139,34 @@ export class CommonDao<
|
|
|
1164
1139
|
}
|
|
1165
1140
|
|
|
1166
1141
|
/**
|
|
1167
|
-
*
|
|
1142
|
+
* @experimental.
|
|
1168
1143
|
*/
|
|
1169
|
-
static async
|
|
1170
|
-
inputs: DaoWithIds<
|
|
1171
|
-
|
|
1144
|
+
static async multiDelete(
|
|
1145
|
+
inputs: (DaoWithId<AnyDao> | DaoWithIds<AnyDao>)[],
|
|
1146
|
+
opt: CommonDaoOptions = {},
|
|
1172
1147
|
): Promise<NonNegativeInteger> {
|
|
1173
1148
|
if (!inputs.length) return 0
|
|
1174
1149
|
const { db } = inputs[0]!.dao.cfg
|
|
1175
1150
|
const idsByTable: StringMap<string[]> = {}
|
|
1176
|
-
for (const
|
|
1177
|
-
|
|
1151
|
+
for (const input of inputs) {
|
|
1152
|
+
const { dao } = input
|
|
1153
|
+
const { table } = dao.cfg
|
|
1154
|
+
dao.requireWriteAccess()
|
|
1155
|
+
dao.requireObjectMutability(opt)
|
|
1156
|
+
idsByTable[table] ||= []
|
|
1157
|
+
|
|
1158
|
+
if ('id' in input) {
|
|
1159
|
+
idsByTable[table].push(input.id)
|
|
1160
|
+
} else {
|
|
1161
|
+
idsByTable[table].push(...input.ids)
|
|
1162
|
+
}
|
|
1178
1163
|
}
|
|
1179
1164
|
|
|
1180
|
-
return await db.multiDelete(idsByTable)
|
|
1165
|
+
return await db.multiDelete(idsByTable, opt)
|
|
1181
1166
|
}
|
|
1182
1167
|
|
|
1183
1168
|
static async multiSave(
|
|
1184
|
-
inputs: (DaoWithRows<
|
|
1169
|
+
inputs: (DaoWithRows<AnyDao> | DaoWithRow<AnyDao>)[],
|
|
1185
1170
|
opt: CommonDaoSaveBatchOptions<any> = {},
|
|
1186
1171
|
): Promise<void> {
|
|
1187
1172
|
if (!inputs.length) return
|
|
@@ -1208,11 +1193,17 @@ export class CommonDao<
|
|
|
1208
1193
|
}
|
|
1209
1194
|
|
|
1210
1195
|
dao.assignIdCreatedUpdated(row, opt)
|
|
1211
|
-
|
|
1196
|
+
const dbm = await dao.bmToDBM(row, opt)
|
|
1197
|
+
dao.cfg.hooks!.beforeSave?.(dbm)
|
|
1198
|
+
dbmsByTable[table].push(dbm)
|
|
1212
1199
|
} else {
|
|
1213
1200
|
// Plural
|
|
1214
1201
|
input.rows.forEach(bm => dao.assignIdCreatedUpdated(bm, opt))
|
|
1215
|
-
|
|
1202
|
+
const dbms = await dao.bmsToDBM(input.rows, opt)
|
|
1203
|
+
if (dao.cfg.hooks!.beforeSave) {
|
|
1204
|
+
dbms.forEach(dbm => dao.cfg.hooks!.beforeSave!(dbm))
|
|
1205
|
+
}
|
|
1206
|
+
dbmsByTable[table].push(...dbms)
|
|
1216
1207
|
}
|
|
1217
1208
|
})
|
|
1218
1209
|
|