@naturalcycles/db-lib 9.4.0 → 9.4.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/cachedb/cache.db.d.ts +10 -10
- package/dist/adapter/cachedb/cache.db.model.d.ts +2 -2
- package/dist/adapter/file/file.db.d.ts +12 -12
- package/dist/adapter/file/file.db.model.d.ts +3 -3
- package/dist/adapter/file/inMemory.persistence.plugin.d.ts +1 -1
- package/dist/adapter/file/localFile.persistence.plugin.d.ts +4 -4
- package/dist/adapter/file/noop.persistence.plugin.d.ts +3 -3
- package/dist/adapter/inmemory/inMemory.db.d.ts +12 -12
- package/dist/adapter/inmemory/queryInMemory.d.ts +2 -2
- package/dist/base.common.db.d.ts +10 -10
- package/dist/common.db.d.ts +10 -10
- package/dist/commondao/common.dao.d.ts +19 -19
- package/dist/commondao/common.dao.js +1 -0
- package/dist/commondao/common.dao.model.d.ts +9 -9
- package/dist/db.model.d.ts +5 -5
- package/dist/pipeline/dbPipelineBackup.d.ts +1 -1
- package/dist/pipeline/dbPipelineCopy.d.ts +1 -1
- package/dist/pipeline/dbPipelineRestore.d.ts +1 -1
- package/dist/query/dbQuery.d.ts +7 -7
- package/dist/transaction/dbTransaction.util.d.ts +3 -3
- package/dist/validation/index.d.ts +2 -2
- package/package.json +1 -1
- package/src/adapter/cachedb/cache.db.model.ts +2 -2
- package/src/adapter/cachedb/cache.db.ts +14 -15
- package/src/adapter/file/file.db.model.ts +3 -3
- package/src/adapter/file/file.db.ts +15 -18
- package/src/adapter/file/inMemory.persistence.plugin.ts +1 -1
- package/src/adapter/file/localFile.persistence.plugin.ts +5 -5
- package/src/adapter/file/noop.persistence.plugin.ts +3 -3
- package/src/adapter/inmemory/inMemory.db.ts +17 -19
- package/src/adapter/inmemory/queryInMemory.ts +2 -5
- package/src/base.common.db.ts +10 -20
- package/src/common.db.ts +13 -20
- package/src/commondao/common.dao.model.ts +11 -17
- package/src/commondao/common.dao.ts +50 -42
- package/src/db.model.ts +5 -6
- package/src/pipeline/dbPipelineBackup.ts +1 -1
- package/src/pipeline/dbPipelineCopy.ts +11 -4
- package/src/pipeline/dbPipelineRestore.ts +5 -4
- package/src/query/dbQuery.ts +9 -11
- package/src/timeseries/commonTimeSeriesDao.ts +1 -1
- package/src/transaction/dbTransaction.util.ts +3 -3
- package/src/validation/index.ts +3 -3
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AnyObject,
|
|
3
|
+
BaseDBEntity,
|
|
3
4
|
CommonLogger,
|
|
4
5
|
ErrorMode,
|
|
5
|
-
PartialObjectWithId,
|
|
6
6
|
Promisable,
|
|
7
7
|
Saved,
|
|
8
8
|
ZodError,
|
|
@@ -19,11 +19,7 @@ import {
|
|
|
19
19
|
import { CommonDB } from '../common.db'
|
|
20
20
|
import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model'
|
|
21
21
|
|
|
22
|
-
export interface CommonDaoHooks<
|
|
23
|
-
BM extends PartialObjectWithId,
|
|
24
|
-
DBM extends PartialObjectWithId,
|
|
25
|
-
TM,
|
|
26
|
-
> {
|
|
22
|
+
export interface CommonDaoHooks<BM extends BaseDBEntity, DBM extends BaseDBEntity, TM> {
|
|
27
23
|
/**
|
|
28
24
|
* Allows to override the id generation function.
|
|
29
25
|
* By default it uses `stringId` from nodejs-lib
|
|
@@ -64,7 +60,7 @@ export interface CommonDaoHooks<
|
|
|
64
60
|
*/
|
|
65
61
|
beforeDBMValidate: (dbm: Partial<DBM>) => Partial<DBM>
|
|
66
62
|
|
|
67
|
-
beforeDBMToBM: (dbm:
|
|
63
|
+
beforeDBMToBM: (dbm: DBM) => Partial<BM> | Promise<Partial<BM>>
|
|
68
64
|
beforeBMToDBM: (bm: BM) => Partial<DBM> | Promise<Partial<DBM>>
|
|
69
65
|
beforeBMToTM: (bm: BM) => Partial<TM>
|
|
70
66
|
|
|
@@ -106,7 +102,7 @@ export interface CommonDaoHooks<
|
|
|
106
102
|
* It still applies to BM "transitively", during dbmToBM
|
|
107
103
|
* (e.g after loaded from the Database).
|
|
108
104
|
*/
|
|
109
|
-
anonymize: (dbm:
|
|
105
|
+
anonymize: (dbm: DBM) => DBM
|
|
110
106
|
|
|
111
107
|
/**
|
|
112
108
|
* If hook is defined - allows to prevent or modify the error thrown.
|
|
@@ -137,8 +133,8 @@ export enum CommonDaoLogLevel {
|
|
|
137
133
|
}
|
|
138
134
|
|
|
139
135
|
export interface CommonDaoCfg<
|
|
140
|
-
BM extends
|
|
141
|
-
DBM extends
|
|
136
|
+
BM extends BaseDBEntity,
|
|
137
|
+
DBM extends BaseDBEntity = BM,
|
|
142
138
|
TM extends AnyObject = BM,
|
|
143
139
|
> {
|
|
144
140
|
db: CommonDB
|
|
@@ -289,10 +285,8 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
289
285
|
table?: string
|
|
290
286
|
}
|
|
291
287
|
|
|
292
|
-
export interface CommonDaoSaveOptions<
|
|
293
|
-
|
|
294
|
-
DBM extends PartialObjectWithId,
|
|
295
|
-
> extends CommonDaoSaveBatchOptions<DBM> {
|
|
288
|
+
export interface CommonDaoSaveOptions<BM extends BaseDBEntity, DBM extends BaseDBEntity>
|
|
289
|
+
extends CommonDaoSaveBatchOptions<DBM> {
|
|
296
290
|
/**
|
|
297
291
|
* If provided - a check will be made.
|
|
298
292
|
* If the object for saving equals to the object passed to `skipIfEquals` - save operation will be skipped.
|
|
@@ -307,7 +301,7 @@ export interface CommonDaoSaveOptions<
|
|
|
307
301
|
/**
|
|
308
302
|
* All properties default to undefined.
|
|
309
303
|
*/
|
|
310
|
-
export interface CommonDaoSaveBatchOptions<DBM extends
|
|
304
|
+
export interface CommonDaoSaveBatchOptions<DBM extends BaseDBEntity>
|
|
311
305
|
extends CommonDaoOptions,
|
|
312
306
|
CommonDBSaveOptions<DBM> {
|
|
313
307
|
/**
|
|
@@ -322,10 +316,10 @@ export interface CommonDaoSaveBatchOptions<DBM extends PartialObjectWithId>
|
|
|
322
316
|
ensureUniqueId?: boolean
|
|
323
317
|
}
|
|
324
318
|
|
|
325
|
-
export interface CommonDaoStreamDeleteOptions<DBM extends
|
|
319
|
+
export interface CommonDaoStreamDeleteOptions<DBM extends BaseDBEntity>
|
|
326
320
|
extends CommonDaoStreamOptions<DBM> {}
|
|
327
321
|
|
|
328
|
-
export interface CommonDaoStreamSaveOptions<DBM extends
|
|
322
|
+
export interface CommonDaoStreamSaveOptions<DBM extends BaseDBEntity>
|
|
329
323
|
extends CommonDaoSaveBatchOptions<DBM>,
|
|
330
324
|
CommonDaoStreamOptions<DBM> {}
|
|
331
325
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
_passthroughPredicate,
|
|
10
10
|
_since,
|
|
11
11
|
_truncate,
|
|
12
|
+
_typeCast,
|
|
12
13
|
_uniqBy,
|
|
13
14
|
AnyObject,
|
|
14
15
|
AppError,
|
|
@@ -19,11 +20,11 @@ import {
|
|
|
19
20
|
JsonSchemaObject,
|
|
20
21
|
JsonSchemaRootObject,
|
|
21
22
|
ObjectWithId,
|
|
22
|
-
PartialObjectWithId,
|
|
23
23
|
pMap,
|
|
24
24
|
Saved,
|
|
25
25
|
SKIP,
|
|
26
26
|
UnixTimestampMillisNumber,
|
|
27
|
+
UnsavedId,
|
|
27
28
|
ZodSchema,
|
|
28
29
|
ZodValidationError,
|
|
29
30
|
zSafeValidate,
|
|
@@ -77,8 +78,8 @@ const isCI = !!process.env['CI']
|
|
|
77
78
|
* TM = Transport model (optimized to be sent over the wire)
|
|
78
79
|
*/
|
|
79
80
|
export class CommonDao<
|
|
80
|
-
BM extends
|
|
81
|
-
DBM extends
|
|
81
|
+
BM extends BaseDBEntity,
|
|
82
|
+
DBM extends BaseDBEntity = BM,
|
|
82
83
|
TM extends AnyObject = BM,
|
|
83
84
|
> {
|
|
84
85
|
constructor(public cfg: CommonDaoCfg<BM, DBM, TM>) {
|
|
@@ -130,7 +131,7 @@ export class CommonDao<
|
|
|
130
131
|
const table = opt.table || this.cfg.table
|
|
131
132
|
const started = this.logStarted(op, table)
|
|
132
133
|
|
|
133
|
-
let dbm = (await (opt.tx || this.cfg.db).getByIds<DBM
|
|
134
|
+
let dbm = (await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, [id]))[0]
|
|
134
135
|
if (dbm && !opt.raw && this.cfg.hooks!.afterLoad) {
|
|
135
136
|
dbm = (await this.cfg.hooks!.afterLoad(dbm)) || undefined
|
|
136
137
|
}
|
|
@@ -170,7 +171,7 @@ export class CommonDao<
|
|
|
170
171
|
const op = `getByIdAsDBM(${id})`
|
|
171
172
|
const table = opt.table || this.cfg.table
|
|
172
173
|
const started = this.logStarted(op, table)
|
|
173
|
-
let [dbm] = await (opt.tx || this.cfg.db).getByIds<DBM
|
|
174
|
+
let [dbm] = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, [id])
|
|
174
175
|
if (dbm && !opt.raw && this.cfg.hooks!.afterLoad) {
|
|
175
176
|
dbm = (await this.cfg.hooks!.afterLoad(dbm)) || undefined
|
|
176
177
|
}
|
|
@@ -189,7 +190,7 @@ export class CommonDao<
|
|
|
189
190
|
const op = `getByIdAsTM(${id})`
|
|
190
191
|
const table = opt.table || this.cfg.table
|
|
191
192
|
const started = this.logStarted(op, table)
|
|
192
|
-
let [dbm] = await (opt.tx || this.cfg.db).getByIds<DBM
|
|
193
|
+
let [dbm] = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, [id])
|
|
193
194
|
if (dbm && !opt.raw && this.cfg.hooks!.afterLoad) {
|
|
194
195
|
dbm = (await this.cfg.hooks!.afterLoad(dbm)) || undefined
|
|
195
196
|
}
|
|
@@ -209,7 +210,7 @@ export class CommonDao<
|
|
|
209
210
|
const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
210
211
|
const table = opt.table || this.cfg.table
|
|
211
212
|
const started = this.logStarted(op, table)
|
|
212
|
-
let dbms = await (opt.tx || this.cfg.db).getByIds<DBM
|
|
213
|
+
let dbms = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, ids)
|
|
213
214
|
if (!opt.raw && this.cfg.hooks!.afterLoad && dbms.length) {
|
|
214
215
|
dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
|
|
215
216
|
_isTruthy,
|
|
@@ -226,7 +227,7 @@ export class CommonDao<
|
|
|
226
227
|
const op = `getByIdsAsDBM ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
227
228
|
const table = opt.table || this.cfg.table
|
|
228
229
|
const started = this.logStarted(op, table)
|
|
229
|
-
let dbms = await (opt.tx || this.cfg.db).getByIds<DBM
|
|
230
|
+
let dbms = await (opt.tx || this.cfg.db).getByIds<Saved<DBM>>(table, ids)
|
|
230
231
|
if (!opt.raw && this.cfg.hooks!.afterLoad && dbms.length) {
|
|
231
232
|
dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
|
|
232
233
|
_isTruthy,
|
|
@@ -283,7 +284,7 @@ export class CommonDao<
|
|
|
283
284
|
}
|
|
284
285
|
}
|
|
285
286
|
|
|
286
|
-
private async ensureUniqueId(table: string, dbm:
|
|
287
|
+
private async ensureUniqueId(table: string, dbm: DBM): Promise<void> {
|
|
287
288
|
// todo: retry N times
|
|
288
289
|
const existing = await this.cfg.db.getByIds<DBM>(table, [dbm.id])
|
|
289
290
|
if (existing.length) {
|
|
@@ -351,7 +352,7 @@ export class CommonDao<
|
|
|
351
352
|
q.table = opt.table || q.table
|
|
352
353
|
const op = `runQuery(${q.pretty()})`
|
|
353
354
|
const started = this.logStarted(op, q.table)
|
|
354
|
-
let { rows, ...queryResult } = await this.cfg.db.runQuery<DBM
|
|
355
|
+
let { rows, ...queryResult } = await this.cfg.db.runQuery<Saved<DBM>>(q, opt)
|
|
355
356
|
const partialQuery = !!q._selectedFieldNames
|
|
356
357
|
if (!opt.raw && this.cfg.hooks!.afterLoad && rows.length) {
|
|
357
358
|
rows = (await pMap(rows, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
|
|
@@ -379,7 +380,7 @@ export class CommonDao<
|
|
|
379
380
|
q.table = opt.table || q.table
|
|
380
381
|
const op = `runQueryAsDBM(${q.pretty()})`
|
|
381
382
|
const started = this.logStarted(op, q.table)
|
|
382
|
-
let { rows, ...queryResult } = await this.cfg.db.runQuery<DBM
|
|
383
|
+
let { rows, ...queryResult } = await this.cfg.db.runQuery<Saved<DBM>>(q, opt)
|
|
383
384
|
if (!opt.raw && this.cfg.hooks!.afterLoad && rows.length) {
|
|
384
385
|
rows = (await pMap(rows, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
|
|
385
386
|
_isTruthy,
|
|
@@ -404,7 +405,7 @@ export class CommonDao<
|
|
|
404
405
|
q.table = opt.table || q.table
|
|
405
406
|
const op = `runQueryAsTM(${q.pretty()})`
|
|
406
407
|
const started = this.logStarted(op, q.table)
|
|
407
|
-
let { rows, ...queryResult } = await this.cfg.db.runQuery<DBM
|
|
408
|
+
let { rows, ...queryResult } = await this.cfg.db.runQuery<Saved<DBM>>(q, opt)
|
|
408
409
|
if (!opt.raw && this.cfg.hooks!.afterLoad && rows.length) {
|
|
409
410
|
rows = (await pMap(rows, async dbm => await this.cfg.hooks!.afterLoad!(dbm))).filter(
|
|
410
411
|
_isTruthy,
|
|
@@ -678,7 +679,7 @@ export class CommonDao<
|
|
|
678
679
|
* Mutates!
|
|
679
680
|
* "Returns", just to have a type of "Saved"
|
|
680
681
|
*/
|
|
681
|
-
assignIdCreatedUpdated<T extends BaseDBEntity>(obj: T
|
|
682
|
+
assignIdCreatedUpdated<T extends BaseDBEntity>(obj: Partial<T>, opt: CommonDaoOptions = {}): T {
|
|
682
683
|
const now = Math.floor(Date.now() / 1000)
|
|
683
684
|
|
|
684
685
|
if (this.cfg.useCreatedProperty) {
|
|
@@ -693,14 +694,14 @@ export class CommonDao<
|
|
|
693
694
|
obj.id ||= this.cfg.hooks!.createNaturalId?.(obj as any) || this.cfg.hooks!.createRandomId!()
|
|
694
695
|
}
|
|
695
696
|
|
|
696
|
-
return obj as
|
|
697
|
+
return obj as T
|
|
697
698
|
}
|
|
698
699
|
|
|
699
700
|
// SAVE
|
|
700
701
|
/**
|
|
701
702
|
* Mutates with id, created, updated
|
|
702
703
|
*/
|
|
703
|
-
async save(bm: BM
|
|
704
|
+
async save(bm: UnsavedId<BM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<Saved<BM>> {
|
|
704
705
|
this.requireWriteAccess()
|
|
705
706
|
|
|
706
707
|
if (opt.skipIfEquals && _deepJsonEquals(bm, opt.skipIfEquals)) {
|
|
@@ -710,11 +711,12 @@ export class CommonDao<
|
|
|
710
711
|
|
|
711
712
|
const idWasGenerated = !bm.id && this.cfg.generateId
|
|
712
713
|
this.assignIdCreatedUpdated(bm, opt) // mutates
|
|
714
|
+
_typeCast<Saved<BM>>(bm)
|
|
713
715
|
let dbm = await this.bmToDBM(bm, opt)
|
|
714
716
|
|
|
715
717
|
if (this.cfg.hooks!.beforeSave) {
|
|
716
718
|
dbm = (await this.cfg.hooks!.beforeSave(dbm))!
|
|
717
|
-
if (dbm === null) return bm
|
|
719
|
+
if (dbm === null) return bm
|
|
718
720
|
}
|
|
719
721
|
|
|
720
722
|
const table = opt.table || this.cfg.table
|
|
@@ -738,7 +740,7 @@ export class CommonDao<
|
|
|
738
740
|
}
|
|
739
741
|
|
|
740
742
|
this.logSaveResult(started, op, table)
|
|
741
|
-
return bm
|
|
743
|
+
return bm
|
|
742
744
|
}
|
|
743
745
|
|
|
744
746
|
/**
|
|
@@ -750,18 +752,18 @@ export class CommonDao<
|
|
|
750
752
|
* Similar to `patch`, but doesn't load the object from the Database.
|
|
751
753
|
*/
|
|
752
754
|
async savePatch(
|
|
753
|
-
bm:
|
|
755
|
+
bm: BM,
|
|
754
756
|
patch: Partial<BM>,
|
|
755
757
|
opt: CommonDaoSaveBatchOptions<DBM>,
|
|
756
758
|
): Promise<Saved<BM>> {
|
|
757
|
-
const patched:
|
|
759
|
+
const patched: BM = {
|
|
758
760
|
...bm,
|
|
759
761
|
...patch,
|
|
760
762
|
}
|
|
761
763
|
|
|
762
764
|
if (_deepJsonEquals(bm, patched)) {
|
|
763
765
|
// Skipping the save operation, as data is the same
|
|
764
|
-
return bm
|
|
766
|
+
return bm as Saved<BM>
|
|
765
767
|
}
|
|
766
768
|
|
|
767
769
|
// Actually apply the patch by mutating the original object (by design)
|
|
@@ -828,7 +830,7 @@ export class CommonDao<
|
|
|
828
830
|
* It still loads the row from the DB.
|
|
829
831
|
*/
|
|
830
832
|
async patch(
|
|
831
|
-
bm:
|
|
833
|
+
bm: BM,
|
|
832
834
|
patch: Partial<BM>,
|
|
833
835
|
opt: CommonDaoSaveBatchOptions<DBM> = {},
|
|
834
836
|
): Promise<Saved<BM>> {
|
|
@@ -846,7 +848,7 @@ export class CommonDao<
|
|
|
846
848
|
|
|
847
849
|
if (_deepJsonEquals(loaded, bm)) {
|
|
848
850
|
// Skipping the save operation, as data is the same
|
|
849
|
-
return bm
|
|
851
|
+
return bm as Saved<BM>
|
|
850
852
|
}
|
|
851
853
|
|
|
852
854
|
// Make `bm` exactly the same as `loaded`
|
|
@@ -862,7 +864,7 @@ export class CommonDao<
|
|
|
862
864
|
* Like patch, but runs all operations within a Transaction.
|
|
863
865
|
*/
|
|
864
866
|
async patchInTransaction(
|
|
865
|
-
bm:
|
|
867
|
+
bm: BM,
|
|
866
868
|
patch: Partial<BM>,
|
|
867
869
|
opt?: CommonDaoSaveBatchOptions<DBM>,
|
|
868
870
|
): Promise<Saved<BM>> {
|
|
@@ -871,7 +873,10 @@ export class CommonDao<
|
|
|
871
873
|
})
|
|
872
874
|
}
|
|
873
875
|
|
|
874
|
-
async saveAsDBM(
|
|
876
|
+
async saveAsDBM(
|
|
877
|
+
dbm: UnsavedId<DBM>,
|
|
878
|
+
opt: CommonDaoSaveBatchOptions<DBM> = {},
|
|
879
|
+
): Promise<Saved<DBM>> {
|
|
875
880
|
this.requireWriteAccess()
|
|
876
881
|
const table = opt.table || this.cfg.table
|
|
877
882
|
|
|
@@ -911,12 +916,15 @@ export class CommonDao<
|
|
|
911
916
|
return row
|
|
912
917
|
}
|
|
913
918
|
|
|
914
|
-
async saveBatch(
|
|
919
|
+
async saveBatch(
|
|
920
|
+
bms: UnsavedId<BM>[],
|
|
921
|
+
opt: CommonDaoSaveBatchOptions<DBM> = {},
|
|
922
|
+
): Promise<Saved<BM>[]> {
|
|
915
923
|
if (!bms.length) return []
|
|
916
924
|
this.requireWriteAccess()
|
|
917
925
|
const table = opt.table || this.cfg.table
|
|
918
926
|
bms.forEach(bm => this.assignIdCreatedUpdated(bm, opt))
|
|
919
|
-
let dbms = await this.bmsToDBM(bms, opt)
|
|
927
|
+
let dbms = await this.bmsToDBM(bms as BM[], opt)
|
|
920
928
|
|
|
921
929
|
if (this.cfg.hooks!.beforeSave && dbms.length) {
|
|
922
930
|
dbms = (await pMap(dbms, async dbm => await this.cfg.hooks!.beforeSave!(dbm))).filter(
|
|
@@ -956,7 +964,7 @@ export class CommonDao<
|
|
|
956
964
|
}
|
|
957
965
|
|
|
958
966
|
async saveBatchAsDBM(
|
|
959
|
-
dbms: DBM[],
|
|
967
|
+
dbms: UnsavedId<DBM>[],
|
|
960
968
|
opt: CommonDaoSaveBatchOptions<DBM> = {},
|
|
961
969
|
): Promise<Saved<DBM>[]> {
|
|
962
970
|
if (!dbms.length) return []
|
|
@@ -1183,13 +1191,13 @@ export class CommonDao<
|
|
|
1183
1191
|
// CONVERSIONS
|
|
1184
1192
|
|
|
1185
1193
|
async dbmToBM(_dbm: undefined, opt?: CommonDaoOptions): Promise<undefined>
|
|
1186
|
-
async dbmToBM(_dbm?:
|
|
1187
|
-
async dbmToBM(_dbm?:
|
|
1194
|
+
async dbmToBM(_dbm?: DBM, opt?: CommonDaoOptions): Promise<Saved<BM>>
|
|
1195
|
+
async dbmToBM(_dbm?: DBM, opt: CommonDaoOptions = {}): Promise<Saved<BM> | undefined> {
|
|
1188
1196
|
if (!_dbm) return
|
|
1189
1197
|
|
|
1190
1198
|
// optimization: no need to run full joi DBM validation, cause BM validation will be run
|
|
1191
1199
|
// const dbm = this.anyToDBM(_dbm, opt)
|
|
1192
|
-
let dbm:
|
|
1200
|
+
let dbm: DBM = { ..._dbm, ...this.cfg.hooks!.parseNaturalId!(_dbm.id) }
|
|
1193
1201
|
|
|
1194
1202
|
if (opt.anonymize) {
|
|
1195
1203
|
dbm = this.cfg.hooks!.anonymize!(dbm)
|
|
@@ -1203,7 +1211,7 @@ export class CommonDao<
|
|
|
1203
1211
|
return this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
|
|
1204
1212
|
}
|
|
1205
1213
|
|
|
1206
|
-
async dbmsToBM(dbms:
|
|
1214
|
+
async dbmsToBM(dbms: DBM[], opt: CommonDaoOptions = {}): Promise<Saved<BM>[]> {
|
|
1207
1215
|
return await pMap(dbms, async dbm => await this.dbmToBM(dbm, opt))
|
|
1208
1216
|
}
|
|
1209
1217
|
|
|
@@ -1239,7 +1247,7 @@ export class CommonDao<
|
|
|
1239
1247
|
|
|
1240
1248
|
anyToDBM(dbm: undefined, opt?: CommonDaoOptions): undefined
|
|
1241
1249
|
anyToDBM(dbm?: any, opt?: CommonDaoOptions): Saved<DBM>
|
|
1242
|
-
anyToDBM(dbm?:
|
|
1250
|
+
anyToDBM(dbm?: DBM, opt: CommonDaoOptions = {}): Saved<DBM> | undefined {
|
|
1243
1251
|
if (!dbm) return
|
|
1244
1252
|
|
|
1245
1253
|
// this shouldn't be happening on load! but should on save!
|
|
@@ -1255,13 +1263,13 @@ export class CommonDao<
|
|
|
1255
1263
|
return this.validateAndConvert(dbm, this.cfg.dbmSchema, DBModelType.DBM, opt)
|
|
1256
1264
|
}
|
|
1257
1265
|
|
|
1258
|
-
anyToDBMs(entities:
|
|
1266
|
+
anyToDBMs(entities: DBM[], opt: CommonDaoOptions = {}): Saved<DBM>[] {
|
|
1259
1267
|
return entities.map(entity => this.anyToDBM(entity, opt))
|
|
1260
1268
|
}
|
|
1261
1269
|
|
|
1262
1270
|
bmToTM(bm: undefined, opt?: CommonDaoOptions): TM | undefined
|
|
1263
|
-
bmToTM(bm?:
|
|
1264
|
-
bmToTM(bm?:
|
|
1271
|
+
bmToTM(bm?: BM, opt?: CommonDaoOptions): TM
|
|
1272
|
+
bmToTM(bm?: BM, opt?: CommonDaoOptions): TM | undefined {
|
|
1265
1273
|
if (bm === undefined) return
|
|
1266
1274
|
|
|
1267
1275
|
// optimization: 1 validation is enough
|
|
@@ -1276,7 +1284,7 @@ export class CommonDao<
|
|
|
1276
1284
|
return this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
|
|
1277
1285
|
}
|
|
1278
1286
|
|
|
1279
|
-
bmsToTM(bms:
|
|
1287
|
+
bmsToTM(bms: BM[], opt: CommonDaoOptions = {}): TM[] {
|
|
1280
1288
|
// try/catch?
|
|
1281
1289
|
return bms.map(bm => this.bmToTM(bm, opt))
|
|
1282
1290
|
}
|
|
@@ -1479,7 +1487,7 @@ export class CommonDaoTransaction {
|
|
|
1479
1487
|
}
|
|
1480
1488
|
}
|
|
1481
1489
|
|
|
1482
|
-
async getById<BM extends
|
|
1490
|
+
async getById<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
|
|
1483
1491
|
dao: CommonDao<BM, DBM, any>,
|
|
1484
1492
|
id?: string | null,
|
|
1485
1493
|
opt?: CommonDaoOptions,
|
|
@@ -1487,7 +1495,7 @@ export class CommonDaoTransaction {
|
|
|
1487
1495
|
return await dao.getById(id, { ...opt, tx: this.tx })
|
|
1488
1496
|
}
|
|
1489
1497
|
|
|
1490
|
-
async getByIds<BM extends
|
|
1498
|
+
async getByIds<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
|
|
1491
1499
|
dao: CommonDao<BM, DBM, any>,
|
|
1492
1500
|
ids: string[],
|
|
1493
1501
|
opt?: CommonDaoOptions,
|
|
@@ -1509,17 +1517,17 @@ export class CommonDaoTransaction {
|
|
|
1509
1517
|
// }
|
|
1510
1518
|
// }
|
|
1511
1519
|
|
|
1512
|
-
async save<BM extends
|
|
1520
|
+
async save<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
|
|
1513
1521
|
dao: CommonDao<BM, DBM, any>,
|
|
1514
|
-
bm: BM
|
|
1522
|
+
bm: UnsavedId<BM>,
|
|
1515
1523
|
opt?: CommonDaoSaveBatchOptions<DBM>,
|
|
1516
1524
|
): Promise<Saved<BM>> {
|
|
1517
1525
|
return (await this.saveBatch(dao, [bm], opt))[0]!
|
|
1518
1526
|
}
|
|
1519
1527
|
|
|
1520
|
-
async saveBatch<BM extends
|
|
1528
|
+
async saveBatch<BM extends BaseDBEntity, DBM extends BaseDBEntity>(
|
|
1521
1529
|
dao: CommonDao<BM, DBM, any>,
|
|
1522
|
-
bms: BM[],
|
|
1530
|
+
bms: UnsavedId<BM>[],
|
|
1523
1531
|
opt?: CommonDaoSaveBatchOptions<DBM>,
|
|
1524
1532
|
): Promise<Saved<BM>[]> {
|
|
1525
1533
|
return await dao.saveBatch(bms, { ...opt, tx: this.tx })
|
package/src/db.model.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
2
|
import { CommonDB } from './common.db'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -55,8 +55,7 @@ export interface CommonDBOptions {
|
|
|
55
55
|
/**
|
|
56
56
|
* All properties default to undefined.
|
|
57
57
|
*/
|
|
58
|
-
export interface CommonDBSaveOptions<ROW extends
|
|
59
|
-
extends CommonDBOptions {
|
|
58
|
+
export interface CommonDBSaveOptions<ROW extends ObjectWithId> extends CommonDBOptions {
|
|
60
59
|
excludeFromIndexes?: (keyof ROW)[]
|
|
61
60
|
|
|
62
61
|
/**
|
|
@@ -89,9 +88,9 @@ export interface RunQueryResult<T> {
|
|
|
89
88
|
endCursor?: string
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
export type DBOperation = DBSaveBatchOperation | DBDeleteByIdsOperation
|
|
91
|
+
export type DBOperation = DBSaveBatchOperation<any> | DBDeleteByIdsOperation
|
|
93
92
|
|
|
94
|
-
export interface DBSaveBatchOperation<ROW extends
|
|
93
|
+
export interface DBSaveBatchOperation<ROW extends ObjectWithId> {
|
|
95
94
|
type: 'saveBatch'
|
|
96
95
|
table: string
|
|
97
96
|
rows: ROW[]
|
|
@@ -131,6 +130,6 @@ export class DBIncrement {
|
|
|
131
130
|
}
|
|
132
131
|
}
|
|
133
132
|
|
|
134
|
-
export type DBPatch<ROW extends
|
|
133
|
+
export type DBPatch<ROW extends ObjectWithId> = Partial<
|
|
135
134
|
Record<keyof ROW, ROW[keyof ROW] | DBIncrement>
|
|
136
135
|
>
|
|
@@ -78,7 +78,7 @@ export interface DBPipelineBackupOptions extends TransformLogProgressOptions {
|
|
|
78
78
|
* But if queryPerTable is set for a table - it will override the Query that is ran for that table
|
|
79
79
|
* (and ignore sinceUpdated, sinceUpdatedPerTable, limit, and any other properties that modify the query).
|
|
80
80
|
*/
|
|
81
|
-
queryPerTable?: StringMap<DBQuery
|
|
81
|
+
queryPerTable?: StringMap<DBQuery<any>>
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Directory path to store dumped files. Will create `${tableName}.ndjson` (or .ndjson.gz if gzip=true) files.
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AsyncMapper,
|
|
3
|
+
ErrorMode,
|
|
4
|
+
pMap,
|
|
5
|
+
_passthroughMapper,
|
|
6
|
+
localTime,
|
|
7
|
+
BaseDBEntity,
|
|
8
|
+
} from '@naturalcycles/js-lib'
|
|
2
9
|
import {
|
|
3
10
|
NDJsonStats,
|
|
4
11
|
transformBuffer,
|
|
@@ -80,7 +87,7 @@ export interface DBPipelineCopyOptions extends TransformLogProgressOptions {
|
|
|
80
87
|
*/
|
|
81
88
|
transformMapOptions?: TransformMapOptions
|
|
82
89
|
|
|
83
|
-
saveOptionsPerTable?: Record<string, CommonDBSaveOptions
|
|
90
|
+
saveOptionsPerTable?: Record<string, CommonDBSaveOptions<any>>
|
|
84
91
|
}
|
|
85
92
|
|
|
86
93
|
/**
|
|
@@ -118,13 +125,13 @@ export async function dbPipelineCopy(opt: DBPipelineCopyOptions): Promise<NDJson
|
|
|
118
125
|
await pMap(
|
|
119
126
|
tables,
|
|
120
127
|
async table => {
|
|
121
|
-
let q = DBQuery.create(table).limit(limit)
|
|
128
|
+
let q = DBQuery.create<BaseDBEntity>(table).limit(limit)
|
|
122
129
|
|
|
123
130
|
if (sinceUpdated) {
|
|
124
131
|
q = q.filter('updated', '>=', sinceUpdated)
|
|
125
132
|
}
|
|
126
133
|
|
|
127
|
-
const saveOptions: CommonDBSaveOptions = saveOptionsPerTable[table] || {}
|
|
134
|
+
const saveOptions: CommonDBSaveOptions<any> = saveOptionsPerTable[table] || {}
|
|
128
135
|
const mapper = mapperPerTable[table] || _passthroughMapper
|
|
129
136
|
|
|
130
137
|
const stream = dbInput.streamQuery(q)
|
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
_hb,
|
|
8
8
|
_mapValues,
|
|
9
9
|
_passthroughMapper,
|
|
10
|
-
SavedDBEntity,
|
|
11
10
|
localTime,
|
|
12
11
|
JsonSchemaObject,
|
|
12
|
+
BaseDBEntity,
|
|
13
|
+
Saved,
|
|
13
14
|
} from '@naturalcycles/js-lib'
|
|
14
15
|
import {
|
|
15
16
|
NDJsonStats,
|
|
@@ -111,7 +112,7 @@ export interface DBPipelineRestoreOptions extends TransformLogProgressOptions {
|
|
|
111
112
|
*/
|
|
112
113
|
transformMapOptions?: TransformMapOptions
|
|
113
114
|
|
|
114
|
-
saveOptionsPerTable?: Record<string, CommonDBSaveOptions
|
|
115
|
+
saveOptionsPerTable?: Record<string, CommonDBSaveOptions<any>>
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
/**
|
|
@@ -194,7 +195,7 @@ export async function dbPipelineRestore(opt: DBPipelineRestoreOptions): Promise<
|
|
|
194
195
|
async table => {
|
|
195
196
|
const gzip = tablesToGzip.has(table)
|
|
196
197
|
const filePath = `${inputDirPath}/${table}.ndjson` + (gzip ? '.gz' : '')
|
|
197
|
-
const saveOptions: CommonDBSaveOptions = saveOptionsPerTable[table] || {}
|
|
198
|
+
const saveOptions: CommonDBSaveOptions<any> = saveOptionsPerTable[table] || {}
|
|
198
199
|
|
|
199
200
|
const started = Date.now()
|
|
200
201
|
let rows = 0
|
|
@@ -216,7 +217,7 @@ export async function dbPipelineRestore(opt: DBPipelineRestoreOptions): Promise<
|
|
|
216
217
|
}),
|
|
217
218
|
transformLimit({ limit }),
|
|
218
219
|
...(sinceUpdated
|
|
219
|
-
? [transformFilterSync<
|
|
220
|
+
? [transformFilterSync<Saved<BaseDBEntity>>(r => r.updated >= sinceUpdated)]
|
|
220
221
|
: []),
|
|
221
222
|
transformMap(mapperPerTable[table] || _passthroughMapper, {
|
|
222
223
|
errorMode,
|
package/src/query/dbQuery.ts
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
Saved,
|
|
5
5
|
AnyObject,
|
|
6
6
|
_objectAssign,
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
BaseDBEntity,
|
|
8
|
+
ObjectWithId,
|
|
9
9
|
} from '@naturalcycles/js-lib'
|
|
10
10
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
11
11
|
import {
|
|
@@ -62,13 +62,13 @@ export const dbQueryFilterOperatorValues: DBQueryFilterOperator[] = [
|
|
|
62
62
|
'array-contains-any',
|
|
63
63
|
]
|
|
64
64
|
|
|
65
|
-
export interface DBQueryFilter<ROW extends
|
|
65
|
+
export interface DBQueryFilter<ROW extends ObjectWithId> {
|
|
66
66
|
name: keyof ROW
|
|
67
67
|
op: DBQueryFilterOperator
|
|
68
68
|
val: any
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
export interface DBQueryOrder<ROW extends
|
|
71
|
+
export interface DBQueryOrder<ROW extends ObjectWithId> {
|
|
72
72
|
name: keyof ROW
|
|
73
73
|
descending?: boolean
|
|
74
74
|
}
|
|
@@ -83,19 +83,17 @@ export interface DBQueryOrder<ROW extends PartialObjectWithId = AnyPartialObject
|
|
|
83
83
|
*
|
|
84
84
|
* <DBM> is the type of **queried** object (so e.g `key of DBM` can be used), not **returned** object.
|
|
85
85
|
*/
|
|
86
|
-
export class DBQuery<ROW extends
|
|
86
|
+
export class DBQuery<ROW extends ObjectWithId> {
|
|
87
87
|
constructor(public table: string) {}
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Convenience method.
|
|
91
91
|
*/
|
|
92
|
-
static create<ROW extends
|
|
93
|
-
table: string,
|
|
94
|
-
): DBQuery<ROW> {
|
|
92
|
+
static create<ROW extends ObjectWithId>(table: string): DBQuery<ROW> {
|
|
95
93
|
return new DBQuery(table)
|
|
96
94
|
}
|
|
97
95
|
|
|
98
|
-
static fromPlainObject<ROW extends
|
|
96
|
+
static fromPlainObject<ROW extends ObjectWithId>(
|
|
99
97
|
obj: Partial<DBQuery<ROW>> & { table: string },
|
|
100
98
|
): DBQuery<ROW> {
|
|
101
99
|
return Object.assign(new DBQuery<ROW>(obj.table), obj)
|
|
@@ -239,8 +237,8 @@ export class DBQuery<ROW extends PartialObjectWithId = AnyPartialObjectWithId> {
|
|
|
239
237
|
* DBQuery that has additional method to support Fluent API style.
|
|
240
238
|
*/
|
|
241
239
|
export class RunnableDBQuery<
|
|
242
|
-
BM extends
|
|
243
|
-
DBM extends
|
|
240
|
+
BM extends BaseDBEntity,
|
|
241
|
+
DBM extends BaseDBEntity = BM,
|
|
244
242
|
TM extends AnyObject = BM,
|
|
245
243
|
> extends DBQuery<DBM> {
|
|
246
244
|
/**
|
|
@@ -78,7 +78,7 @@ export class CommonTimeSeriesDao {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
async query(q: TimeSeriesQuery): Promise<TimeSeriesDataPoint[]> {
|
|
81
|
-
const dbq = DBQuery.create(`${q.series}${_TIMESERIES_RAW}`).order('ts')
|
|
81
|
+
const dbq = DBQuery.create<any>(`${q.series}${_TIMESERIES_RAW}`).order('ts')
|
|
82
82
|
if (q.fromIncl) dbq.filter('ts', '>=', q.fromIncl)
|
|
83
83
|
if (q.toExcl) dbq.filter('ts', '<', q.toExcl)
|
|
84
84
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
2
|
import type { CommonDB } from '../common.db'
|
|
3
3
|
import { CommonDBOptions, CommonDBSaveOptions, DBTransaction } from '../db.model'
|
|
4
4
|
|
|
@@ -100,7 +100,7 @@ export class FakeDBTransaction implements DBTransaction {
|
|
|
100
100
|
// no-op
|
|
101
101
|
async rollback(): Promise<void> {}
|
|
102
102
|
|
|
103
|
-
async getByIds<ROW extends
|
|
103
|
+
async getByIds<ROW extends ObjectWithId>(
|
|
104
104
|
table: string,
|
|
105
105
|
ids: string[],
|
|
106
106
|
opt?: CommonDBOptions,
|
|
@@ -113,7 +113,7 @@ export class FakeDBTransaction implements DBTransaction {
|
|
|
113
113
|
// ): Promise<RunQueryResult<ROW>> {
|
|
114
114
|
// return await this.db.runQuery(q, opt)
|
|
115
115
|
// }
|
|
116
|
-
async saveBatch<ROW extends
|
|
116
|
+
async saveBatch<ROW extends ObjectWithId>(
|
|
117
117
|
table: string,
|
|
118
118
|
rows: ROW[],
|
|
119
119
|
opt?: CommonDBSaveOptions<ROW>,
|
package/src/validation/index.ts
CHANGED
|
@@ -21,7 +21,7 @@ export const commonDBOptionsSchema = objectSchema<CommonDBOptions>({
|
|
|
21
21
|
['skipCache' as any]: booleanSchema.optional(),
|
|
22
22
|
})
|
|
23
23
|
|
|
24
|
-
export const commonDBSaveOptionsSchema = objectSchema<CommonDBSaveOptions
|
|
24
|
+
export const commonDBSaveOptionsSchema = objectSchema<CommonDBSaveOptions<any>>({
|
|
25
25
|
excludeFromIndexes: arraySchema(stringSchema).optional(),
|
|
26
26
|
}).concat(commonDBOptionsSchema)
|
|
27
27
|
|
|
@@ -29,13 +29,13 @@ export const dbQueryFilterOperatorSchema = Joi.string<DBQueryFilterOperator>().v
|
|
|
29
29
|
...dbQueryFilterOperatorValues,
|
|
30
30
|
)
|
|
31
31
|
|
|
32
|
-
export const dbQueryFilterSchema = objectSchema<DBQueryFilter
|
|
32
|
+
export const dbQueryFilterSchema = objectSchema<DBQueryFilter<any>>({
|
|
33
33
|
name: stringSchema,
|
|
34
34
|
op: dbQueryFilterOperatorSchema,
|
|
35
35
|
val: anySchema,
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
-
export const dbQueryOrderSchema = objectSchema<DBQueryOrder
|
|
38
|
+
export const dbQueryOrderSchema = objectSchema<DBQueryOrder<any>>({
|
|
39
39
|
name: stringSchema,
|
|
40
40
|
descending: booleanSchema.optional(),
|
|
41
41
|
})
|