@naturalcycles/db-lib 8.49.1 → 8.50.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.js +2 -1
- package/dist/adapter/file/file.db.d.ts +8 -8
- package/dist/adapter/file/file.db.model.d.ts +1 -1
- package/dist/adapter/file/inMemory.persistence.plugin.d.ts +1 -1
- package/dist/adapter/file/localFile.persistence.plugin.d.ts +1 -1
- package/dist/adapter/file/noop.persistence.plugin.d.ts +1 -1
- package/dist/adapter/inmemory/inMemory.db.d.ts +8 -8
- package/dist/adapter/inmemory/queryInMemory.d.ts +1 -1
- package/dist/commondao/common.dao.d.ts +5 -16
- package/dist/commondao/common.dao.js +1 -81
- package/dist/commondao/common.dao.model.d.ts +11 -15
- package/dist/db.model.d.ts +1 -2
- package/dist/db.model.js +0 -1
- package/dist/query/dbQuery.d.ts +8 -10
- package/dist/query/dbQuery.js +0 -6
- package/dist/testing/daoTest.js +0 -1
- package/package.json +1 -1
- package/src/adapter/cachedb/cache.db.ts +2 -1
- package/src/adapter/file/file.db.model.ts +1 -1
- package/src/adapter/file/file.db.ts +12 -12
- package/src/adapter/file/inMemory.persistence.plugin.ts +1 -1
- package/src/adapter/file/localFile.persistence.plugin.ts +1 -1
- package/src/adapter/file/noop.persistence.plugin.ts +1 -1
- package/src/adapter/inmemory/inMemory.db.ts +11 -11
- package/src/adapter/inmemory/queryInMemory.ts +4 -1
- package/src/commondao/common.dao.model.ts +15 -21
- package/src/commondao/common.dao.ts +7 -113
- package/src/db.model.ts +0 -1
- package/src/query/dbQuery.ts +8 -18
- package/src/testing/daoTest.ts +0 -2
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CacheDB = void 0;
|
|
4
4
|
const node_stream_1 = require("node:stream");
|
|
5
|
+
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
6
|
const base_common_db_1 = require("../../base.common.db");
|
|
6
7
|
/**
|
|
7
8
|
* CommonDB implementation that proxies requests to downstream CommonDB
|
|
@@ -70,7 +71,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
// return in right order
|
|
73
|
-
return ids.map(id => resultMap[id]).filter(
|
|
74
|
+
return ids.map(id => resultMap[id]).filter(js_lib_1._isTruthy);
|
|
74
75
|
}
|
|
75
76
|
async saveBatch(table, rows, opt = {}) {
|
|
76
77
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
@@ -21,19 +21,19 @@ export declare class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
21
21
|
cfg: FileDBCfg;
|
|
22
22
|
ping(): Promise<void>;
|
|
23
23
|
getTables(): Promise<string[]>;
|
|
24
|
-
getByIds<ROW extends ObjectWithId
|
|
24
|
+
getByIds<ROW extends Partial<ObjectWithId>>(table: string, ids: ROW['id'][], _opt?: CommonDBOptions): Promise<ROW[]>;
|
|
25
25
|
saveBatch<ROW extends Partial<ObjectWithId>>(table: string, rows: ROW[], _opt?: CommonDBSaveOptions<ROW>): Promise<void>;
|
|
26
26
|
/**
|
|
27
27
|
* Implementation is optimized for loading/saving _whole files_.
|
|
28
28
|
*/
|
|
29
29
|
commitTransaction(tx: DBTransaction, _opt?: CommonDBOptions): Promise<void>;
|
|
30
|
-
runQuery<ROW extends ObjectWithId
|
|
31
|
-
runQueryCount<ROW extends ObjectWithId
|
|
32
|
-
streamQuery<ROW extends ObjectWithId
|
|
33
|
-
deleteByQuery<ROW extends ObjectWithId
|
|
34
|
-
getTableSchema<ROW extends ObjectWithId
|
|
35
|
-
loadFile<ROW extends ObjectWithId
|
|
36
|
-
saveFile<ROW extends ObjectWithId
|
|
30
|
+
runQuery<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<RunQueryResult<ROW>>;
|
|
31
|
+
runQueryCount<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
32
|
+
streamQuery<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, opt?: CommonDBStreamOptions): ReadableTyped<ROW>;
|
|
33
|
+
deleteByQuery<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
34
|
+
getTableSchema<ROW extends Partial<ObjectWithId>>(table: string): Promise<JsonSchemaRootObject<ROW>>;
|
|
35
|
+
loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]>;
|
|
36
|
+
saveFile<ROW extends Partial<ObjectWithId>>(table: string, _rows: ROW[]): Promise<void>;
|
|
37
37
|
saveFiles<ROW extends ObjectWithId>(ops: DBSaveBatchOperation<ROW>[]): Promise<void>;
|
|
38
38
|
private sortRows;
|
|
39
39
|
private logStarted;
|
|
@@ -4,7 +4,7 @@ import type { DBQueryOrder } from '../../query/dbQuery';
|
|
|
4
4
|
export interface FileDBPersistencePlugin {
|
|
5
5
|
ping(): Promise<void>;
|
|
6
6
|
getTables(): Promise<string[]>;
|
|
7
|
-
loadFile<ROW extends ObjectWithId
|
|
7
|
+
loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]>;
|
|
8
8
|
saveFiles(ops: DBSaveBatchOperation<any>[]): Promise<void>;
|
|
9
9
|
}
|
|
10
10
|
export interface FileDBCfg {
|
|
@@ -8,6 +8,6 @@ export declare class InMemoryPersistencePlugin implements FileDBPersistencePlugi
|
|
|
8
8
|
data: StringMap<StringMap<ObjectWithId>>;
|
|
9
9
|
ping(): Promise<void>;
|
|
10
10
|
getTables(): Promise<string[]>;
|
|
11
|
-
loadFile<ROW extends ObjectWithId
|
|
11
|
+
loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]>;
|
|
12
12
|
saveFiles(ops: DBSaveBatchOperation[]): Promise<void>;
|
|
13
13
|
}
|
|
@@ -19,7 +19,7 @@ export declare class LocalFilePersistencePlugin implements FileDBPersistencePlug
|
|
|
19
19
|
cfg: LocalFilePersistencePluginCfg;
|
|
20
20
|
ping(): Promise<void>;
|
|
21
21
|
getTables(): Promise<string[]>;
|
|
22
|
-
loadFile<ROW extends ObjectWithId
|
|
22
|
+
loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]>;
|
|
23
23
|
saveFiles(ops: DBSaveBatchOperation[]): Promise<void>;
|
|
24
24
|
saveFile<ROW extends ObjectWithId>(table: string, rows: ROW[]): Promise<void>;
|
|
25
25
|
}
|
|
@@ -4,6 +4,6 @@ import { FileDBPersistencePlugin } from './file.db.model';
|
|
|
4
4
|
export declare class NoopPersistencePlugin implements FileDBPersistencePlugin {
|
|
5
5
|
ping(): Promise<void>;
|
|
6
6
|
getTables(): Promise<string[]>;
|
|
7
|
-
loadFile<ROW extends ObjectWithId
|
|
7
|
+
loadFile<ROW extends Partial<ObjectWithId>>(_table: string): Promise<ROW[]>;
|
|
8
8
|
saveFiles(_ops: DBSaveBatchOperation[]): Promise<void>;
|
|
9
9
|
}
|
|
@@ -50,15 +50,15 @@ export declare class InMemoryDB implements CommonDB {
|
|
|
50
50
|
*/
|
|
51
51
|
resetCache(_table?: string): Promise<void>;
|
|
52
52
|
getTables(): Promise<string[]>;
|
|
53
|
-
getTableSchema<ROW extends ObjectWithId
|
|
54
|
-
createTable<ROW extends ObjectWithId
|
|
55
|
-
getByIds<ROW extends ObjectWithId
|
|
53
|
+
getTableSchema<ROW extends Partial<ObjectWithId>>(_table: string): Promise<JsonSchemaRootObject<ROW>>;
|
|
54
|
+
createTable<ROW extends Partial<ObjectWithId>>(_table: string, _schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions): Promise<void>;
|
|
55
|
+
getByIds<ROW extends Partial<ObjectWithId>>(_table: string, ids: ROW['id'][], _opt?: CommonDBOptions): Promise<ROW[]>;
|
|
56
56
|
saveBatch<ROW extends Partial<ObjectWithId>>(_table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW>): Promise<void>;
|
|
57
|
-
deleteByQuery<ROW extends ObjectWithId
|
|
58
|
-
updateByQuery<ROW extends ObjectWithId
|
|
59
|
-
runQuery<ROW extends ObjectWithId
|
|
60
|
-
runQueryCount<ROW extends ObjectWithId
|
|
61
|
-
streamQuery<ROW extends ObjectWithId
|
|
57
|
+
deleteByQuery<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
58
|
+
updateByQuery<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, patch: DBPatch<ROW>): Promise<number>;
|
|
59
|
+
runQuery<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<RunQueryResult<ROW>>;
|
|
60
|
+
runQueryCount<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
61
|
+
streamQuery<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, _opt?: CommonDBOptions): ReadableTyped<ROW>;
|
|
62
62
|
commitTransaction(tx: DBTransaction, opt?: CommonDBOptions): Promise<void>;
|
|
63
63
|
/**
|
|
64
64
|
* Flushes all tables (all namespaces) at once.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ObjectWithId } from '@naturalcycles/js-lib';
|
|
2
2
|
import { DBQuery } from '../../query/dbQuery';
|
|
3
|
-
export declare function queryInMemory<ROW extends ObjectWithId
|
|
3
|
+
export declare function queryInMemory<ROW extends Partial<ObjectWithId>>(q: DBQuery<ROW>, rows?: ROW[]): ROW[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Saved, Unsaved } 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';
|
|
@@ -8,11 +8,10 @@ import { CommonDaoCfg, CommonDaoCreateOptions, CommonDaoOptions, CommonDaoSaveOp
|
|
|
8
8
|
*
|
|
9
9
|
* DBM = Database model (how it's stored in DB)
|
|
10
10
|
* BM = Backend model (optimized for API access)
|
|
11
|
-
* TM = Transport model (optimized to be sent over the wire)
|
|
12
11
|
*/
|
|
13
|
-
export declare class CommonDao<BM extends
|
|
14
|
-
cfg: CommonDaoCfg<BM, DBM,
|
|
15
|
-
constructor(cfg: CommonDaoCfg<BM, DBM,
|
|
12
|
+
export declare class CommonDao<BM extends ObjectWithId<ID>, DBM extends ObjectWithId<ID> = BM, ID extends string | number = BM['id']> {
|
|
13
|
+
cfg: CommonDaoCfg<BM, DBM, ID>;
|
|
14
|
+
constructor(cfg: CommonDaoCfg<BM, DBM, ID>);
|
|
16
15
|
create(part?: Partial<BM>, opt?: CommonDaoOptions): Saved<BM>;
|
|
17
16
|
getById(id: undefined | null, opt?: CommonDaoOptions): Promise<null>;
|
|
18
17
|
getById(id?: ID | null, opt?: CommonDaoOptions): Promise<Saved<BM> | null>;
|
|
@@ -20,8 +19,6 @@ export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
20
19
|
getByIdAsDBMOrEmpty(id: ID, part?: Partial<BM>, opt?: CommonDaoOptions): Promise<DBM>;
|
|
21
20
|
getByIdAsDBM(id: undefined | null, opt?: CommonDaoOptions): Promise<null>;
|
|
22
21
|
getByIdAsDBM(id?: ID | null, opt?: CommonDaoOptions): Promise<DBM | null>;
|
|
23
|
-
getByIdAsTM(id: undefined | null, opt?: CommonDaoOptions): Promise<null>;
|
|
24
|
-
getByIdAsTM(id?: ID | null, opt?: CommonDaoOptions): Promise<TM | null>;
|
|
25
22
|
getByIds(ids: ID[], opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
|
|
26
23
|
getByIdsAsDBM(ids: ID[], opt?: CommonDaoOptions): Promise<DBM[]>;
|
|
27
24
|
requireById(id: ID, opt?: CommonDaoOptions): Promise<Saved<BM>>;
|
|
@@ -42,7 +39,7 @@ export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
42
39
|
/**
|
|
43
40
|
* Pass `table` to override table
|
|
44
41
|
*/
|
|
45
|
-
query(table?: string): RunnableDBQuery<BM, DBM,
|
|
42
|
+
query(table?: string): RunnableDBQuery<BM, DBM, ID>;
|
|
46
43
|
runQuery(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
|
|
47
44
|
runQuerySingleColumn<T = any>(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<T[]>;
|
|
48
45
|
/**
|
|
@@ -54,8 +51,6 @@ export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
54
51
|
runQueryExtended(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<RunQueryResult<Saved<BM>>>;
|
|
55
52
|
runQueryAsDBM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<DBM[]>;
|
|
56
53
|
runQueryExtendedAsDBM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<RunQueryResult<DBM>>;
|
|
57
|
-
runQueryAsTM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<TM[]>;
|
|
58
|
-
runQueryExtendedAsTM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<RunQueryResult<TM>>;
|
|
59
54
|
runQueryCount(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<number>;
|
|
60
55
|
streamQueryForEach(q: DBQuery<DBM>, mapper: AsyncMapper<Saved<BM>, void>, opt?: CommonDaoStreamForEachOptions<Saved<BM>>): Promise<void>;
|
|
61
56
|
streamQueryAsDBMForEach(q: DBQuery<DBM>, mapper: AsyncMapper<DBM, void>, opt?: CommonDaoStreamForEachOptions<DBM>): Promise<void>;
|
|
@@ -136,12 +131,6 @@ export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
136
131
|
anyToDBM(dbm: undefined, opt?: CommonDaoOptions): undefined;
|
|
137
132
|
anyToDBM(dbm?: any, opt?: CommonDaoOptions): DBM;
|
|
138
133
|
anyToDBMs(entities: DBM[], opt?: CommonDaoOptions): DBM[];
|
|
139
|
-
bmToTM(bm: undefined, opt?: CommonDaoOptions): TM | undefined;
|
|
140
|
-
bmToTM(bm?: Saved<BM>, opt?: CommonDaoOptions): TM;
|
|
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
134
|
/**
|
|
146
135
|
* Returns *converted value*.
|
|
147
136
|
* Validates (unless `skipValidation=true` passed).
|
|
@@ -15,7 +15,6 @@ const isCI = !!process.env['CI'];
|
|
|
15
15
|
*
|
|
16
16
|
* DBM = Database model (how it's stored in DB)
|
|
17
17
|
* BM = Backend model (optimized for API access)
|
|
18
|
-
* TM = Transport model (optimized to be sent over the wire)
|
|
19
18
|
*/
|
|
20
19
|
class CommonDao {
|
|
21
20
|
constructor(cfg) {
|
|
@@ -80,8 +79,6 @@ class CommonDao {
|
|
|
80
79
|
beforeDBMValidate: dbm => dbm,
|
|
81
80
|
beforeDBMToBM: dbm => dbm,
|
|
82
81
|
beforeBMToDBM: bm => bm,
|
|
83
|
-
beforeTMToBM: tm => tm,
|
|
84
|
-
beforeBMToTM: bm => bm,
|
|
85
82
|
anonymize: dbm => dbm,
|
|
86
83
|
onValidationError: err => err,
|
|
87
84
|
...cfg.hooks,
|
|
@@ -108,19 +105,7 @@ class CommonDao {
|
|
|
108
105
|
const op = `getById(${id})`;
|
|
109
106
|
const table = opt.table || this.cfg.table;
|
|
110
107
|
const started = this.logStarted(op, table);
|
|
111
|
-
|
|
112
|
-
if (opt.timeout) {
|
|
113
|
-
// todo: possibly remove it after debugging is done
|
|
114
|
-
dbm = await (0, js_lib_1.pTimeout)(async () => {
|
|
115
|
-
return (await this.cfg.db.getByIds(table, [id]))[0];
|
|
116
|
-
}, {
|
|
117
|
-
timeout: opt.timeout,
|
|
118
|
-
name: `getById(${table})`,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
dbm = (await this.cfg.db.getByIds(table, [id]))[0];
|
|
123
|
-
}
|
|
108
|
+
const dbm = (await this.cfg.db.getByIds(table, [id]))[0];
|
|
124
109
|
const bm = opt.raw ? dbm : await this.dbmToBM(dbm, opt);
|
|
125
110
|
this.logResult(started, op, bm, table);
|
|
126
111
|
return bm || null;
|
|
@@ -151,22 +136,6 @@ class CommonDao {
|
|
|
151
136
|
this.logResult(started, op, dbm, table);
|
|
152
137
|
return dbm || null;
|
|
153
138
|
}
|
|
154
|
-
async getByIdAsTM(id, opt = {}) {
|
|
155
|
-
if (!id)
|
|
156
|
-
return null;
|
|
157
|
-
const op = `getByIdAsTM(${id})`;
|
|
158
|
-
const table = opt.table || this.cfg.table;
|
|
159
|
-
const started = this.logStarted(op, table);
|
|
160
|
-
const [dbm] = await this.cfg.db.getByIds(table, [id]);
|
|
161
|
-
if (opt.raw) {
|
|
162
|
-
this.logResult(started, op, dbm, table);
|
|
163
|
-
return dbm || null;
|
|
164
|
-
}
|
|
165
|
-
const bm = await this.dbmToBM(dbm, opt);
|
|
166
|
-
const tm = this.bmToTM(bm, opt);
|
|
167
|
-
this.logResult(started, op, tm, table);
|
|
168
|
-
return tm || null;
|
|
169
|
-
}
|
|
170
139
|
async getByIds(ids, opt = {}) {
|
|
171
140
|
const op = `getByIds ${ids.length} id(s) (${(0, js_lib_1._truncate)(ids.slice(0, 10).join(', '), 50)})`;
|
|
172
141
|
const table = opt.table || this.cfg.table;
|
|
@@ -302,23 +271,6 @@ class CommonDao {
|
|
|
302
271
|
this.logResult(started, op, dbms, q.table);
|
|
303
272
|
return { rows: dbms, ...queryResult };
|
|
304
273
|
}
|
|
305
|
-
async runQueryAsTM(q, opt) {
|
|
306
|
-
const { rows } = await this.runQueryExtendedAsTM(q, opt);
|
|
307
|
-
return rows;
|
|
308
|
-
}
|
|
309
|
-
async runQueryExtendedAsTM(q, opt = {}) {
|
|
310
|
-
q.table = opt.table || q.table;
|
|
311
|
-
const op = `runQueryAsTM(${q.pretty()})`;
|
|
312
|
-
const started = this.logStarted(op, q.table);
|
|
313
|
-
const { rows, ...queryResult } = await this.cfg.db.runQuery(q, opt);
|
|
314
|
-
const partialQuery = !!q._selectedFieldNames;
|
|
315
|
-
const tms = partialQuery || opt.raw ? rows : this.bmsToTM(await this.dbmsToBM(rows, opt), opt);
|
|
316
|
-
this.logResult(started, op, tms, q.table);
|
|
317
|
-
return {
|
|
318
|
-
rows: tms,
|
|
319
|
-
...queryResult,
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
274
|
async runQueryCount(q, opt = {}) {
|
|
323
275
|
q.table = opt.table || q.table;
|
|
324
276
|
const op = `runQueryCount(${q.pretty()})`;
|
|
@@ -780,38 +732,6 @@ class CommonDao {
|
|
|
780
732
|
anyToDBMs(entities, opt = {}) {
|
|
781
733
|
return entities.map(entity => this.anyToDBM(entity, opt));
|
|
782
734
|
}
|
|
783
|
-
bmToTM(bm, opt) {
|
|
784
|
-
if (bm === undefined)
|
|
785
|
-
return;
|
|
786
|
-
// optimization: 1 validation is enough
|
|
787
|
-
// Validate/convert BM
|
|
788
|
-
// bm gets assigned to the new reference
|
|
789
|
-
// bm = this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
|
|
790
|
-
// BM > TM
|
|
791
|
-
const tm = this.cfg.hooks.beforeBMToTM(bm);
|
|
792
|
-
// Validate/convert DBM
|
|
793
|
-
return this.validateAndConvert(tm, this.cfg.tmSchema, db_model_1.DBModelType.TM, opt);
|
|
794
|
-
}
|
|
795
|
-
bmsToTM(bms, opt = {}) {
|
|
796
|
-
// try/catch?
|
|
797
|
-
return bms.map(bm => this.bmToTM(bm, opt));
|
|
798
|
-
}
|
|
799
|
-
tmToBM(tm, opt = {}) {
|
|
800
|
-
if (!tm)
|
|
801
|
-
return;
|
|
802
|
-
// optimization: 1 validation is enough
|
|
803
|
-
// Validate/convert TM
|
|
804
|
-
// bm gets assigned to the new reference
|
|
805
|
-
// tm = this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
|
|
806
|
-
// TM > BM
|
|
807
|
-
const bm = this.cfg.hooks.beforeTMToBM(tm);
|
|
808
|
-
// Validate/convert BM
|
|
809
|
-
return this.validateAndConvert(bm, this.cfg.bmSchema, db_model_1.DBModelType.BM, opt);
|
|
810
|
-
}
|
|
811
|
-
tmsToBM(tms, opt = {}) {
|
|
812
|
-
// try/catch?
|
|
813
|
-
return tms.map(tm => this.tmToBM(tm, opt));
|
|
814
|
-
}
|
|
815
735
|
/**
|
|
816
736
|
* Returns *converted value*.
|
|
817
737
|
* Validates (unless `skipValidation=true` passed).
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { CommonLogger, ErrorMode, ObjectWithId
|
|
1
|
+
import { CommonLogger, ErrorMode, ObjectWithId } from '@naturalcycles/js-lib';
|
|
2
2
|
import { AjvSchema, AjvValidationError, JoiValidationError, ObjectSchemaTyped, TransformLogProgressOptions, TransformMapOptions } from '@naturalcycles/nodejs-lib';
|
|
3
3
|
import { CommonDB } from '../common.db';
|
|
4
4
|
import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../db.model';
|
|
5
|
-
export interface CommonDaoHooks<BM extends Partial<ObjectWithId<ID>>, DBM extends ObjectWithId<ID
|
|
5
|
+
export interface CommonDaoHooks<BM extends Partial<ObjectWithId<ID>>, DBM extends Partial<ObjectWithId<ID>> = BM, ID extends string | number = NonNullable<BM['id']>> {
|
|
6
6
|
createRandomId(): ID;
|
|
7
7
|
/**
|
|
8
8
|
* createNaturalId hook is called (tried) first.
|
|
@@ -14,8 +14,9 @@ export interface CommonDaoHooks<BM extends Partial<ObjectWithId<ID>>, DBM extend
|
|
|
14
14
|
beforeDBMValidate(dbm: Partial<DBM>): Partial<DBM>;
|
|
15
15
|
beforeDBMToBM(dbm: DBM): Partial<BM> | Promise<Partial<BM>>;
|
|
16
16
|
beforeBMToDBM(bm: BM): Partial<DBM> | Promise<Partial<DBM>>;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Applicable to **read** operations, never to **save** operations.
|
|
19
|
+
*/
|
|
19
20
|
anonymize(dbm: DBM): DBM;
|
|
20
21
|
/**
|
|
21
22
|
* If hook is defined - allows to prevent or modify the error thrown.
|
|
@@ -43,7 +44,7 @@ export declare enum CommonDaoLogLevel {
|
|
|
43
44
|
*/
|
|
44
45
|
DATA_FULL = 30
|
|
45
46
|
}
|
|
46
|
-
export interface CommonDaoCfg<BM extends
|
|
47
|
+
export interface CommonDaoCfg<BM extends ObjectWithId<ID>, DBM extends ObjectWithId<ID> = BM, ID extends string | number = BM['id']> {
|
|
47
48
|
db: CommonDB;
|
|
48
49
|
table: string;
|
|
49
50
|
/**
|
|
@@ -51,7 +52,6 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
51
52
|
*/
|
|
52
53
|
dbmSchema?: ObjectSchemaTyped<DBM> | AjvSchema<DBM>;
|
|
53
54
|
bmSchema?: ObjectSchemaTyped<BM> | AjvSchema<BM>;
|
|
54
|
-
tmSchema?: ObjectSchemaTyped<TM> | AjvSchema<TM>;
|
|
55
55
|
excludeFromIndexes?: (keyof DBM)[];
|
|
56
56
|
/**
|
|
57
57
|
* Defaults to false.
|
|
@@ -61,6 +61,8 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
61
61
|
* `delete*` and `patch` will throw.
|
|
62
62
|
*
|
|
63
63
|
* You can still override saveMethod, or set opt.allowMutability to allow deletion.
|
|
64
|
+
*
|
|
65
|
+
* todo: consider merging it with readOnly, as it's almost the same
|
|
64
66
|
*/
|
|
65
67
|
immutable?: boolean;
|
|
66
68
|
/**
|
|
@@ -80,7 +82,7 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
80
82
|
* @default false
|
|
81
83
|
*/
|
|
82
84
|
logStarted?: boolean;
|
|
83
|
-
hooks?: Partial<CommonDaoHooks<BM, DBM,
|
|
85
|
+
hooks?: Partial<CommonDaoHooks<BM, DBM, ID>>;
|
|
84
86
|
/**
|
|
85
87
|
* Defaults to 'string'
|
|
86
88
|
*/
|
|
@@ -94,6 +96,7 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId<ID>>, DBM extends
|
|
|
94
96
|
/**
|
|
95
97
|
* See the same option in CommonDB.
|
|
96
98
|
* Defaults to false normally.
|
|
99
|
+
* "Generated" means "generated by the underlying DB" (e.g MySQL autoincrement).
|
|
97
100
|
*/
|
|
98
101
|
assignGeneratedIds?: boolean;
|
|
99
102
|
/**
|
|
@@ -165,13 +168,6 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
165
168
|
* Useful e.g in AirtableDB where you can have one Dao to control multiple tables.
|
|
166
169
|
*/
|
|
167
170
|
table?: string;
|
|
168
|
-
/**
|
|
169
|
-
* If set - wraps the method in `pTimeout` with a timeout of given number of milliseconds.
|
|
170
|
-
* Currently, it is only used to debug an ongoing GCP infra issue.
|
|
171
|
-
*
|
|
172
|
-
* @experimental
|
|
173
|
-
*/
|
|
174
|
-
timeout?: number;
|
|
175
171
|
/**
|
|
176
172
|
* If passed - operation will not be performed immediately, but instead "added" to the transaction.
|
|
177
173
|
* In the end - transaction needs to be committed (by calling `commit`).
|
|
@@ -186,7 +182,7 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
186
182
|
/**
|
|
187
183
|
* All properties default to undefined.
|
|
188
184
|
*/
|
|
189
|
-
export interface CommonDaoSaveOptions<DBM extends ObjectWithId
|
|
185
|
+
export interface CommonDaoSaveOptions<DBM extends Partial<ObjectWithId>> extends CommonDaoOptions, CommonDBSaveOptions<DBM> {
|
|
190
186
|
/**
|
|
191
187
|
* @default false
|
|
192
188
|
*
|
package/dist/db.model.d.ts
CHANGED
package/dist/db.model.js
CHANGED
package/dist/query/dbQuery.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyObjectWithId, ObjectWithId, AsyncMapper, Saved
|
|
1
|
+
import { AnyObjectWithId, ObjectWithId, AsyncMapper, Saved } from '@naturalcycles/js-lib';
|
|
2
2
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib';
|
|
3
3
|
import { CommonDaoOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions, DBPatch } from '..';
|
|
4
4
|
import { CommonDao } from '../commondao/common.dao';
|
|
@@ -24,12 +24,12 @@ import { RunQueryResult } from '../db.model';
|
|
|
24
24
|
*/
|
|
25
25
|
export type DBQueryFilterOperator = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
|
|
26
26
|
export declare const dbQueryFilterOperatorValues: DBQueryFilterOperator[];
|
|
27
|
-
export interface DBQueryFilter<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
27
|
+
export interface DBQueryFilter<ROW extends Partial<ObjectWithId> = AnyObjectWithId> {
|
|
28
28
|
name: keyof ROW;
|
|
29
29
|
op: DBQueryFilterOperator;
|
|
30
30
|
val: any;
|
|
31
31
|
}
|
|
32
|
-
export interface DBQueryOrder<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
32
|
+
export interface DBQueryOrder<ROW extends Partial<ObjectWithId> = AnyObjectWithId> {
|
|
33
33
|
name: keyof ROW;
|
|
34
34
|
descending?: boolean;
|
|
35
35
|
}
|
|
@@ -43,14 +43,14 @@ export interface DBQueryOrder<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
|
43
43
|
*
|
|
44
44
|
* <DBM> is the type of **queried** object (so e.g `key of DBM` can be used), not **returned** object.
|
|
45
45
|
*/
|
|
46
|
-
export declare class DBQuery<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
46
|
+
export declare class DBQuery<ROW extends Partial<ObjectWithId> = AnyObjectWithId> {
|
|
47
47
|
table: string;
|
|
48
48
|
constructor(table: string);
|
|
49
49
|
/**
|
|
50
50
|
* Convenience method.
|
|
51
51
|
*/
|
|
52
52
|
static create<ROW extends ObjectWithId = AnyObjectWithId>(table: string): DBQuery<ROW>;
|
|
53
|
-
static fromPlainObject<ROW extends ObjectWithId = AnyObjectWithId>(obj: Partial<DBQuery<ROW>> & {
|
|
53
|
+
static fromPlainObject<ROW extends Partial<ObjectWithId> = AnyObjectWithId>(obj: Partial<DBQuery<ROW>> & {
|
|
54
54
|
table: string;
|
|
55
55
|
}): DBQuery<ROW>;
|
|
56
56
|
_filters: DBQueryFilter<ROW>[];
|
|
@@ -84,19 +84,17 @@ export declare class DBQuery<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
|
84
84
|
/**
|
|
85
85
|
* DBQuery that has additional method to support Fluent API style.
|
|
86
86
|
*/
|
|
87
|
-
export declare class RunnableDBQuery<BM extends
|
|
88
|
-
dao: CommonDao<BM, DBM,
|
|
87
|
+
export declare class RunnableDBQuery<BM extends ObjectWithId<ID>, DBM extends ObjectWithId<ID> = BM, ID extends string | number = BM['id']> extends DBQuery<DBM> {
|
|
88
|
+
dao: CommonDao<BM, DBM, ID>;
|
|
89
89
|
/**
|
|
90
90
|
* Pass `table` to override table.
|
|
91
91
|
*/
|
|
92
|
-
constructor(dao: CommonDao<BM, DBM,
|
|
92
|
+
constructor(dao: CommonDao<BM, DBM, ID>, table?: string);
|
|
93
93
|
runQuery(opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
|
|
94
94
|
runQuerySingleColumn<T = any>(opt?: CommonDaoOptions): Promise<T[]>;
|
|
95
95
|
runQueryAsDBM(opt?: CommonDaoOptions): Promise<DBM[]>;
|
|
96
|
-
runQueryAsTM(opt?: CommonDaoOptions): Promise<TM[]>;
|
|
97
96
|
runQueryExtended(opt?: CommonDaoOptions): Promise<RunQueryResult<Saved<BM>>>;
|
|
98
97
|
runQueryExtendedAsDBM(opt?: CommonDaoOptions): Promise<RunQueryResult<DBM>>;
|
|
99
|
-
runQueryExtendedAsTM(opt?: CommonDaoOptions): Promise<RunQueryResult<TM>>;
|
|
100
98
|
runQueryCount(opt?: CommonDaoOptions): Promise<number>;
|
|
101
99
|
updateByQuery(patch: DBPatch<DBM>, opt?: CommonDaoOptions): Promise<number>;
|
|
102
100
|
streamQueryForEach(mapper: AsyncMapper<Saved<BM>, void>, opt?: CommonDaoStreamForEachOptions<Saved<BM>>): Promise<void>;
|
package/dist/query/dbQuery.js
CHANGED
|
@@ -153,18 +153,12 @@ class RunnableDBQuery extends DBQuery {
|
|
|
153
153
|
async runQueryAsDBM(opt) {
|
|
154
154
|
return await this.dao.runQueryAsDBM(this, opt);
|
|
155
155
|
}
|
|
156
|
-
async runQueryAsTM(opt) {
|
|
157
|
-
return await this.dao.runQueryAsTM(this, opt);
|
|
158
|
-
}
|
|
159
156
|
async runQueryExtended(opt) {
|
|
160
157
|
return await this.dao.runQueryExtended(this, opt);
|
|
161
158
|
}
|
|
162
159
|
async runQueryExtendedAsDBM(opt) {
|
|
163
160
|
return await this.dao.runQueryExtendedAsDBM(this, opt);
|
|
164
161
|
}
|
|
165
|
-
async runQueryExtendedAsTM(opt) {
|
|
166
|
-
return await this.dao.runQueryExtendedAsTM(this, opt);
|
|
167
|
-
}
|
|
168
162
|
async runQueryCount(opt) {
|
|
169
163
|
return await this.dao.runQueryCount(this, opt);
|
|
170
164
|
}
|
package/dist/testing/daoTest.js
CHANGED
|
@@ -13,7 +13,6 @@ function runCommonDaoTest(db, features = {}, quirks = {}) {
|
|
|
13
13
|
db,
|
|
14
14
|
dbmSchema: test_model_1.testItemDBMSchema,
|
|
15
15
|
bmSchema: test_model_1.testItemBMSchema,
|
|
16
|
-
tmSchema: test_model_1.testItemTMSchema,
|
|
17
16
|
logStarted: true,
|
|
18
17
|
logLevel: __1.CommonDaoLogLevel.DATA_FULL,
|
|
19
18
|
});
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Readable } from 'node:stream'
|
|
2
2
|
import {
|
|
3
|
+
_isTruthy,
|
|
3
4
|
JsonSchemaObject,
|
|
4
5
|
JsonSchemaRootObject,
|
|
5
6
|
ObjectWithId,
|
|
@@ -115,7 +116,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
// return in right order
|
|
118
|
-
return ids.map(id => resultMap[id]
|
|
119
|
+
return ids.map(id => resultMap[id]).filter(_isTruthy)
|
|
119
120
|
}
|
|
120
121
|
|
|
121
122
|
override async saveBatch<ROW extends Partial<ObjectWithId>>(
|
|
@@ -5,7 +5,7 @@ import type { DBQueryOrder } from '../../query/dbQuery'
|
|
|
5
5
|
export interface FileDBPersistencePlugin {
|
|
6
6
|
ping(): Promise<void>
|
|
7
7
|
getTables(): Promise<string[]>
|
|
8
|
-
loadFile<ROW extends ObjectWithId
|
|
8
|
+
loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]>
|
|
9
9
|
saveFiles(ops: DBSaveBatchOperation<any>[]): Promise<void>
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -65,13 +65,13 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
65
65
|
return tables
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
override async getByIds<ROW extends ObjectWithId
|
|
68
|
+
override async getByIds<ROW extends Partial<ObjectWithId>>(
|
|
69
69
|
table: string,
|
|
70
70
|
ids: ROW['id'][],
|
|
71
71
|
_opt?: CommonDBOptions,
|
|
72
72
|
): Promise<ROW[]> {
|
|
73
73
|
const byId = _by(await this.loadFile<ROW>(table), r => r.id)
|
|
74
|
-
return ids.map(id => byId[id]!).filter(Boolean)
|
|
74
|
+
return ids.map(id => byId[id!]!).filter(Boolean)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
override async saveBatch<ROW extends Partial<ObjectWithId>>(
|
|
@@ -115,7 +115,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
115
115
|
await pMap(
|
|
116
116
|
tables,
|
|
117
117
|
async table => {
|
|
118
|
-
const rows = await this.loadFile(table)
|
|
118
|
+
const rows: ObjectWithId[] = await this.loadFile(table)
|
|
119
119
|
data[table] = _by(rows, r => r.id)
|
|
120
120
|
},
|
|
121
121
|
{ concurrency: 16 },
|
|
@@ -168,7 +168,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
override async runQuery<ROW extends ObjectWithId
|
|
171
|
+
override async runQuery<ROW extends Partial<ObjectWithId>>(
|
|
172
172
|
q: DBQuery<ROW>,
|
|
173
173
|
_opt?: CommonDBOptions,
|
|
174
174
|
): Promise<RunQueryResult<ROW>> {
|
|
@@ -177,14 +177,14 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
override async runQueryCount<ROW extends ObjectWithId
|
|
180
|
+
override async runQueryCount<ROW extends Partial<ObjectWithId>>(
|
|
181
181
|
q: DBQuery<ROW>,
|
|
182
182
|
_opt?: CommonDBOptions,
|
|
183
183
|
): Promise<number> {
|
|
184
184
|
return (await this.loadFile(q.table)).length
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
override streamQuery<ROW extends ObjectWithId
|
|
187
|
+
override streamQuery<ROW extends Partial<ObjectWithId>>(
|
|
188
188
|
q: DBQuery<ROW>,
|
|
189
189
|
opt?: CommonDBStreamOptions,
|
|
190
190
|
): ReadableTyped<ROW> {
|
|
@@ -198,7 +198,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
198
198
|
return readable
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
override async deleteByQuery<ROW extends ObjectWithId
|
|
201
|
+
override async deleteByQuery<ROW extends Partial<ObjectWithId>>(
|
|
202
202
|
q: DBQuery<ROW>,
|
|
203
203
|
_opt?: CommonDBOptions,
|
|
204
204
|
): Promise<number> {
|
|
@@ -206,7 +206,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
206
206
|
|
|
207
207
|
let deleted = 0
|
|
208
208
|
queryInMemory(q, _stringMapValues(byId)).forEach(r => {
|
|
209
|
-
delete byId[r.id]
|
|
209
|
+
delete byId[r.id!]
|
|
210
210
|
deleted++
|
|
211
211
|
})
|
|
212
212
|
|
|
@@ -217,7 +217,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
217
217
|
return deleted
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
override async getTableSchema<ROW extends ObjectWithId
|
|
220
|
+
override async getTableSchema<ROW extends Partial<ObjectWithId>>(
|
|
221
221
|
table: string,
|
|
222
222
|
): Promise<JsonSchemaRootObject<ROW>> {
|
|
223
223
|
const rows = await this.loadFile(table)
|
|
@@ -228,7 +228,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
// wrapper, to handle logging
|
|
231
|
-
async loadFile<ROW extends ObjectWithId
|
|
231
|
+
async loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]> {
|
|
232
232
|
const started = this.logStarted(`loadFile(${table})`)
|
|
233
233
|
const rows = await this.cfg.plugin.loadFile<ROW>(table)
|
|
234
234
|
this.logFinished(started, `loadFile(${table}) ${rows.length} row(s)`)
|
|
@@ -236,7 +236,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// wrapper, to handle logging, sorting rows before saving
|
|
239
|
-
async saveFile<ROW extends ObjectWithId
|
|
239
|
+
async saveFile<ROW extends Partial<ObjectWithId>>(table: string, _rows: ROW[]): Promise<void> {
|
|
240
240
|
// if (!_rows.length) return // NO, it should be able to save file with 0 rows!
|
|
241
241
|
|
|
242
242
|
// Sort the rows, if needed
|
|
@@ -257,7 +257,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
257
257
|
this.logFinished(started, op)
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
private sortRows<ROW extends ObjectWithId
|
|
260
|
+
private sortRows<ROW extends Partial<ObjectWithId>>(rows: ROW[]): ROW[] {
|
|
261
261
|
rows = rows.map(r => _filterUndefinedValues(r))
|
|
262
262
|
|
|
263
263
|
if (this.cfg.sortOnSave) {
|
|
@@ -14,7 +14,7 @@ export class InMemoryPersistencePlugin implements FileDBPersistencePlugin {
|
|
|
14
14
|
return Object.keys(this.data)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
async loadFile<ROW extends ObjectWithId
|
|
17
|
+
async loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]> {
|
|
18
18
|
return Object.values(this.data[table] || ({} as any))
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -46,7 +46,7 @@ export class LocalFilePersistencePlugin implements FileDBPersistencePlugin {
|
|
|
46
46
|
.map(f => f.split('.ndjson')[0]!)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
async loadFile<ROW extends ObjectWithId
|
|
49
|
+
async loadFile<ROW extends Partial<ObjectWithId>>(table: string): Promise<ROW[]> {
|
|
50
50
|
await fs.ensureDir(this.cfg.storagePath)
|
|
51
51
|
const ext = `ndjson${this.cfg.gzip ? '.gz' : ''}`
|
|
52
52
|
const filePath = `${this.cfg.storagePath}/${table}.${ext}`
|
|
@@ -9,7 +9,7 @@ export class NoopPersistencePlugin implements FileDBPersistencePlugin {
|
|
|
9
9
|
return []
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
async loadFile<ROW extends ObjectWithId
|
|
12
|
+
async loadFile<ROW extends Partial<ObjectWithId>>(_table: string): Promise<ROW[]> {
|
|
13
13
|
return []
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -120,7 +120,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
120
120
|
return Object.keys(this.data).filter(t => t.startsWith(this.cfg.tablesPrefix))
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
async getTableSchema<ROW extends ObjectWithId
|
|
123
|
+
async getTableSchema<ROW extends Partial<ObjectWithId>>(
|
|
124
124
|
_table: string,
|
|
125
125
|
): Promise<JsonSchemaRootObject<ROW>> {
|
|
126
126
|
const table = this.cfg.tablesPrefix + _table
|
|
@@ -130,7 +130,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
async createTable<ROW extends ObjectWithId
|
|
133
|
+
async createTable<ROW extends Partial<ObjectWithId>>(
|
|
134
134
|
_table: string,
|
|
135
135
|
_schema: JsonSchemaObject<ROW>,
|
|
136
136
|
opt: CommonDBCreateOptions = {},
|
|
@@ -143,14 +143,14 @@ export class InMemoryDB implements CommonDB {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
async getByIds<ROW extends ObjectWithId
|
|
146
|
+
async getByIds<ROW extends Partial<ObjectWithId>>(
|
|
147
147
|
_table: string,
|
|
148
148
|
ids: ROW['id'][],
|
|
149
149
|
_opt?: CommonDBOptions,
|
|
150
150
|
): Promise<ROW[]> {
|
|
151
151
|
const table = this.cfg.tablesPrefix + _table
|
|
152
152
|
this.data[table] ||= {}
|
|
153
|
-
return ids.map(id => this.data[table]![id] as ROW).filter(Boolean)
|
|
153
|
+
return ids.map(id => this.data[table]![id!] as ROW).filter(Boolean)
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
async saveBatch<ROW extends Partial<ObjectWithId>>(
|
|
@@ -184,7 +184,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
184
184
|
})
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
async deleteByQuery<ROW extends ObjectWithId
|
|
187
|
+
async deleteByQuery<ROW extends Partial<ObjectWithId>>(
|
|
188
188
|
q: DBQuery<ROW>,
|
|
189
189
|
_opt?: CommonDBOptions,
|
|
190
190
|
): Promise<number> {
|
|
@@ -192,14 +192,14 @@ export class InMemoryDB implements CommonDB {
|
|
|
192
192
|
this.data[table] ||= {}
|
|
193
193
|
let count = 0
|
|
194
194
|
queryInMemory(q, Object.values(this.data[table] || {}) as ROW[]).forEach(r => {
|
|
195
|
-
if (!this.data[table]![r.id]) return
|
|
196
|
-
delete this.data[table]![r.id]
|
|
195
|
+
if (!this.data[table]![r.id!]) return
|
|
196
|
+
delete this.data[table]![r.id!]
|
|
197
197
|
count++
|
|
198
198
|
})
|
|
199
199
|
return count
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
async updateByQuery<ROW extends ObjectWithId
|
|
202
|
+
async updateByQuery<ROW extends Partial<ObjectWithId>>(
|
|
203
203
|
q: DBQuery<ROW>,
|
|
204
204
|
patch: DBPatch<ROW>,
|
|
205
205
|
): Promise<number> {
|
|
@@ -221,7 +221,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
221
221
|
return rows.length
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
async runQuery<ROW extends ObjectWithId
|
|
224
|
+
async runQuery<ROW extends Partial<ObjectWithId>>(
|
|
225
225
|
q: DBQuery<ROW>,
|
|
226
226
|
_opt?: CommonDBOptions,
|
|
227
227
|
): Promise<RunQueryResult<ROW>> {
|
|
@@ -229,7 +229,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
229
229
|
return { rows: queryInMemory(q, Object.values(this.data[table] || {}) as ROW[]) }
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
async runQueryCount<ROW extends ObjectWithId
|
|
232
|
+
async runQueryCount<ROW extends Partial<ObjectWithId>>(
|
|
233
233
|
q: DBQuery<ROW>,
|
|
234
234
|
_opt?: CommonDBOptions,
|
|
235
235
|
): Promise<number> {
|
|
@@ -237,7 +237,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
237
237
|
return queryInMemory<any>(q, Object.values(this.data[table] || {})).length
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
streamQuery<ROW extends ObjectWithId
|
|
240
|
+
streamQuery<ROW extends Partial<ObjectWithId>>(
|
|
241
241
|
q: DBQuery<ROW>,
|
|
242
242
|
_opt?: CommonDBOptions,
|
|
243
243
|
): ReadableTyped<ROW> {
|
|
@@ -18,7 +18,10 @@ const FILTER_FNS: Record<DBQueryFilterOperator, FilterFn> = {
|
|
|
18
18
|
|
|
19
19
|
// Important: q.table is not used in this function, so tablesPrefix is not needed.
|
|
20
20
|
// But should be careful here..
|
|
21
|
-
export function queryInMemory<ROW extends ObjectWithId
|
|
21
|
+
export function queryInMemory<ROW extends Partial<ObjectWithId>>(
|
|
22
|
+
q: DBQuery<ROW>,
|
|
23
|
+
rows: ROW[] = [],
|
|
24
|
+
): ROW[] {
|
|
22
25
|
// .filter
|
|
23
26
|
// eslint-disable-next-line unicorn/no-array-reduce
|
|
24
27
|
rows = q._filters.reduce((rows, filter) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CommonLogger, ErrorMode, ObjectWithId
|
|
1
|
+
import { CommonLogger, ErrorMode, ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
2
|
import {
|
|
3
3
|
AjvSchema,
|
|
4
4
|
AjvValidationError,
|
|
@@ -12,9 +12,8 @@ import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions } from '../
|
|
|
12
12
|
|
|
13
13
|
export interface CommonDaoHooks<
|
|
14
14
|
BM extends Partial<ObjectWithId<ID>>,
|
|
15
|
-
DBM extends ObjectWithId<ID
|
|
16
|
-
|
|
17
|
-
ID extends string | number,
|
|
15
|
+
DBM extends Partial<ObjectWithId<ID>> = BM,
|
|
16
|
+
ID extends string | number = NonNullable<BM['id']>,
|
|
18
17
|
> {
|
|
19
18
|
createRandomId(): ID
|
|
20
19
|
/**
|
|
@@ -27,8 +26,10 @@ export interface CommonDaoHooks<
|
|
|
27
26
|
beforeDBMValidate(dbm: Partial<DBM>): Partial<DBM>
|
|
28
27
|
beforeDBMToBM(dbm: DBM): Partial<BM> | Promise<Partial<BM>>
|
|
29
28
|
beforeBMToDBM(bm: BM): Partial<DBM> | Promise<Partial<DBM>>
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Applicable to **read** operations, never to **save** operations.
|
|
32
|
+
*/
|
|
32
33
|
anonymize(dbm: DBM): DBM
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -60,10 +61,9 @@ export enum CommonDaoLogLevel {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
export interface CommonDaoCfg<
|
|
63
|
-
BM extends
|
|
64
|
-
DBM extends ObjectWithId<ID> =
|
|
65
|
-
|
|
66
|
-
ID extends string | number = string,
|
|
64
|
+
BM extends ObjectWithId<ID>,
|
|
65
|
+
DBM extends ObjectWithId<ID> = BM,
|
|
66
|
+
ID extends string | number = BM['id'],
|
|
67
67
|
> {
|
|
68
68
|
db: CommonDB
|
|
69
69
|
table: string
|
|
@@ -73,7 +73,6 @@ export interface CommonDaoCfg<
|
|
|
73
73
|
*/
|
|
74
74
|
dbmSchema?: ObjectSchemaTyped<DBM> | AjvSchema<DBM>
|
|
75
75
|
bmSchema?: ObjectSchemaTyped<BM> | AjvSchema<BM>
|
|
76
|
-
tmSchema?: ObjectSchemaTyped<TM> | AjvSchema<TM>
|
|
77
76
|
|
|
78
77
|
excludeFromIndexes?: (keyof DBM)[]
|
|
79
78
|
|
|
@@ -85,6 +84,8 @@ export interface CommonDaoCfg<
|
|
|
85
84
|
* `delete*` and `patch` will throw.
|
|
86
85
|
*
|
|
87
86
|
* You can still override saveMethod, or set opt.allowMutability to allow deletion.
|
|
87
|
+
*
|
|
88
|
+
* todo: consider merging it with readOnly, as it's almost the same
|
|
88
89
|
*/
|
|
89
90
|
immutable?: boolean
|
|
90
91
|
|
|
@@ -110,7 +111,7 @@ export interface CommonDaoCfg<
|
|
|
110
111
|
logStarted?: boolean
|
|
111
112
|
|
|
112
113
|
// Hooks are designed with inspiration from got/ky interface
|
|
113
|
-
hooks?: Partial<CommonDaoHooks<BM, DBM,
|
|
114
|
+
hooks?: Partial<CommonDaoHooks<BM, DBM, ID>>
|
|
114
115
|
|
|
115
116
|
/**
|
|
116
117
|
* Defaults to 'string'
|
|
@@ -127,6 +128,7 @@ export interface CommonDaoCfg<
|
|
|
127
128
|
/**
|
|
128
129
|
* See the same option in CommonDB.
|
|
129
130
|
* Defaults to false normally.
|
|
131
|
+
* "Generated" means "generated by the underlying DB" (e.g MySQL autoincrement).
|
|
130
132
|
*/
|
|
131
133
|
assignGeneratedIds?: boolean
|
|
132
134
|
|
|
@@ -209,14 +211,6 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
209
211
|
*/
|
|
210
212
|
table?: string
|
|
211
213
|
|
|
212
|
-
/**
|
|
213
|
-
* If set - wraps the method in `pTimeout` with a timeout of given number of milliseconds.
|
|
214
|
-
* Currently, it is only used to debug an ongoing GCP infra issue.
|
|
215
|
-
*
|
|
216
|
-
* @experimental
|
|
217
|
-
*/
|
|
218
|
-
timeout?: number
|
|
219
|
-
|
|
220
214
|
/**
|
|
221
215
|
* If passed - operation will not be performed immediately, but instead "added" to the transaction.
|
|
222
216
|
* In the end - transaction needs to be committed (by calling `commit`).
|
|
@@ -232,7 +226,7 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
232
226
|
/**
|
|
233
227
|
* All properties default to undefined.
|
|
234
228
|
*/
|
|
235
|
-
export interface CommonDaoSaveOptions<DBM extends ObjectWithId
|
|
229
|
+
export interface CommonDaoSaveOptions<DBM extends Partial<ObjectWithId>>
|
|
236
230
|
extends CommonDaoOptions,
|
|
237
231
|
CommonDBSaveOptions<DBM> {
|
|
238
232
|
/**
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
_since,
|
|
7
7
|
_truncate,
|
|
8
8
|
_uniqBy,
|
|
9
|
-
AnyObject,
|
|
10
9
|
AppError,
|
|
11
10
|
AsyncMapper,
|
|
12
11
|
ErrorMode,
|
|
@@ -14,7 +13,6 @@ import {
|
|
|
14
13
|
JsonSchemaRootObject,
|
|
15
14
|
ObjectWithId,
|
|
16
15
|
pMap,
|
|
17
|
-
pTimeout,
|
|
18
16
|
Saved,
|
|
19
17
|
Unsaved,
|
|
20
18
|
} from '@naturalcycles/js-lib'
|
|
@@ -64,15 +62,13 @@ const isCI = !!process.env['CI']
|
|
|
64
62
|
*
|
|
65
63
|
* DBM = Database model (how it's stored in DB)
|
|
66
64
|
* BM = Backend model (optimized for API access)
|
|
67
|
-
* TM = Transport model (optimized to be sent over the wire)
|
|
68
65
|
*/
|
|
69
66
|
export class CommonDao<
|
|
70
|
-
BM extends
|
|
71
|
-
DBM extends ObjectWithId<ID> =
|
|
72
|
-
|
|
73
|
-
ID extends string | number = NonNullable<BM['id']>,
|
|
67
|
+
BM extends ObjectWithId<ID>,
|
|
68
|
+
DBM extends ObjectWithId<ID> = BM,
|
|
69
|
+
ID extends string | number = BM['id'],
|
|
74
70
|
> {
|
|
75
|
-
constructor(public cfg: CommonDaoCfg<BM, DBM,
|
|
71
|
+
constructor(public cfg: CommonDaoCfg<BM, DBM, ID>) {
|
|
76
72
|
this.cfg = {
|
|
77
73
|
// Default is to NOT log in AppEngine and in CI,
|
|
78
74
|
// otherwise to log Operations
|
|
@@ -91,8 +87,6 @@ export class CommonDao<
|
|
|
91
87
|
beforeDBMValidate: dbm => dbm,
|
|
92
88
|
beforeDBMToBM: dbm => dbm as any,
|
|
93
89
|
beforeBMToDBM: bm => bm as any,
|
|
94
|
-
beforeTMToBM: tm => tm as any,
|
|
95
|
-
beforeBMToTM: bm => bm as any,
|
|
96
90
|
anonymize: dbm => dbm,
|
|
97
91
|
onValidationError: err => err,
|
|
98
92
|
...cfg.hooks,
|
|
@@ -128,22 +122,7 @@ export class CommonDao<
|
|
|
128
122
|
const table = opt.table || this.cfg.table
|
|
129
123
|
const started = this.logStarted(op, table)
|
|
130
124
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (opt.timeout) {
|
|
134
|
-
// todo: possibly remove it after debugging is done
|
|
135
|
-
dbm = await pTimeout(
|
|
136
|
-
async () => {
|
|
137
|
-
return (await this.cfg.db.getByIds<DBM>(table, [id]))[0]
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
timeout: opt.timeout,
|
|
141
|
-
name: `getById(${table})`,
|
|
142
|
-
},
|
|
143
|
-
)
|
|
144
|
-
} else {
|
|
145
|
-
dbm = (await this.cfg.db.getByIds<DBM>(table, [id]))[0]
|
|
146
|
-
}
|
|
125
|
+
const dbm = (await this.cfg.db.getByIds<DBM>(table, [id]))[0]
|
|
147
126
|
|
|
148
127
|
const bm = opt.raw ? (dbm as any) : await this.dbmToBM(dbm, opt)
|
|
149
128
|
this.logResult(started, op, bm, table)
|
|
@@ -180,24 +159,6 @@ export class CommonDao<
|
|
|
180
159
|
return dbm || null
|
|
181
160
|
}
|
|
182
161
|
|
|
183
|
-
async getByIdAsTM(id: undefined | null, opt?: CommonDaoOptions): Promise<null>
|
|
184
|
-
async getByIdAsTM(id?: ID | null, opt?: CommonDaoOptions): Promise<TM | null>
|
|
185
|
-
async getByIdAsTM(id?: ID | null, opt: CommonDaoOptions = {}): Promise<TM | null> {
|
|
186
|
-
if (!id) return null
|
|
187
|
-
const op = `getByIdAsTM(${id})`
|
|
188
|
-
const table = opt.table || this.cfg.table
|
|
189
|
-
const started = this.logStarted(op, table)
|
|
190
|
-
const [dbm] = await this.cfg.db.getByIds<DBM>(table, [id])
|
|
191
|
-
if (opt.raw) {
|
|
192
|
-
this.logResult(started, op, dbm, table)
|
|
193
|
-
return (dbm as any) || null
|
|
194
|
-
}
|
|
195
|
-
const bm = await this.dbmToBM(dbm, opt)
|
|
196
|
-
const tm = this.bmToTM(bm, opt)
|
|
197
|
-
this.logResult(started, op, tm, table)
|
|
198
|
-
return tm || null
|
|
199
|
-
}
|
|
200
|
-
|
|
201
162
|
async getByIds(ids: ID[], opt: CommonDaoOptions = {}): Promise<Saved<BM>[]> {
|
|
202
163
|
const op = `getByIds ${ids.length} id(s) (${_truncate(ids.slice(0, 10).join(', '), 50)})`
|
|
203
164
|
const table = opt.table || this.cfg.table
|
|
@@ -295,8 +256,8 @@ export class CommonDao<
|
|
|
295
256
|
/**
|
|
296
257
|
* Pass `table` to override table
|
|
297
258
|
*/
|
|
298
|
-
query(table?: string): RunnableDBQuery<BM, DBM,
|
|
299
|
-
return new RunnableDBQuery<BM, DBM,
|
|
259
|
+
query(table?: string): RunnableDBQuery<BM, DBM, ID> {
|
|
260
|
+
return new RunnableDBQuery<BM, DBM, ID>(this, table)
|
|
300
261
|
}
|
|
301
262
|
|
|
302
263
|
async runQuery(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<Saved<BM>[]> {
|
|
@@ -364,29 +325,6 @@ export class CommonDao<
|
|
|
364
325
|
return { rows: dbms, ...queryResult }
|
|
365
326
|
}
|
|
366
327
|
|
|
367
|
-
async runQueryAsTM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<TM[]> {
|
|
368
|
-
const { rows } = await this.runQueryExtendedAsTM(q, opt)
|
|
369
|
-
return rows
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
async runQueryExtendedAsTM(
|
|
373
|
-
q: DBQuery<DBM>,
|
|
374
|
-
opt: CommonDaoOptions = {},
|
|
375
|
-
): Promise<RunQueryResult<TM>> {
|
|
376
|
-
q.table = opt.table || q.table
|
|
377
|
-
const op = `runQueryAsTM(${q.pretty()})`
|
|
378
|
-
const started = this.logStarted(op, q.table)
|
|
379
|
-
const { rows, ...queryResult } = await this.cfg.db.runQuery<DBM>(q, opt)
|
|
380
|
-
const partialQuery = !!q._selectedFieldNames
|
|
381
|
-
const tms =
|
|
382
|
-
partialQuery || opt.raw ? (rows as any[]) : this.bmsToTM(await this.dbmsToBM(rows, opt), opt)
|
|
383
|
-
this.logResult(started, op, tms, q.table)
|
|
384
|
-
return {
|
|
385
|
-
rows: tms,
|
|
386
|
-
...queryResult,
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
328
|
async runQueryCount(q: DBQuery<DBM>, opt: CommonDaoOptions = {}): Promise<number> {
|
|
391
329
|
q.table = opt.table || q.table
|
|
392
330
|
const op = `runQueryCount(${q.pretty()})`
|
|
@@ -1041,50 +979,6 @@ export class CommonDao<
|
|
|
1041
979
|
return entities.map(entity => this.anyToDBM(entity, opt))
|
|
1042
980
|
}
|
|
1043
981
|
|
|
1044
|
-
bmToTM(bm: undefined, opt?: CommonDaoOptions): TM | undefined
|
|
1045
|
-
bmToTM(bm?: Saved<BM>, opt?: CommonDaoOptions): TM
|
|
1046
|
-
bmToTM(bm?: Saved<BM>, opt?: CommonDaoOptions): TM | undefined {
|
|
1047
|
-
if (bm === undefined) return
|
|
1048
|
-
|
|
1049
|
-
// optimization: 1 validation is enough
|
|
1050
|
-
// Validate/convert BM
|
|
1051
|
-
// bm gets assigned to the new reference
|
|
1052
|
-
// bm = this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
|
|
1053
|
-
|
|
1054
|
-
// BM > TM
|
|
1055
|
-
const tm = this.cfg.hooks!.beforeBMToTM!(bm as any)
|
|
1056
|
-
|
|
1057
|
-
// Validate/convert DBM
|
|
1058
|
-
return this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
bmsToTM(bms: Saved<BM>[], opt: CommonDaoOptions = {}): TM[] {
|
|
1062
|
-
// try/catch?
|
|
1063
|
-
return bms.map(bm => this.bmToTM(bm, opt))
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
tmToBM(tm: undefined, opt?: CommonDaoOptions): undefined
|
|
1067
|
-
tmToBM(tm?: TM, opt?: CommonDaoOptions): BM
|
|
1068
|
-
tmToBM(tm?: TM, opt: CommonDaoOptions = {}): BM | undefined {
|
|
1069
|
-
if (!tm) return
|
|
1070
|
-
|
|
1071
|
-
// optimization: 1 validation is enough
|
|
1072
|
-
// Validate/convert TM
|
|
1073
|
-
// bm gets assigned to the new reference
|
|
1074
|
-
// tm = this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
|
|
1075
|
-
|
|
1076
|
-
// TM > BM
|
|
1077
|
-
const bm = this.cfg.hooks!.beforeTMToBM!(tm) as BM
|
|
1078
|
-
|
|
1079
|
-
// Validate/convert BM
|
|
1080
|
-
return this.validateAndConvert<BM>(bm, this.cfg.bmSchema, DBModelType.BM, opt)
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
tmsToBM(tms: TM[], opt: CommonDaoOptions = {}): BM[] {
|
|
1084
|
-
// try/catch?
|
|
1085
|
-
return tms.map(tm => this.tmToBM(tm, opt))
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
982
|
/**
|
|
1089
983
|
* Returns *converted value*.
|
|
1090
984
|
* Validates (unless `skipValidation=true` passed).
|
package/src/db.model.ts
CHANGED
package/src/query/dbQuery.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
AsyncMapper,
|
|
5
5
|
_truncate,
|
|
6
6
|
Saved,
|
|
7
|
-
AnyObject,
|
|
8
7
|
_objectAssign,
|
|
9
8
|
} from '@naturalcycles/js-lib'
|
|
10
9
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
@@ -61,13 +60,13 @@ export const dbQueryFilterOperatorValues: DBQueryFilterOperator[] = [
|
|
|
61
60
|
'array-contains-any',
|
|
62
61
|
]
|
|
63
62
|
|
|
64
|
-
export interface DBQueryFilter<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
63
|
+
export interface DBQueryFilter<ROW extends Partial<ObjectWithId> = AnyObjectWithId> {
|
|
65
64
|
name: keyof ROW
|
|
66
65
|
op: DBQueryFilterOperator
|
|
67
66
|
val: any
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
export interface DBQueryOrder<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
69
|
+
export interface DBQueryOrder<ROW extends Partial<ObjectWithId> = AnyObjectWithId> {
|
|
71
70
|
name: keyof ROW
|
|
72
71
|
descending?: boolean
|
|
73
72
|
}
|
|
@@ -82,7 +81,7 @@ export interface DBQueryOrder<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
|
82
81
|
*
|
|
83
82
|
* <DBM> is the type of **queried** object (so e.g `key of DBM` can be used), not **returned** object.
|
|
84
83
|
*/
|
|
85
|
-
export class DBQuery<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
84
|
+
export class DBQuery<ROW extends Partial<ObjectWithId> = AnyObjectWithId> {
|
|
86
85
|
constructor(public table: string) {}
|
|
87
86
|
|
|
88
87
|
/**
|
|
@@ -92,7 +91,7 @@ export class DBQuery<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
|
92
91
|
return new DBQuery(table)
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
static fromPlainObject<ROW extends ObjectWithId = AnyObjectWithId>(
|
|
94
|
+
static fromPlainObject<ROW extends Partial<ObjectWithId> = AnyObjectWithId>(
|
|
96
95
|
obj: Partial<DBQuery<ROW>> & { table: string },
|
|
97
96
|
): DBQuery<ROW> {
|
|
98
97
|
return Object.assign(new DBQuery<ROW>(obj.table), obj)
|
|
@@ -236,15 +235,14 @@ export class DBQuery<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
|
236
235
|
* DBQuery that has additional method to support Fluent API style.
|
|
237
236
|
*/
|
|
238
237
|
export class RunnableDBQuery<
|
|
239
|
-
BM extends
|
|
240
|
-
DBM extends ObjectWithId<ID> =
|
|
241
|
-
|
|
242
|
-
ID extends string | number = string,
|
|
238
|
+
BM extends ObjectWithId<ID>,
|
|
239
|
+
DBM extends ObjectWithId<ID> = BM,
|
|
240
|
+
ID extends string | number = BM['id'],
|
|
243
241
|
> extends DBQuery<DBM> {
|
|
244
242
|
/**
|
|
245
243
|
* Pass `table` to override table.
|
|
246
244
|
*/
|
|
247
|
-
constructor(public dao: CommonDao<BM, DBM,
|
|
245
|
+
constructor(public dao: CommonDao<BM, DBM, ID>, table?: string) {
|
|
248
246
|
super(table || dao.cfg.table)
|
|
249
247
|
}
|
|
250
248
|
|
|
@@ -260,10 +258,6 @@ export class RunnableDBQuery<
|
|
|
260
258
|
return await this.dao.runQueryAsDBM(this, opt)
|
|
261
259
|
}
|
|
262
260
|
|
|
263
|
-
async runQueryAsTM(opt?: CommonDaoOptions): Promise<TM[]> {
|
|
264
|
-
return await this.dao.runQueryAsTM(this, opt)
|
|
265
|
-
}
|
|
266
|
-
|
|
267
261
|
async runQueryExtended(opt?: CommonDaoOptions): Promise<RunQueryResult<Saved<BM>>> {
|
|
268
262
|
return await this.dao.runQueryExtended(this, opt)
|
|
269
263
|
}
|
|
@@ -272,10 +266,6 @@ export class RunnableDBQuery<
|
|
|
272
266
|
return await this.dao.runQueryExtendedAsDBM(this, opt)
|
|
273
267
|
}
|
|
274
268
|
|
|
275
|
-
async runQueryExtendedAsTM(opt?: CommonDaoOptions): Promise<RunQueryResult<TM>> {
|
|
276
|
-
return await this.dao.runQueryExtendedAsTM(this, opt)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
269
|
async runQueryCount(opt?: CommonDaoOptions): Promise<number> {
|
|
280
270
|
return await this.dao.runQueryCount(this, opt)
|
|
281
271
|
}
|
package/src/testing/daoTest.ts
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
createTestItemsBM,
|
|
9
9
|
testItemBMSchema,
|
|
10
10
|
testItemDBMSchema,
|
|
11
|
-
testItemTMSchema,
|
|
12
11
|
TEST_TABLE,
|
|
13
12
|
createTestItemBM,
|
|
14
13
|
testItemDBMJsonSchema,
|
|
@@ -25,7 +24,6 @@ export function runCommonDaoTest(
|
|
|
25
24
|
db,
|
|
26
25
|
dbmSchema: testItemDBMSchema,
|
|
27
26
|
bmSchema: testItemBMSchema,
|
|
28
|
-
tmSchema: testItemTMSchema,
|
|
29
27
|
logStarted: true,
|
|
30
28
|
logLevel: CommonDaoLogLevel.DATA_FULL,
|
|
31
29
|
})
|