@naturalcycles/db-lib 8.34.2 → 8.36.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 +9 -9
- package/dist/adapter/cachedb/cache.db.js +3 -1
- package/dist/adapter/cachedb/cache.db.model.d.ts +5 -3
- package/dist/adapter/file/file.db.d.ts +2 -2
- package/dist/adapter/inmemory/inMemory.db.d.ts +2 -2
- package/dist/adapter/inmemory/inMemory.db.js +6 -3
- package/dist/base.common.db.d.ts +2 -2
- package/dist/common.db.d.ts +3 -3
- package/dist/commondao/common.dao.d.ts +20 -20
- package/dist/commondao/common.dao.js +13 -9
- package/dist/commondao/common.dao.model.d.ts +22 -22
- package/dist/db.model.d.ts +2 -17
- package/dist/index.d.ts +4 -5
- package/dist/index.js +2 -4
- package/dist/model.util.d.ts +2 -3
- package/dist/model.util.js +1 -7
- package/dist/pipeline/dbPipelineBackup.js +1 -2
- package/dist/pipeline/dbPipelineCopy.js +1 -2
- package/dist/pipeline/dbPipelineRestore.js +1 -2
- package/dist/query/dbQuery.d.ts +6 -6
- package/dist/validation/index.d.ts +3 -3
- package/package.json +1 -2
- package/src/adapter/cachedb/cache.db.model.ts +8 -7
- package/src/adapter/cachedb/cache.db.ts +20 -17
- package/src/adapter/file/file.db.ts +2 -2
- package/src/adapter/inmemory/inMemory.db.ts +9 -5
- package/src/base.common.db.ts +2 -2
- package/src/common.db.ts +7 -3
- package/src/commondao/common.dao.model.ts +31 -24
- package/src/commondao/common.dao.ts +51 -60
- package/src/db.model.ts +2 -18
- package/src/index.ts +2 -22
- package/src/model.util.ts +3 -9
- package/src/pipeline/dbPipelineBackup.ts +9 -3
- package/src/pipeline/dbPipelineCopy.ts +2 -3
- package/src/pipeline/dbPipelineRestore.ts +2 -2
- package/src/query/dbQuery.ts +8 -7
- package/dist/adapter/inmemory/index.d.ts +0 -3
- package/dist/adapter/inmemory/index.js +0 -8
- package/dist/getDB.d.ts +0 -19
- package/dist/getDB.js +0 -32
- package/src/adapter/inmemory/index.ts +0 -9
- package/src/getDB.ts +0 -50
|
@@ -45,7 +45,7 @@ export interface CacheDBCfg {
|
|
|
45
45
|
logger?: CommonLogger
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
export interface CacheDBOptions
|
|
48
|
+
export interface CacheDBOptions {
|
|
49
49
|
/**
|
|
50
50
|
* @default false
|
|
51
51
|
*/
|
|
@@ -57,9 +57,10 @@ export interface CacheDBOptions<ROW extends ObjectWithId> extends CommonDBSaveOp
|
|
|
57
57
|
onlyCache?: boolean
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export interface
|
|
61
|
-
extends CacheDBOptions
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
export interface CacheDBSaveOptions<ROW extends ObjectWithId>
|
|
61
|
+
extends CacheDBOptions,
|
|
62
|
+
CommonDBSaveOptions<ROW> {}
|
|
63
|
+
|
|
64
|
+
export interface CacheDBStreamOptions extends CacheDBOptions, CommonDBStreamOptions {}
|
|
65
|
+
|
|
66
|
+
export interface CacheDBCreateOptions extends CacheDBOptions, CommonDBCreateOptions {}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
CacheDBCfg,
|
|
14
14
|
CacheDBCreateOptions,
|
|
15
15
|
CacheDBOptions,
|
|
16
|
+
CacheDBSaveOptions,
|
|
16
17
|
CacheDBStreamOptions,
|
|
17
18
|
} from './cache.db.model'
|
|
18
19
|
|
|
@@ -59,7 +60,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
59
60
|
override async createTable<ROW extends ObjectWithId>(
|
|
60
61
|
table: string,
|
|
61
62
|
schema: JsonSchemaObject<ROW>,
|
|
62
|
-
opt: CacheDBCreateOptions
|
|
63
|
+
opt: CacheDBCreateOptions = {},
|
|
63
64
|
): Promise<void> {
|
|
64
65
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
65
66
|
await this.cfg.downstreamDB.createTable(table, schema, opt)
|
|
@@ -72,11 +73,11 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
72
73
|
|
|
73
74
|
override async getByIds<ROW extends ObjectWithId>(
|
|
74
75
|
table: string,
|
|
75
|
-
ids:
|
|
76
|
-
opt:
|
|
76
|
+
ids: ROW['id'][],
|
|
77
|
+
opt: CacheDBSaveOptions<ROW> = {},
|
|
77
78
|
): Promise<ROW[]> {
|
|
78
79
|
const resultMap: StringMap<ROW> = {}
|
|
79
|
-
const missingIds:
|
|
80
|
+
const missingIds: ROW['id'][] = []
|
|
80
81
|
|
|
81
82
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
82
83
|
const results = await this.cfg.cacheDB.getByIds<ROW>(table, ids, opt)
|
|
@@ -118,13 +119,13 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
118
119
|
|
|
119
120
|
override async deleteByIds<ROW extends ObjectWithId>(
|
|
120
121
|
table: string,
|
|
121
|
-
ids:
|
|
122
|
-
opt: CacheDBOptions
|
|
122
|
+
ids: ROW['id'][],
|
|
123
|
+
opt: CacheDBOptions = {},
|
|
123
124
|
): Promise<number> {
|
|
124
125
|
let deletedIds = 0
|
|
125
126
|
|
|
126
127
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
127
|
-
deletedIds = await this.cfg.downstreamDB.deleteByIds(table, ids, opt)
|
|
128
|
+
deletedIds = await this.cfg.downstreamDB.deleteByIds<ROW>(table, ids, opt)
|
|
128
129
|
|
|
129
130
|
if (this.cfg.logDownstream) {
|
|
130
131
|
this.cfg.logger?.log(`${table}.deleteByIds ${deletedIds} rows from downstream`)
|
|
@@ -132,11 +133,13 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
135
|
-
const cacheResult = this.cfg.cacheDB
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
const cacheResult = this.cfg.cacheDB
|
|
137
|
+
.deleteByIds<ROW>(table, ids, opt)
|
|
138
|
+
.then(deletedFromCache => {
|
|
139
|
+
if (this.cfg.logCached) {
|
|
140
|
+
this.cfg.logger?.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`)
|
|
141
|
+
}
|
|
142
|
+
})
|
|
140
143
|
if (this.cfg.awaitCache) await cacheResult
|
|
141
144
|
}
|
|
142
145
|
|
|
@@ -146,7 +149,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
146
149
|
override async saveBatch<ROW extends ObjectWithId>(
|
|
147
150
|
table: string,
|
|
148
151
|
rows: ROW[],
|
|
149
|
-
opt:
|
|
152
|
+
opt: CacheDBSaveOptions<ROW> = {},
|
|
150
153
|
): Promise<void> {
|
|
151
154
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
152
155
|
await this.cfg.downstreamDB.saveBatch(table, rows, opt)
|
|
@@ -174,7 +177,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
174
177
|
|
|
175
178
|
override async runQuery<ROW extends ObjectWithId>(
|
|
176
179
|
q: DBQuery<ROW>,
|
|
177
|
-
opt:
|
|
180
|
+
opt: CacheDBSaveOptions<ROW> = {},
|
|
178
181
|
): Promise<RunQueryResult<ROW>> {
|
|
179
182
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
180
183
|
const { rows, ...queryResult } = await this.cfg.downstreamDB.runQuery(q, opt)
|
|
@@ -204,7 +207,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
204
207
|
|
|
205
208
|
override async runQueryCount<ROW extends ObjectWithId>(
|
|
206
209
|
q: DBQuery<ROW>,
|
|
207
|
-
opt: CacheDBOptions
|
|
210
|
+
opt: CacheDBOptions = {},
|
|
208
211
|
): Promise<number> {
|
|
209
212
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
210
213
|
return await this.cfg.downstreamDB.runQueryCount(q, opt)
|
|
@@ -221,7 +224,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
221
224
|
|
|
222
225
|
override streamQuery<ROW extends ObjectWithId>(
|
|
223
226
|
q: DBQuery<ROW>,
|
|
224
|
-
opt: CacheDBStreamOptions
|
|
227
|
+
opt: CacheDBStreamOptions = {},
|
|
225
228
|
): Readable {
|
|
226
229
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
227
230
|
const stream = this.cfg.downstreamDB.streamQuery<ROW>(q, opt)
|
|
@@ -260,7 +263,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
260
263
|
|
|
261
264
|
override async deleteByQuery<ROW extends ObjectWithId>(
|
|
262
265
|
q: DBQuery<ROW>,
|
|
263
|
-
opt: CacheDBOptions
|
|
266
|
+
opt: CacheDBOptions = {},
|
|
264
267
|
): Promise<number> {
|
|
265
268
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
266
269
|
const deletedIds = await this.cfg.downstreamDB.deleteByQuery(q, opt)
|
|
@@ -64,7 +64,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
64
64
|
|
|
65
65
|
override async getByIds<ROW extends ObjectWithId>(
|
|
66
66
|
table: string,
|
|
67
|
-
ids:
|
|
67
|
+
ids: ROW['id'][],
|
|
68
68
|
_opt?: CommonDBOptions,
|
|
69
69
|
): Promise<ROW[]> {
|
|
70
70
|
const byId = _by(await this.loadFile<ROW>(table), r => r.id)
|
|
@@ -173,7 +173,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
173
173
|
|
|
174
174
|
override async deleteByIds<ROW extends ObjectWithId>(
|
|
175
175
|
table: string,
|
|
176
|
-
ids:
|
|
176
|
+
ids: ROW['id'][],
|
|
177
177
|
_opt?: CommonDBOptions,
|
|
178
178
|
): Promise<number> {
|
|
179
179
|
if (!ids.length) return 0
|
|
@@ -137,17 +137,17 @@ export class InMemoryDB implements CommonDB {
|
|
|
137
137
|
if (opt.dropIfExists) {
|
|
138
138
|
this.data[table] = {}
|
|
139
139
|
} else {
|
|
140
|
-
this.data[table]
|
|
140
|
+
this.data[table] ||= {}
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
async getByIds<ROW extends ObjectWithId>(
|
|
145
145
|
_table: string,
|
|
146
|
-
ids:
|
|
146
|
+
ids: ROW['id'][],
|
|
147
147
|
_opt?: CommonDBOptions,
|
|
148
148
|
): Promise<ROW[]> {
|
|
149
149
|
const table = this.cfg.tablesPrefix + _table
|
|
150
|
-
this.data[table]
|
|
150
|
+
this.data[table] ||= {}
|
|
151
151
|
return ids.map(id => this.data[table]![id]).filter(Boolean) as ROW[]
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -157,7 +157,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
157
157
|
_opt?: CommonDBSaveOptions<ROW>,
|
|
158
158
|
): Promise<void> {
|
|
159
159
|
const table = this.cfg.tablesPrefix + _table
|
|
160
|
-
this.data[table]
|
|
160
|
+
this.data[table] ||= {}
|
|
161
161
|
|
|
162
162
|
rows.forEach(r => {
|
|
163
163
|
if (!r.id) {
|
|
@@ -179,7 +179,11 @@ export class InMemoryDB implements CommonDB {
|
|
|
179
179
|
})
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
async deleteByIds
|
|
182
|
+
async deleteByIds<ROW extends ObjectWithId>(
|
|
183
|
+
_table: string,
|
|
184
|
+
ids: ROW['id'][],
|
|
185
|
+
_opt?: CommonDBOptions,
|
|
186
|
+
): Promise<number> {
|
|
183
187
|
const table = this.cfg.tablesPrefix + _table
|
|
184
188
|
this.data[table] = this.data[table] || {}
|
|
185
189
|
|
package/src/base.common.db.ts
CHANGED
|
@@ -35,7 +35,7 @@ export class BaseCommonDB implements CommonDB {
|
|
|
35
35
|
_schema: JsonSchemaObject<ROW>,
|
|
36
36
|
): Promise<void> {}
|
|
37
37
|
|
|
38
|
-
async deleteByIds(_table: string, _ids:
|
|
38
|
+
async deleteByIds<ROW extends ObjectWithId>(_table: string, _ids: ROW['id'][]): Promise<number> {
|
|
39
39
|
return 0
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ export class BaseCommonDB implements CommonDB {
|
|
|
43
43
|
return 0
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
async getByIds<ROW extends ObjectWithId>(_table: string, _ids:
|
|
46
|
+
async getByIds<ROW extends ObjectWithId>(_table: string, _ids: ROW['id'][]): Promise<ROW[]> {
|
|
47
47
|
return []
|
|
48
48
|
}
|
|
49
49
|
|
package/src/common.db.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface CommonDB {
|
|
|
49
49
|
*/
|
|
50
50
|
getByIds<ROW extends ObjectWithId>(
|
|
51
51
|
table: string,
|
|
52
|
-
ids:
|
|
52
|
+
ids: ROW['id'][],
|
|
53
53
|
opt?: CommonDBOptions,
|
|
54
54
|
): Promise<ROW[]>
|
|
55
55
|
|
|
@@ -78,10 +78,14 @@ export interface CommonDB {
|
|
|
78
78
|
|
|
79
79
|
// DELETE
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
81
|
+
* Returns number of deleted items.
|
|
82
82
|
* Not supported by all implementations (e.g Datastore will always return same number as number of ids).
|
|
83
83
|
*/
|
|
84
|
-
deleteByIds
|
|
84
|
+
deleteByIds<ROW extends ObjectWithId>(
|
|
85
|
+
table: string,
|
|
86
|
+
ids: ROW['id'][],
|
|
87
|
+
opt?: CommonDBOptions,
|
|
88
|
+
): Promise<number>
|
|
85
89
|
|
|
86
90
|
deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions): Promise<number>
|
|
87
91
|
|
|
@@ -10,27 +10,21 @@ import {
|
|
|
10
10
|
import { CommonDB } from '../common.db'
|
|
11
11
|
import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model'
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
beforeDBMValidate: CommonDaoBeforeDBMValidateHook<DBM>
|
|
29
|
-
beforeDBMToBM: CommonDaoBeforeDBMToBMHook<BM, DBM>
|
|
30
|
-
beforeBMToDBM: CommonDaoBeforeBMToDBMHook<BM, DBM>
|
|
31
|
-
beforeTMToBM: CommonDaoBeforeTMToBMHook<BM, TM>
|
|
32
|
-
beforeBMToTM: CommonDaoBeforeBMToTMHook<BM, TM>
|
|
33
|
-
anonymize: CommonDaoAnonymizeHook<DBM>
|
|
13
|
+
export interface CommonDaoHooks<
|
|
14
|
+
BM extends Partial<ObjectWithId<ID>>,
|
|
15
|
+
DBM extends ObjectWithId<ID>,
|
|
16
|
+
TM,
|
|
17
|
+
ID extends string | number,
|
|
18
|
+
> {
|
|
19
|
+
createId: (obj: DBM | BM) => ID
|
|
20
|
+
parseNaturalId: (id: ID) => Partial<DBM>
|
|
21
|
+
beforeCreate: (bm: Partial<BM>) => Partial<BM>
|
|
22
|
+
beforeDBMValidate: (dbm: Partial<DBM>) => Partial<DBM>
|
|
23
|
+
beforeDBMToBM: (dbm: DBM) => Partial<BM> | Promise<Partial<BM>>
|
|
24
|
+
beforeBMToDBM: (bm: BM) => Partial<DBM> | Promise<Partial<DBM>>
|
|
25
|
+
beforeTMToBM: (tm: TM) => Partial<BM>
|
|
26
|
+
beforeBMToTM: (bm: BM) => Partial<TM>
|
|
27
|
+
anonymize: (dbm: DBM) => DBM
|
|
34
28
|
|
|
35
29
|
/**
|
|
36
30
|
* If hook is defined - allows to prevent or modify the error thrown.
|
|
@@ -61,9 +55,10 @@ export enum CommonDaoLogLevel {
|
|
|
61
55
|
}
|
|
62
56
|
|
|
63
57
|
export interface CommonDaoCfg<
|
|
64
|
-
BM extends Partial<ObjectWithId
|
|
65
|
-
DBM extends ObjectWithId = Saved<BM>,
|
|
58
|
+
BM extends Partial<ObjectWithId<ID>>,
|
|
59
|
+
DBM extends ObjectWithId<ID> = Saved<BM>,
|
|
66
60
|
TM = BM,
|
|
61
|
+
ID extends string | number = DBM['id'],
|
|
67
62
|
> {
|
|
68
63
|
db: CommonDB
|
|
69
64
|
table: string
|
|
@@ -109,7 +104,19 @@ export interface CommonDaoCfg<
|
|
|
109
104
|
logStarted?: boolean
|
|
110
105
|
|
|
111
106
|
// Hooks are designed with inspiration from got/ky interface
|
|
112
|
-
hooks?: Partial<CommonDaoHooks<BM, DBM, TM>>
|
|
107
|
+
hooks?: Partial<CommonDaoHooks<BM, DBM, TM, ID>>
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Defaults to 'string'
|
|
111
|
+
*/
|
|
112
|
+
idType?: 'string' | 'number'
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Defaults to true.
|
|
116
|
+
* Set to false to disable auto-generation of `id`.
|
|
117
|
+
* Useful e.g when your DB is generating ids by itself (e.g mysql auto_increment).
|
|
118
|
+
*/
|
|
119
|
+
createId?: boolean
|
|
113
120
|
|
|
114
121
|
/**
|
|
115
122
|
* Defaults to true
|
|
@@ -59,49 +59,60 @@ const isCI = !!process.env['CI']
|
|
|
59
59
|
* TM = Transport model (optimized to be sent over the wire)
|
|
60
60
|
*/
|
|
61
61
|
export class CommonDao<
|
|
62
|
-
BM extends Partial<ObjectWithId
|
|
63
|
-
DBM extends ObjectWithId = Saved<BM>,
|
|
62
|
+
BM extends Partial<ObjectWithId<ID>>,
|
|
63
|
+
DBM extends ObjectWithId<ID> = Saved<BM>,
|
|
64
64
|
TM = BM,
|
|
65
|
+
ID extends string | number = DBM['id'],
|
|
65
66
|
> {
|
|
66
|
-
constructor(public cfg: CommonDaoCfg<BM, DBM, TM>) {
|
|
67
|
+
constructor(public cfg: CommonDaoCfg<BM, DBM, TM, ID>) {
|
|
67
68
|
this.cfg = {
|
|
68
69
|
// Default is to NOT log in AppEngine and in CI,
|
|
69
70
|
// otherwise to log Operations
|
|
70
71
|
// e.g in Dev (local machine), Test - it will log operations (useful for debugging)
|
|
71
72
|
logLevel: isGAE || isCI ? CommonDaoLogLevel.NONE : CommonDaoLogLevel.OPERATIONS,
|
|
73
|
+
idType: 'string',
|
|
74
|
+
createId: true,
|
|
72
75
|
created: true,
|
|
73
76
|
updated: true,
|
|
74
77
|
logger: console,
|
|
75
78
|
...cfg,
|
|
76
79
|
hooks: {
|
|
77
|
-
createId: () => stringId(),
|
|
78
80
|
parseNaturalId: () => ({}),
|
|
79
81
|
beforeCreate: bm => bm as BM,
|
|
80
82
|
beforeDBMValidate: dbm => dbm,
|
|
81
83
|
beforeDBMToBM: dbm => dbm as any,
|
|
82
84
|
beforeBMToDBM: bm => bm as any,
|
|
83
|
-
beforeTMToBM: tm => tm
|
|
85
|
+
beforeTMToBM: tm => tm,
|
|
84
86
|
beforeBMToTM: bm => bm as any,
|
|
85
87
|
anonymize: dbm => dbm,
|
|
86
88
|
onValidationError: err => err,
|
|
87
89
|
...cfg.hooks,
|
|
88
90
|
},
|
|
89
91
|
}
|
|
92
|
+
|
|
93
|
+
if (this.cfg.createId) {
|
|
94
|
+
_assert(
|
|
95
|
+
this.cfg.idType === 'string',
|
|
96
|
+
'db-lib: automatic generation of non-string ids is not supported',
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
this.cfg.hooks!.createId ||= () => stringId() as ID
|
|
100
|
+
} else {
|
|
101
|
+
delete this.cfg.hooks!.createId
|
|
102
|
+
}
|
|
90
103
|
}
|
|
91
104
|
|
|
92
105
|
// CREATE
|
|
93
106
|
create(part: Partial<BM> = {}, opt: CommonDaoOptions = {}): Saved<BM> {
|
|
94
107
|
let bm = this.cfg.hooks!.beforeCreate!(part) as BM
|
|
95
108
|
bm = this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
|
|
96
|
-
|
|
97
|
-
// If no SCHEMA - return as is
|
|
98
109
|
return this.assignIdCreatedUpdated(bm, opt)
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
// GET
|
|
102
113
|
async getById(id: undefined, opt?: CommonDaoOptions): Promise<null>
|
|
103
|
-
async getById(id?:
|
|
104
|
-
async getById(id?:
|
|
114
|
+
async getById(id?: ID, opt?: CommonDaoOptions): Promise<Saved<BM> | null>
|
|
115
|
+
async getById(id?: ID, opt: CommonDaoOptions = {}): Promise<Saved<BM> | null> {
|
|
105
116
|
if (!id) return null
|
|
106
117
|
const op = `getById(${id})`
|
|
107
118
|
const table = opt.table || this.cfg.table
|
|
@@ -126,22 +137,14 @@ export class CommonDao<
|
|
|
126
137
|
return bm || null
|
|
127
138
|
}
|
|
128
139
|
|
|
129
|
-
async getByIdOrEmpty(
|
|
130
|
-
id: string,
|
|
131
|
-
part: Partial<BM> = {},
|
|
132
|
-
opt?: CommonDaoOptions,
|
|
133
|
-
): Promise<Saved<BM>> {
|
|
140
|
+
async getByIdOrEmpty(id: ID, part: Partial<BM> = {}, opt?: CommonDaoOptions): Promise<Saved<BM>> {
|
|
134
141
|
const bm = await this.getById(id, opt)
|
|
135
142
|
if (bm) return bm
|
|
136
143
|
|
|
137
144
|
return this.create({ ...part, id }, opt)
|
|
138
145
|
}
|
|
139
146
|
|
|
140
|
-
async getByIdAsDBMOrEmpty(
|
|
141
|
-
id: string,
|
|
142
|
-
part: Partial<BM> = {},
|
|
143
|
-
opt?: CommonDaoOptions,
|
|
144
|
-
): Promise<DBM> {
|
|
147
|
+
async getByIdAsDBMOrEmpty(id: ID, part: Partial<BM> = {}, opt?: CommonDaoOptions): Promise<DBM> {
|
|
145
148
|
const dbm = await this.getByIdAsDBM(id, opt)
|
|
146
149
|
if (dbm) return dbm
|
|
147
150
|
|
|
@@ -150,8 +153,8 @@ export class CommonDao<
|
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
async getByIdAsDBM(id: undefined, opt?: CommonDaoOptions): Promise<null>
|
|
153
|
-
async getByIdAsDBM(id?:
|
|
154
|
-
async getByIdAsDBM(id?:
|
|
156
|
+
async getByIdAsDBM(id?: ID, opt?: CommonDaoOptions): Promise<DBM | null>
|
|
157
|
+
async getByIdAsDBM(id?: ID, opt: CommonDaoOptions = {}): Promise<DBM | null> {
|
|
155
158
|
if (!id) return null
|
|
156
159
|
const op = `getByIdAsDBM(${id})`
|
|
157
160
|
const table = opt.table || this.cfg.table
|
|
@@ -165,8 +168,8 @@ export class CommonDao<
|
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
async getByIdAsTM(id: undefined, opt?: CommonDaoOptions): Promise<null>
|
|
168
|
-
async getByIdAsTM(id?:
|
|
169
|
-
async getByIdAsTM(id?:
|
|
171
|
+
async getByIdAsTM(id?: ID, opt?: CommonDaoOptions): Promise<TM | null>
|
|
172
|
+
async getByIdAsTM(id?: ID, opt: CommonDaoOptions = {}): Promise<TM | null> {
|
|
170
173
|
if (!id) return null
|
|
171
174
|
const op = `getByIdAsTM(${id})`
|
|
172
175
|
const table = opt.table || this.cfg.table
|
|
@@ -182,7 +185,7 @@ export class CommonDao<
|
|
|
182
185
|
return tm || null
|
|
183
186
|
}
|
|
184
187
|
|
|
185
|
-
async getByIds(ids:
|
|
188
|
+
async getByIds(ids: ID[], opt: CommonDaoOptions = {}): Promise<Saved<BM>[]> {
|
|
186
189
|
const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
187
190
|
const table = opt.table || this.cfg.table
|
|
188
191
|
const started = this.logStarted(op, table)
|
|
@@ -192,7 +195,7 @@ export class CommonDao<
|
|
|
192
195
|
return bms
|
|
193
196
|
}
|
|
194
197
|
|
|
195
|
-
async getByIdsAsDBM(ids:
|
|
198
|
+
async getByIdsAsDBM(ids: ID[], opt: CommonDaoOptions = {}): Promise<DBM[]> {
|
|
196
199
|
const op = `getByIdsAsDBM ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
197
200
|
const table = opt.table || this.cfg.table
|
|
198
201
|
const started = this.logStarted(op, table)
|
|
@@ -201,7 +204,7 @@ export class CommonDao<
|
|
|
201
204
|
return dbms
|
|
202
205
|
}
|
|
203
206
|
|
|
204
|
-
async requireById(id:
|
|
207
|
+
async requireById(id: ID, opt: CommonDaoOptions = {}): Promise<Saved<BM>> {
|
|
205
208
|
const r = await this.getById(id, opt)
|
|
206
209
|
if (!r) {
|
|
207
210
|
this.throwRequiredError(id, opt)
|
|
@@ -209,7 +212,7 @@ export class CommonDao<
|
|
|
209
212
|
return r
|
|
210
213
|
}
|
|
211
214
|
|
|
212
|
-
async requireByIdAsDBM(id:
|
|
215
|
+
async requireByIdAsDBM(id: ID, opt: CommonDaoOptions = {}): Promise<DBM> {
|
|
213
216
|
const r = await this.getByIdAsDBM(id, opt)
|
|
214
217
|
if (!r) {
|
|
215
218
|
this.throwRequiredError(id, opt)
|
|
@@ -217,7 +220,7 @@ export class CommonDao<
|
|
|
217
220
|
return r
|
|
218
221
|
}
|
|
219
222
|
|
|
220
|
-
private throwRequiredError(id:
|
|
223
|
+
private throwRequiredError(id: ID, opt: CommonDaoOptions): never {
|
|
221
224
|
const table = opt.table || this.cfg.table
|
|
222
225
|
throw new AppError(`DB row required, but not found: ${table}.${id}`, {
|
|
223
226
|
code: DBLibError.DB_ROW_REQUIRED,
|
|
@@ -267,8 +270,8 @@ export class CommonDao<
|
|
|
267
270
|
/**
|
|
268
271
|
* Pass `table` to override table
|
|
269
272
|
*/
|
|
270
|
-
query(table?: string): RunnableDBQuery<BM, DBM, TM> {
|
|
271
|
-
return new RunnableDBQuery<BM, DBM, TM>(this, table)
|
|
273
|
+
query(table?: string): RunnableDBQuery<BM, DBM, TM, ID> {
|
|
274
|
+
return new RunnableDBQuery<BM, DBM, TM, ID>(this, table)
|
|
272
275
|
}
|
|
273
276
|
|
|
274
277
|
async runQuery(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<Saved<BM>[]> {
|
|
@@ -514,18 +517,18 @@ export class CommonDao<
|
|
|
514
517
|
)
|
|
515
518
|
}
|
|
516
519
|
|
|
517
|
-
async queryIds(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<
|
|
520
|
+
async queryIds(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<ID[]> {
|
|
518
521
|
q.table = opt.table || q.table
|
|
519
522
|
const { rows } = await this.cfg.db.runQuery(q.select(['id']), opt)
|
|
520
523
|
return rows.map(r => r.id)
|
|
521
524
|
}
|
|
522
525
|
|
|
523
|
-
streamQueryIds(q: DBQuery<DBM>, opt: CommonDaoStreamOptions = {}): ReadableTyped<
|
|
526
|
+
streamQueryIds(q: DBQuery<DBM>, opt: CommonDaoStreamOptions = {}): ReadableTyped<ID> {
|
|
524
527
|
q.table = opt.table || q.table
|
|
525
528
|
opt.errorMode ||= ErrorMode.SUPPRESS
|
|
526
529
|
|
|
527
530
|
return this.cfg.db.streamQuery<DBM>(q.select(['id']), opt).pipe(
|
|
528
|
-
transformMapSimple<
|
|
531
|
+
transformMapSimple<DBM, ID>(objectWithId => objectWithId.id, {
|
|
529
532
|
errorMode: ErrorMode.SUPPRESS, // cause .pipe() cannot propagate errors
|
|
530
533
|
}),
|
|
531
534
|
)
|
|
@@ -533,8 +536,8 @@ export class CommonDao<
|
|
|
533
536
|
|
|
534
537
|
async streamQueryIdsForEach(
|
|
535
538
|
q: DBQuery<DBM>,
|
|
536
|
-
mapper: AsyncMapper<
|
|
537
|
-
opt: CommonDaoStreamForEachOptions<
|
|
539
|
+
mapper: AsyncMapper<ID, void>,
|
|
540
|
+
opt: CommonDaoStreamForEachOptions<ID> = {},
|
|
538
541
|
): Promise<void> {
|
|
539
542
|
q.table = opt.table || q.table
|
|
540
543
|
opt.errorMode = opt.errorMode || ErrorMode.SUPPRESS
|
|
@@ -545,9 +548,9 @@ export class CommonDao<
|
|
|
545
548
|
|
|
546
549
|
await _pipeline([
|
|
547
550
|
this.cfg.db.streamQuery<DBM>(q.select(['id']), opt),
|
|
548
|
-
transformMapSimple<
|
|
551
|
+
transformMapSimple<DBM, ID>(objectWithId => objectWithId.id),
|
|
549
552
|
transformTap(() => count++),
|
|
550
|
-
transformMap<
|
|
553
|
+
transformMap<ID, void>(mapper, {
|
|
551
554
|
...opt,
|
|
552
555
|
predicate: _passthroughPredicate,
|
|
553
556
|
}),
|
|
@@ -573,18 +576,14 @@ export class CommonDao<
|
|
|
573
576
|
assignIdCreatedUpdated(obj: DBM | BM, opt: CommonDaoOptions = {}): DBM | Saved<BM> {
|
|
574
577
|
const now = Math.floor(Date.now() / 1000)
|
|
575
578
|
|
|
576
|
-
obj.id
|
|
579
|
+
obj.id ||= this.cfg.hooks!.createId?.(obj)
|
|
577
580
|
|
|
578
581
|
if (this.cfg.created) {
|
|
579
|
-
|
|
580
|
-
created: (obj as any).created || (obj as any).updated || now,
|
|
581
|
-
})
|
|
582
|
+
obj['created'] ||= obj['updated'] || now
|
|
582
583
|
}
|
|
583
584
|
|
|
584
585
|
if (this.cfg.updated) {
|
|
585
|
-
|
|
586
|
-
updated: opt.preserveUpdatedCreated && (obj as any).updated ? (obj as any).updated : now,
|
|
587
|
-
})
|
|
586
|
+
obj['updated'] = opt.preserveUpdatedCreated && obj['updated'] ? obj['updated'] : now
|
|
588
587
|
}
|
|
589
588
|
|
|
590
589
|
return obj as any
|
|
@@ -613,7 +612,7 @@ export class CommonDao<
|
|
|
613
612
|
return bm as any
|
|
614
613
|
}
|
|
615
614
|
|
|
616
|
-
private async ensureImmutableDontExist(table: string, ids:
|
|
615
|
+
private async ensureImmutableDontExist(table: string, ids: ID[]): Promise<void> {
|
|
617
616
|
await this.throwIfObjectExists(table, ids, [
|
|
618
617
|
DBLibError.OBJECT_IS_IMMUTABLE,
|
|
619
618
|
{
|
|
@@ -640,7 +639,7 @@ export class CommonDao<
|
|
|
640
639
|
|
|
641
640
|
private async throwIfObjectExists(
|
|
642
641
|
table: string,
|
|
643
|
-
ids:
|
|
642
|
+
ids: ID[],
|
|
644
643
|
errorMeta: [DBLibError, any],
|
|
645
644
|
): Promise<void> {
|
|
646
645
|
const existing = await this.cfg.db.getByIds<DBM>(table, ids)
|
|
@@ -656,11 +655,7 @@ export class CommonDao<
|
|
|
656
655
|
*
|
|
657
656
|
* Convenience method to replace 3 operations (loading+patching+saving) with one.
|
|
658
657
|
*/
|
|
659
|
-
async patch(
|
|
660
|
-
id: string,
|
|
661
|
-
patch: Partial<BM>,
|
|
662
|
-
opt: CommonDaoSaveOptions<DBM> = {},
|
|
663
|
-
): Promise<Saved<BM>> {
|
|
658
|
+
async patch(id: ID, patch: Partial<BM>, opt: CommonDaoSaveOptions<DBM> = {}): Promise<Saved<BM>> {
|
|
664
659
|
return await this.save(
|
|
665
660
|
{
|
|
666
661
|
...(await this.getByIdOrEmpty(id, patch, opt)),
|
|
@@ -670,11 +665,7 @@ export class CommonDao<
|
|
|
670
665
|
)
|
|
671
666
|
}
|
|
672
667
|
|
|
673
|
-
async patchAsDBM(
|
|
674
|
-
id: string,
|
|
675
|
-
patch: Partial<DBM>,
|
|
676
|
-
opt: CommonDaoSaveOptions<DBM> = {},
|
|
677
|
-
): Promise<DBM> {
|
|
668
|
+
async patchAsDBM(id: ID, patch: Partial<DBM>, opt: CommonDaoSaveOptions<DBM> = {}): Promise<DBM> {
|
|
678
669
|
const dbm =
|
|
679
670
|
(await this.getByIdAsDBM(id, opt)) ||
|
|
680
671
|
(this.create({ ...patch, id } as Partial<BM>, opt) as any as DBM)
|
|
@@ -778,8 +769,8 @@ export class CommonDao<
|
|
|
778
769
|
* @returns number of deleted items
|
|
779
770
|
*/
|
|
780
771
|
async deleteById(id: undefined, opt?: CommonDaoOptions): Promise<0>
|
|
781
|
-
async deleteById(id?:
|
|
782
|
-
async deleteById(id?:
|
|
772
|
+
async deleteById(id?: ID, opt?: CommonDaoOptions): Promise<number>
|
|
773
|
+
async deleteById(id?: ID, opt: CommonDaoOptions = {}): Promise<number> {
|
|
783
774
|
if (!id) return 0
|
|
784
775
|
this.requireWriteAccess()
|
|
785
776
|
if (!opt.allowMutability) this.requireObjectMutability()
|
|
@@ -791,7 +782,7 @@ export class CommonDao<
|
|
|
791
782
|
return ids
|
|
792
783
|
}
|
|
793
784
|
|
|
794
|
-
async deleteByIds(ids:
|
|
785
|
+
async deleteByIds(ids: ID[], opt: CommonDaoOptions = {}): Promise<number> {
|
|
795
786
|
this.requireWriteAccess()
|
|
796
787
|
if (!opt.allowMutability) this.requireObjectMutability()
|
|
797
788
|
const op = `deleteByIds(${ids.join(', ')})`
|
|
@@ -823,7 +814,7 @@ export class CommonDao<
|
|
|
823
814
|
|
|
824
815
|
await _pipeline([
|
|
825
816
|
this.cfg.db.streamQuery<DBM>(q.select(['id']), opt),
|
|
826
|
-
transformMapSimple<
|
|
817
|
+
transformMapSimple<DBM, ID>(objectWithId => objectWithId.id, {
|
|
827
818
|
errorMode: ErrorMode.SUPPRESS,
|
|
828
819
|
}),
|
|
829
820
|
transformBuffer<string>({ batchSize }),
|
package/src/db.model.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AnyObjectWithId, ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
|
-
import { CommonDB } from './common.db'
|
|
3
2
|
|
|
4
3
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
5
4
|
export interface CommonDBOptions {}
|
|
@@ -16,8 +15,9 @@ export type CommonDBStreamOptions = CommonDBOptions
|
|
|
16
15
|
|
|
17
16
|
export interface CommonDBCreateOptions extends CommonDBOptions {
|
|
18
17
|
/**
|
|
19
|
-
* @default false
|
|
20
18
|
* Caution! If set to true - will actually DROP the table!
|
|
19
|
+
*
|
|
20
|
+
* @default false
|
|
21
21
|
*/
|
|
22
22
|
dropIfExists?: boolean
|
|
23
23
|
}
|
|
@@ -51,19 +51,3 @@ export enum DBModelType {
|
|
|
51
51
|
BM = 'BM',
|
|
52
52
|
TM = 'TM',
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Interface for a module (lib) that implements CommonDB.
|
|
57
|
-
*
|
|
58
|
-
* Example:
|
|
59
|
-
*
|
|
60
|
-
* const lib: CommonDBModule = require('mysql-lib')
|
|
61
|
-
* const db = lib.getDB()
|
|
62
|
-
*/
|
|
63
|
-
export interface CommonDBAdapter {
|
|
64
|
-
/**
|
|
65
|
-
* @param cfg was read from SECRET_DB${i} by secret('SECRET_DB${i}') method and passed there.
|
|
66
|
-
* It's a string that can contain e.g JSON.stringified configuration object (depends on the adapter).
|
|
67
|
-
*/
|
|
68
|
-
getDBAdapter(cfg?: string): CommonDB
|
|
69
|
-
}
|