@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.
Files changed (43) hide show
  1. package/dist/adapter/cachedb/cache.db.d.ts +9 -9
  2. package/dist/adapter/cachedb/cache.db.js +3 -1
  3. package/dist/adapter/cachedb/cache.db.model.d.ts +5 -3
  4. package/dist/adapter/file/file.db.d.ts +2 -2
  5. package/dist/adapter/inmemory/inMemory.db.d.ts +2 -2
  6. package/dist/adapter/inmemory/inMemory.db.js +6 -3
  7. package/dist/base.common.db.d.ts +2 -2
  8. package/dist/common.db.d.ts +3 -3
  9. package/dist/commondao/common.dao.d.ts +20 -20
  10. package/dist/commondao/common.dao.js +13 -9
  11. package/dist/commondao/common.dao.model.d.ts +22 -22
  12. package/dist/db.model.d.ts +2 -17
  13. package/dist/index.d.ts +4 -5
  14. package/dist/index.js +2 -4
  15. package/dist/model.util.d.ts +2 -3
  16. package/dist/model.util.js +1 -7
  17. package/dist/pipeline/dbPipelineBackup.js +1 -2
  18. package/dist/pipeline/dbPipelineCopy.js +1 -2
  19. package/dist/pipeline/dbPipelineRestore.js +1 -2
  20. package/dist/query/dbQuery.d.ts +6 -6
  21. package/dist/validation/index.d.ts +3 -3
  22. package/package.json +1 -2
  23. package/src/adapter/cachedb/cache.db.model.ts +8 -7
  24. package/src/adapter/cachedb/cache.db.ts +20 -17
  25. package/src/adapter/file/file.db.ts +2 -2
  26. package/src/adapter/inmemory/inMemory.db.ts +9 -5
  27. package/src/base.common.db.ts +2 -2
  28. package/src/common.db.ts +7 -3
  29. package/src/commondao/common.dao.model.ts +31 -24
  30. package/src/commondao/common.dao.ts +51 -60
  31. package/src/db.model.ts +2 -18
  32. package/src/index.ts +2 -22
  33. package/src/model.util.ts +3 -9
  34. package/src/pipeline/dbPipelineBackup.ts +9 -3
  35. package/src/pipeline/dbPipelineCopy.ts +2 -3
  36. package/src/pipeline/dbPipelineRestore.ts +2 -2
  37. package/src/query/dbQuery.ts +8 -7
  38. package/dist/adapter/inmemory/index.d.ts +0 -3
  39. package/dist/adapter/inmemory/index.js +0 -8
  40. package/dist/getDB.d.ts +0 -19
  41. package/dist/getDB.js +0 -32
  42. package/src/adapter/inmemory/index.ts +0 -9
  43. 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<ROW extends ObjectWithId> extends CommonDBSaveOptions<ROW> {
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 CacheDBStreamOptions<ROW extends ObjectWithId>
61
- extends CacheDBOptions<ROW>,
62
- CommonDBStreamOptions {}
63
- export interface CacheDBCreateOptions<ROW extends ObjectWithId>
64
- extends CacheDBOptions<ROW>,
65
- CommonDBCreateOptions {}
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<ROW> = {},
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: string[],
76
- opt: CacheDBOptions<ROW> = {},
76
+ ids: ROW['id'][],
77
+ opt: CacheDBSaveOptions<ROW> = {},
77
78
  ): Promise<ROW[]> {
78
79
  const resultMap: StringMap<ROW> = {}
79
- const missingIds: string[] = []
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: string[],
122
- opt: CacheDBOptions<ROW> = {},
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.deleteByIds(table, ids, opt).then(deletedFromCache => {
136
- if (this.cfg.logCached) {
137
- this.cfg.logger?.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`)
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: CacheDBOptions<ROW> = {},
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: CacheDBOptions<ROW> = {},
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<ROW> = {},
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<ROW> = {},
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<ROW> = {},
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: string[],
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: string[],
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] = 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: string[],
146
+ ids: ROW['id'][],
147
147
  _opt?: CommonDBOptions,
148
148
  ): Promise<ROW[]> {
149
149
  const table = this.cfg.tablesPrefix + _table
150
- this.data[table] = 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] = 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(_table: string, ids: string[], _opt?: CommonDBOptions): Promise<number> {
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
 
@@ -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: string[]): Promise<number> {
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: string[]): Promise<ROW[]> {
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: string[],
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
- * @returns number of deleted items.
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(table: string, ids: string[], opt?: CommonDBOptions): Promise<number>
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
- // Hook DBM, BM, TM types should follow this exact order
14
- export type CommonDaoCreateIdHook<BM, DBM> = (obj: DBM | BM) => string
15
- export type CommonDaoParseNaturalIdHook<DBM> = (id: string) => Partial<DBM>
16
- export type CommonDaoBeforeCreateHook<BM> = (bm: Partial<BM>) => Partial<BM>
17
- export type CommonDaoBeforeDBMValidateHook<DBM> = (dbm: Partial<DBM>) => Partial<DBM>
18
- export type CommonDaoBeforeDBMToBMHook<BM, DBM> = (dbm: DBM) => Partial<BM> | Promise<Partial<BM>>
19
- export type CommonDaoBeforeBMToDBMHook<BM, DBM> = (bm: BM) => Partial<DBM> | Promise<Partial<DBM>>
20
- export type CommonDaoBeforeTMToBMHook<BM, TM> = (tm: TM) => Partial<BM>
21
- export type CommonDaoBeforeBMToTMHook<BM, TM> = (bm: BM) => Partial<TM>
22
- export type CommonDaoAnonymizeHook<DBM> = (dbm: DBM) => DBM
23
-
24
- interface CommonDaoHooks<BM, DBM, TM> {
25
- createId: CommonDaoCreateIdHook<BM, DBM>
26
- parseNaturalId: CommonDaoParseNaturalIdHook<DBM>
27
- beforeCreate: CommonDaoBeforeCreateHook<BM>
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 as any,
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?: string, opt?: CommonDaoOptions): Promise<Saved<BM> | null>
104
- async getById(id?: string, opt: CommonDaoOptions = {}): Promise<Saved<BM> | null> {
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?: string, opt?: CommonDaoOptions): Promise<DBM | null>
154
- async getByIdAsDBM(id?: string, opt: CommonDaoOptions = {}): Promise<DBM | null> {
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?: string, opt?: CommonDaoOptions): Promise<TM | null>
169
- async getByIdAsTM(id?: string, opt: CommonDaoOptions = {}): Promise<TM | null> {
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: string[], opt: CommonDaoOptions = {}): Promise<Saved<BM>[]> {
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: string[], opt: CommonDaoOptions = {}): Promise<DBM[]> {
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: string, opt: CommonDaoOptions = {}): Promise<Saved<BM>> {
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: string, opt: CommonDaoOptions = {}): Promise<DBM> {
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: string, opt: CommonDaoOptions): never {
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<string[]> {
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<string> {
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<ObjectWithId, string>(objectWithId => objectWithId.id, {
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<string, void>,
537
- opt: CommonDaoStreamForEachOptions<string> = {},
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<ObjectWithId, string>(objectWithId => objectWithId.id),
551
+ transformMapSimple<DBM, ID>(objectWithId => objectWithId.id),
549
552
  transformTap(() => count++),
550
- transformMap<string, void>(mapper, {
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 = obj.id || this.cfg.hooks!.createId!(obj)
579
+ obj.id ||= this.cfg.hooks!.createId?.(obj)
577
580
 
578
581
  if (this.cfg.created) {
579
- Object.assign(obj, {
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
- Object.assign(obj, {
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: string[]): Promise<void> {
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: string[],
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?: string, opt?: CommonDaoOptions): Promise<number>
782
- async deleteById(id?: string, opt: CommonDaoOptions = {}): Promise<number> {
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: string[], opt: CommonDaoOptions = {}): Promise<number> {
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<ObjectWithId, string>(objectWithId => objectWithId.id, {
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
- }