@naturalcycles/db-lib 8.51.1 → 8.53.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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyObject, AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Saved, Unsaved, ZodSchema } from '@naturalcycles/js-lib';
|
|
1
|
+
import { AnyObject, AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Promisable, Saved, Unsaved, ZodSchema } from '@naturalcycles/js-lib';
|
|
2
2
|
import { AjvSchema, ObjectSchemaTyped, ReadableTyped } from '@naturalcycles/nodejs-lib';
|
|
3
3
|
import { DBDeleteByIdsOperation, DBModelType, DBOperation, DBPatch, DBSaveBatchOperation, RunQueryResult } from '../db.model';
|
|
4
4
|
import { DBQuery, RunnableDBQuery } from '../query/dbQuery';
|
|
@@ -85,9 +85,9 @@ export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
85
85
|
assignIdCreatedUpdated(obj: Unsaved<BM>, opt?: CommonDaoOptions): Saved<BM>;
|
|
86
86
|
tx: {
|
|
87
87
|
save: (bm: Unsaved<BM>, opt?: CommonDaoSaveOptions<DBM>) => Promise<DBSaveBatchOperation>;
|
|
88
|
-
saveBatch: (bms: Unsaved<BM>[], opt?: CommonDaoSaveOptions<DBM>) => Promise<DBSaveBatchOperation>;
|
|
89
|
-
deleteByIds: (ids: ID[], opt?: CommonDaoOptions) => Promise<DBDeleteByIdsOperation>;
|
|
90
|
-
deleteById: (id: ID, opt?: CommonDaoOptions) => Promise<DBDeleteByIdsOperation>;
|
|
88
|
+
saveBatch: (bms: Unsaved<BM>[], opt?: CommonDaoSaveOptions<DBM>) => Promise<DBSaveBatchOperation | undefined>;
|
|
89
|
+
deleteByIds: (ids: ID[], opt?: CommonDaoOptions) => Promise<DBDeleteByIdsOperation | undefined>;
|
|
90
|
+
deleteById: (id: ID | null | undefined, opt?: CommonDaoOptions) => Promise<DBDeleteByIdsOperation | undefined>;
|
|
91
91
|
};
|
|
92
92
|
/**
|
|
93
93
|
* Mutates with id, created, updated
|
|
@@ -139,9 +139,6 @@ export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
139
139
|
bmToTM(bm: undefined, opt?: CommonDaoOptions): TM | undefined;
|
|
140
140
|
bmToTM(bm?: Saved<BM>, opt?: CommonDaoOptions): TM;
|
|
141
141
|
bmsToTM(bms: Saved<BM>[], opt?: CommonDaoOptions): TM[];
|
|
142
|
-
tmToBM(tm: undefined, opt?: CommonDaoOptions): undefined;
|
|
143
|
-
tmToBM(tm?: TM, opt?: CommonDaoOptions): BM;
|
|
144
|
-
tmsToBM(tms: TM[], opt?: CommonDaoOptions): BM[];
|
|
145
142
|
/**
|
|
146
143
|
* Returns *converted value*.
|
|
147
144
|
* Validates (unless `skipValidation=true` passed).
|
|
@@ -155,7 +152,7 @@ export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
155
152
|
* Proxy to this.cfg.db.ping
|
|
156
153
|
*/
|
|
157
154
|
ping(): Promise<void>;
|
|
158
|
-
runInTransaction(ops:
|
|
155
|
+
runInTransaction(ops: Promisable<DBOperation | undefined>[]): Promise<void>;
|
|
159
156
|
protected logResult(started: number, op: string, res: any, table: string): void;
|
|
160
157
|
protected logSaveResult(started: number, op: string, table: string): void;
|
|
161
158
|
protected logStarted(op: string, table: string, force?: boolean): number;
|
|
@@ -34,6 +34,8 @@ class CommonDao {
|
|
|
34
34
|
};
|
|
35
35
|
},
|
|
36
36
|
saveBatch: async (bms, opt = {}) => {
|
|
37
|
+
if (!bms.length)
|
|
38
|
+
return;
|
|
37
39
|
const rows = (await this.saveBatch(bms, { ...opt, tx: true }));
|
|
38
40
|
return {
|
|
39
41
|
type: 'saveBatch',
|
|
@@ -46,6 +48,8 @@ class CommonDao {
|
|
|
46
48
|
};
|
|
47
49
|
},
|
|
48
50
|
deleteByIds: async (ids, opt = {}) => {
|
|
51
|
+
if (!ids.length)
|
|
52
|
+
return;
|
|
49
53
|
return {
|
|
50
54
|
type: 'deleteByIds',
|
|
51
55
|
table: this.cfg.table,
|
|
@@ -54,6 +58,8 @@ class CommonDao {
|
|
|
54
58
|
};
|
|
55
59
|
},
|
|
56
60
|
deleteById: async (id, opt = {}) => {
|
|
61
|
+
if (!id)
|
|
62
|
+
return;
|
|
57
63
|
return {
|
|
58
64
|
type: 'deleteByIds',
|
|
59
65
|
table: this.cfg.table,
|
|
@@ -80,7 +86,6 @@ class CommonDao {
|
|
|
80
86
|
beforeDBMValidate: dbm => dbm,
|
|
81
87
|
beforeDBMToBM: dbm => dbm,
|
|
82
88
|
beforeBMToDBM: bm => bm,
|
|
83
|
-
beforeTMToBM: tm => tm,
|
|
84
89
|
beforeBMToTM: bm => bm,
|
|
85
90
|
anonymize: dbm => dbm,
|
|
86
91
|
onValidationError: err => err,
|
|
@@ -784,22 +789,6 @@ class CommonDao {
|
|
|
784
789
|
// try/catch?
|
|
785
790
|
return bms.map(bm => this.bmToTM(bm, opt));
|
|
786
791
|
}
|
|
787
|
-
tmToBM(tm, opt = {}) {
|
|
788
|
-
if (!tm)
|
|
789
|
-
return;
|
|
790
|
-
// optimization: 1 validation is enough
|
|
791
|
-
// Validate/convert TM
|
|
792
|
-
// bm gets assigned to the new reference
|
|
793
|
-
// tm = this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
|
|
794
|
-
// TM > BM
|
|
795
|
-
const bm = this.cfg.hooks.beforeTMToBM(tm);
|
|
796
|
-
// Validate/convert BM
|
|
797
|
-
return this.validateAndConvert(bm, this.cfg.bmSchema, db_model_1.DBModelType.BM, opt);
|
|
798
|
-
}
|
|
799
|
-
tmsToBM(tms, opt = {}) {
|
|
800
|
-
// try/catch?
|
|
801
|
-
return tms.map(tm => this.tmToBM(tm, opt));
|
|
802
|
-
}
|
|
803
792
|
/**
|
|
804
793
|
* Returns *converted value*.
|
|
805
794
|
* Validates (unless `skipValidation=true` passed).
|
|
@@ -879,9 +868,9 @@ class CommonDao {
|
|
|
879
868
|
await this.cfg.db.ping();
|
|
880
869
|
}
|
|
881
870
|
async runInTransaction(ops) {
|
|
882
|
-
|
|
871
|
+
const resolvedOps = (await Promise.all(ops)).filter(js_lib_1._isTruthy);
|
|
872
|
+
if (!resolvedOps.length)
|
|
883
873
|
return;
|
|
884
|
-
const resolvedOps = await Promise.all(ops);
|
|
885
874
|
await this.cfg.db.commitTransaction(dbTransaction_1.DBTransaction.create(resolvedOps));
|
|
886
875
|
}
|
|
887
876
|
logResult(started, op, res, table) {
|
|
@@ -3,19 +3,53 @@ import { AjvSchema, AjvValidationError, JoiValidationError, ObjectSchemaTyped, T
|
|
|
3
3
|
import { CommonDB } from '../common.db';
|
|
4
4
|
import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model';
|
|
5
5
|
export interface CommonDaoHooks<BM extends Partial<ObjectWithId<ID>>, DBM extends ObjectWithId<ID>, TM, ID extends string | number> {
|
|
6
|
+
/**
|
|
7
|
+
* Allows to override the id generation function.
|
|
8
|
+
* By default it uses `stringId` from nodejs-lib
|
|
9
|
+
* (which uses lowercase alphanumberic alphabet and the size of 16).
|
|
10
|
+
*/
|
|
6
11
|
createRandomId: () => ID;
|
|
7
12
|
/**
|
|
8
13
|
* createNaturalId hook is called (tried) first.
|
|
9
14
|
* If it doesn't exist - createRandomId is called.
|
|
10
15
|
*/
|
|
11
16
|
createNaturalId: (obj: DBM | BM) => ID;
|
|
17
|
+
/**
|
|
18
|
+
* It's a counter-part of `createNaturalId`.
|
|
19
|
+
* Allows to provide a parser function to parse "natural id" into
|
|
20
|
+
* DBM components (e.g accountId and some other property that is part of the id).
|
|
21
|
+
*/
|
|
12
22
|
parseNaturalId: (id: ID) => Partial<DBM>;
|
|
23
|
+
/**
|
|
24
|
+
* It is called only on `dao.create` method.
|
|
25
|
+
* Dao.create method is called in:
|
|
26
|
+
*
|
|
27
|
+
* - getByIdOrEmpty, getByIdAsDBMOrEmpty
|
|
28
|
+
* - patch, patchAsDBM
|
|
29
|
+
*/
|
|
13
30
|
beforeCreate: (bm: Partial<BM>) => Partial<BM>;
|
|
31
|
+
/**
|
|
32
|
+
* Called when loading things "as DBM" and validation is not skipped.
|
|
33
|
+
* When loading things like BM/TM - other hooks get involved instead:
|
|
34
|
+
* - beforeDBMToBM
|
|
35
|
+
* - beforeBMToTM
|
|
36
|
+
*
|
|
37
|
+
* TODO: maybe rename those to `validateAs(model)`
|
|
38
|
+
* as it only validates "final state", not intermediate
|
|
39
|
+
*/
|
|
14
40
|
beforeDBMValidate: (dbm: Partial<DBM>) => Partial<DBM>;
|
|
15
41
|
beforeDBMToBM: (dbm: DBM) => Partial<BM> | Promise<Partial<BM>>;
|
|
16
42
|
beforeBMToDBM: (bm: BM) => Partial<DBM> | Promise<Partial<DBM>>;
|
|
17
|
-
beforeTMToBM: (tm: TM) => Partial<BM>;
|
|
18
43
|
beforeBMToTM: (bm: BM) => Partial<TM>;
|
|
44
|
+
/**
|
|
45
|
+
* Called in:
|
|
46
|
+
* - dbmToBM (applied before DBM becomes BM)
|
|
47
|
+
* - anyToDBM
|
|
48
|
+
*
|
|
49
|
+
* Hook only allows to apply anonymization to DBM (not to BM).
|
|
50
|
+
* It still applies to BM "transitively", during dbmToBM
|
|
51
|
+
* (e.g after loaded from the Database).
|
|
52
|
+
*/
|
|
19
53
|
anonymize: (dbm: DBM) => DBM;
|
|
20
54
|
/**
|
|
21
55
|
* If hook is defined - allows to prevent or modify the error thrown.
|
package/package.json
CHANGED
|
@@ -23,19 +23,59 @@ export interface CommonDaoHooks<
|
|
|
23
23
|
TM,
|
|
24
24
|
ID extends string | number,
|
|
25
25
|
> {
|
|
26
|
+
/**
|
|
27
|
+
* Allows to override the id generation function.
|
|
28
|
+
* By default it uses `stringId` from nodejs-lib
|
|
29
|
+
* (which uses lowercase alphanumberic alphabet and the size of 16).
|
|
30
|
+
*/
|
|
26
31
|
createRandomId: () => ID
|
|
32
|
+
|
|
27
33
|
/**
|
|
28
34
|
* createNaturalId hook is called (tried) first.
|
|
29
35
|
* If it doesn't exist - createRandomId is called.
|
|
30
36
|
*/
|
|
31
37
|
createNaturalId: (obj: DBM | BM) => ID
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* It's a counter-part of `createNaturalId`.
|
|
41
|
+
* Allows to provide a parser function to parse "natural id" into
|
|
42
|
+
* DBM components (e.g accountId and some other property that is part of the id).
|
|
43
|
+
*/
|
|
32
44
|
parseNaturalId: (id: ID) => Partial<DBM>
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* It is called only on `dao.create` method.
|
|
48
|
+
* Dao.create method is called in:
|
|
49
|
+
*
|
|
50
|
+
* - getByIdOrEmpty, getByIdAsDBMOrEmpty
|
|
51
|
+
* - patch, patchAsDBM
|
|
52
|
+
*/
|
|
33
53
|
beforeCreate: (bm: Partial<BM>) => Partial<BM>
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Called when loading things "as DBM" and validation is not skipped.
|
|
57
|
+
* When loading things like BM/TM - other hooks get involved instead:
|
|
58
|
+
* - beforeDBMToBM
|
|
59
|
+
* - beforeBMToTM
|
|
60
|
+
*
|
|
61
|
+
* TODO: maybe rename those to `validateAs(model)`
|
|
62
|
+
* as it only validates "final state", not intermediate
|
|
63
|
+
*/
|
|
34
64
|
beforeDBMValidate: (dbm: Partial<DBM>) => Partial<DBM>
|
|
65
|
+
|
|
35
66
|
beforeDBMToBM: (dbm: DBM) => Partial<BM> | Promise<Partial<BM>>
|
|
36
67
|
beforeBMToDBM: (bm: BM) => Partial<DBM> | Promise<Partial<DBM>>
|
|
37
|
-
beforeTMToBM: (tm: TM) => Partial<BM>
|
|
38
68
|
beforeBMToTM: (bm: BM) => Partial<TM>
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Called in:
|
|
72
|
+
* - dbmToBM (applied before DBM becomes BM)
|
|
73
|
+
* - anyToDBM
|
|
74
|
+
*
|
|
75
|
+
* Hook only allows to apply anonymization to DBM (not to BM).
|
|
76
|
+
* It still applies to BM "transitively", during dbmToBM
|
|
77
|
+
* (e.g after loaded from the Database).
|
|
78
|
+
*/
|
|
39
79
|
anonymize: (dbm: DBM) => DBM
|
|
40
80
|
|
|
41
81
|
/**
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
_assert,
|
|
3
3
|
_filterNullishValues,
|
|
4
4
|
_filterUndefinedValues,
|
|
5
|
+
_isTruthy,
|
|
5
6
|
_passthroughPredicate,
|
|
6
7
|
_since,
|
|
7
8
|
_truncate,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
JsonSchemaRootObject,
|
|
15
16
|
ObjectWithId,
|
|
16
17
|
pMap,
|
|
18
|
+
Promisable,
|
|
17
19
|
Saved,
|
|
18
20
|
Unsaved,
|
|
19
21
|
ZodSchema,
|
|
@@ -93,7 +95,6 @@ export class CommonDao<
|
|
|
93
95
|
beforeDBMValidate: dbm => dbm,
|
|
94
96
|
beforeDBMToBM: dbm => dbm as any,
|
|
95
97
|
beforeBMToDBM: bm => bm as any,
|
|
96
|
-
beforeTMToBM: tm => tm as any,
|
|
97
98
|
beforeBMToTM: bm => bm as any,
|
|
98
99
|
anonymize: dbm => dbm,
|
|
99
100
|
onValidationError: err => err,
|
|
@@ -633,7 +634,8 @@ export class CommonDao<
|
|
|
633
634
|
saveBatch: async (
|
|
634
635
|
bms: Unsaved<BM>[],
|
|
635
636
|
opt: CommonDaoSaveOptions<DBM> = {},
|
|
636
|
-
): Promise<DBSaveBatchOperation> => {
|
|
637
|
+
): Promise<DBSaveBatchOperation | undefined> => {
|
|
638
|
+
if (!bms.length) return
|
|
637
639
|
const rows: DBM[] = (await this.saveBatch(bms, { ...opt, tx: true })) as any
|
|
638
640
|
|
|
639
641
|
return {
|
|
@@ -646,7 +648,11 @@ export class CommonDao<
|
|
|
646
648
|
},
|
|
647
649
|
}
|
|
648
650
|
},
|
|
649
|
-
deleteByIds: async (
|
|
651
|
+
deleteByIds: async (
|
|
652
|
+
ids: ID[],
|
|
653
|
+
opt: CommonDaoOptions = {},
|
|
654
|
+
): Promise<DBDeleteByIdsOperation | undefined> => {
|
|
655
|
+
if (!ids.length) return
|
|
650
656
|
return {
|
|
651
657
|
type: 'deleteByIds',
|
|
652
658
|
table: this.cfg.table,
|
|
@@ -654,7 +660,11 @@ export class CommonDao<
|
|
|
654
660
|
opt,
|
|
655
661
|
}
|
|
656
662
|
},
|
|
657
|
-
deleteById: async (
|
|
663
|
+
deleteById: async (
|
|
664
|
+
id: ID | null | undefined,
|
|
665
|
+
opt: CommonDaoOptions = {},
|
|
666
|
+
): Promise<DBDeleteByIdsOperation | undefined> => {
|
|
667
|
+
if (!id) return
|
|
658
668
|
return {
|
|
659
669
|
type: 'deleteByIds',
|
|
660
670
|
table: this.cfg.table,
|
|
@@ -1050,28 +1060,6 @@ export class CommonDao<
|
|
|
1050
1060
|
return bms.map(bm => this.bmToTM(bm, opt))
|
|
1051
1061
|
}
|
|
1052
1062
|
|
|
1053
|
-
tmToBM(tm: undefined, opt?: CommonDaoOptions): undefined
|
|
1054
|
-
tmToBM(tm?: TM, opt?: CommonDaoOptions): BM
|
|
1055
|
-
tmToBM(tm?: TM, opt: CommonDaoOptions = {}): BM | undefined {
|
|
1056
|
-
if (!tm) return
|
|
1057
|
-
|
|
1058
|
-
// optimization: 1 validation is enough
|
|
1059
|
-
// Validate/convert TM
|
|
1060
|
-
// bm gets assigned to the new reference
|
|
1061
|
-
// tm = this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
|
|
1062
|
-
|
|
1063
|
-
// TM > BM
|
|
1064
|
-
const bm = this.cfg.hooks!.beforeTMToBM!(tm) as BM
|
|
1065
|
-
|
|
1066
|
-
// Validate/convert BM
|
|
1067
|
-
return this.validateAndConvert<BM>(bm, this.cfg.bmSchema, DBModelType.BM, opt)
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
tmsToBM(tms: TM[], opt: CommonDaoOptions = {}): BM[] {
|
|
1071
|
-
// try/catch?
|
|
1072
|
-
return tms.map(tm => this.tmToBM(tm, opt))
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
1063
|
/**
|
|
1076
1064
|
* Returns *converted value*.
|
|
1077
1065
|
* Validates (unless `skipValidation=true` passed).
|
|
@@ -1164,10 +1152,9 @@ export class CommonDao<
|
|
|
1164
1152
|
await this.cfg.db.ping()
|
|
1165
1153
|
}
|
|
1166
1154
|
|
|
1167
|
-
async runInTransaction(ops:
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
const resolvedOps = await Promise.all(ops)
|
|
1155
|
+
async runInTransaction(ops: Promisable<DBOperation | undefined>[]): Promise<void> {
|
|
1156
|
+
const resolvedOps = (await Promise.all(ops)).filter(_isTruthy)
|
|
1157
|
+
if (!resolvedOps.length) return
|
|
1171
1158
|
|
|
1172
1159
|
await this.cfg.db.commitTransaction(DBTransaction.create(resolvedOps))
|
|
1173
1160
|
}
|
package/src/db.model.ts
CHANGED