@naturalcycles/db-lib 8.50.2 → 8.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/file/file.db.d.ts +8 -8
- package/dist/adapter/file/file.db.model.d.ts +4 -4
- 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/common.db.d.ts +12 -12
- package/dist/commondao/common.dao.d.ts +17 -6
- package/dist/commondao/common.dao.js +75 -1
- package/dist/commondao/common.dao.model.d.ts +20 -23
- package/dist/db.model.d.ts +2 -1
- package/dist/db.model.js +1 -0
- package/dist/kv/commonKeyValueDB.d.ts +9 -9
- package/dist/kv/commonKeyValueDao.d.ts +3 -3
- package/dist/query/dbQuery.d.ts +10 -8
- package/dist/query/dbQuery.js +6 -0
- package/dist/testing/daoTest.js +1 -0
- package/package.json +1 -1
- package/src/adapter/file/file.db.model.ts +4 -4
- 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 +1 -4
- package/src/common.db.ts +24 -18
- package/src/commondao/common.dao.model.ts +32 -27
- package/src/commondao/common.dao.ts +108 -10
- package/src/db.model.ts +1 -0
- package/src/kv/commonKeyValueDB.ts +9 -9
- package/src/kv/commonKeyValueDao.ts +3 -3
- package/src/query/dbQuery.ts +18 -8
- package/src/testing/daoTest.ts +2 -0
|
@@ -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
|
|
24
|
+
getByIds<ROW extends 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
|
|
31
|
-
runQueryCount<ROW extends
|
|
32
|
-
streamQuery<ROW extends
|
|
33
|
-
deleteByQuery<ROW extends
|
|
34
|
-
getTableSchema<ROW extends
|
|
35
|
-
loadFile<ROW extends
|
|
36
|
-
saveFile<ROW extends
|
|
30
|
+
runQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<RunQueryResult<ROW>>;
|
|
31
|
+
runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
32
|
+
streamQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBStreamOptions): ReadableTyped<ROW>;
|
|
33
|
+
deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
34
|
+
getTableSchema<ROW extends ObjectWithId>(table: string): Promise<JsonSchemaRootObject<ROW>>;
|
|
35
|
+
loadFile<ROW extends ObjectWithId>(table: string): Promise<ROW[]>;
|
|
36
|
+
saveFile<ROW extends 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;
|
|
@@ -2,10 +2,10 @@ import { CommonLogger, ObjectWithId } from '@naturalcycles/js-lib';
|
|
|
2
2
|
import { DBSaveBatchOperation } from '../../db.model';
|
|
3
3
|
import type { DBQueryOrder } from '../../query/dbQuery';
|
|
4
4
|
export interface FileDBPersistencePlugin {
|
|
5
|
-
ping()
|
|
6
|
-
getTables()
|
|
7
|
-
loadFile<ROW extends
|
|
8
|
-
saveFiles(ops: DBSaveBatchOperation<any>[])
|
|
5
|
+
ping: () => Promise<void>;
|
|
6
|
+
getTables: () => Promise<string[]>;
|
|
7
|
+
loadFile: <ROW extends ObjectWithId>(table: string) => Promise<ROW[]>;
|
|
8
|
+
saveFiles: (ops: DBSaveBatchOperation<any>[]) => Promise<void>;
|
|
9
9
|
}
|
|
10
10
|
export interface FileDBCfg {
|
|
11
11
|
plugin: FileDBPersistencePlugin;
|
|
@@ -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
|
|
11
|
+
loadFile<ROW extends 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
|
|
22
|
+
loadFile<ROW extends 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
|
|
7
|
+
loadFile<ROW extends 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
|
|
54
|
-
createTable<ROW extends
|
|
55
|
-
getByIds<ROW extends
|
|
53
|
+
getTableSchema<ROW extends ObjectWithId>(_table: string): Promise<JsonSchemaRootObject<ROW>>;
|
|
54
|
+
createTable<ROW extends ObjectWithId>(_table: string, _schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions): Promise<void>;
|
|
55
|
+
getByIds<ROW extends 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
|
|
58
|
-
updateByQuery<ROW extends
|
|
59
|
-
runQuery<ROW extends
|
|
60
|
-
runQueryCount<ROW extends
|
|
61
|
-
streamQuery<ROW extends
|
|
57
|
+
deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
58
|
+
updateByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: DBPatch<ROW>): Promise<number>;
|
|
59
|
+
runQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<RunQueryResult<ROW>>;
|
|
60
|
+
runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>, _opt?: CommonDBOptions): Promise<number>;
|
|
61
|
+
streamQuery<ROW extends 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
|
|
3
|
+
export declare function queryInMemory<ROW extends ObjectWithId>(q: DBQuery<ROW>, rows?: ROW[]): ROW[];
|
package/dist/common.db.d.ts
CHANGED
|
@@ -10,43 +10,43 @@ export interface CommonDB {
|
|
|
10
10
|
* It SHOULD fail if DB setup is wrong (e.g on wrong credentials).
|
|
11
11
|
* It SHOULD succeed if e.g getByIds(['nonExistingKey']) doesn't throw.
|
|
12
12
|
*/
|
|
13
|
-
ping()
|
|
13
|
+
ping: () => Promise<void>;
|
|
14
14
|
/**
|
|
15
15
|
* Return all tables (table names) available in this DB.
|
|
16
16
|
*/
|
|
17
|
-
getTables()
|
|
17
|
+
getTables: () => Promise<string[]>;
|
|
18
18
|
/**
|
|
19
19
|
* $id of the schema SHOULD be like this:
|
|
20
20
|
* `${tableName}.schema.json`
|
|
21
21
|
*
|
|
22
22
|
* This is important for the code to rely on it, and it's verified by dbTest
|
|
23
23
|
*/
|
|
24
|
-
getTableSchema<ROW extends ObjectWithId>(table: string)
|
|
24
|
+
getTableSchema: <ROW extends ObjectWithId>(table: string) => Promise<JsonSchemaRootObject<ROW>>;
|
|
25
25
|
/**
|
|
26
26
|
* Will do like `create table ...` for mysql.
|
|
27
27
|
* Caution! dropIfExists defaults to false. If set to true - will actually DROP the table!
|
|
28
28
|
*/
|
|
29
|
-
createTable<ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions)
|
|
29
|
+
createTable: <ROW extends ObjectWithId>(table: string, schema: JsonSchemaObject<ROW>, opt?: CommonDBCreateOptions) => Promise<void>;
|
|
30
30
|
/**
|
|
31
31
|
* Order of items returned is not guaranteed to match order of ids.
|
|
32
32
|
* (Such limitation exists because Datastore doesn't support it).
|
|
33
33
|
*/
|
|
34
|
-
getByIds<ROW extends ObjectWithId>(table: string, ids: ROW['id'][], opt?: CommonDBOptions)
|
|
34
|
+
getByIds: <ROW extends ObjectWithId>(table: string, ids: ROW['id'][], opt?: CommonDBOptions) => Promise<ROW[]>;
|
|
35
35
|
/**
|
|
36
36
|
* Order by 'id' is not supported by all implementations (for example, Datastore doesn't support it).
|
|
37
37
|
*/
|
|
38
|
-
runQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions)
|
|
39
|
-
runQueryCount<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions)
|
|
40
|
-
streamQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBStreamOptions)
|
|
38
|
+
runQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions) => Promise<RunQueryResult<ROW>>;
|
|
39
|
+
runQueryCount: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions) => Promise<number>;
|
|
40
|
+
streamQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBStreamOptions) => ReadableTyped<ROW>;
|
|
41
41
|
/**
|
|
42
42
|
* rows can have missing ids only if DB supports auto-generating them (like mysql auto_increment).
|
|
43
43
|
*/
|
|
44
|
-
saveBatch<ROW extends Partial<ObjectWithId>>(table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW>)
|
|
44
|
+
saveBatch: <ROW extends Partial<ObjectWithId>>(table: string, rows: ROW[], opt?: CommonDBSaveOptions<ROW>) => Promise<void>;
|
|
45
45
|
/**
|
|
46
46
|
* Returns number of deleted items.
|
|
47
47
|
* Not supported by all implementations (e.g Datastore will always return same number as number of ids).
|
|
48
48
|
*/
|
|
49
|
-
deleteByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions)
|
|
49
|
+
deleteByQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, opt?: CommonDBOptions) => Promise<number>;
|
|
50
50
|
/**
|
|
51
51
|
* Applies patch to the rows returned by the query.
|
|
52
52
|
*
|
|
@@ -65,10 +65,10 @@ export interface CommonDB {
|
|
|
65
65
|
*
|
|
66
66
|
* Returns number of rows affected.
|
|
67
67
|
*/
|
|
68
|
-
updateByQuery<ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: DBPatch<ROW>, opt?: CommonDBOptions)
|
|
68
|
+
updateByQuery: <ROW extends ObjectWithId>(q: DBQuery<ROW>, patch: DBPatch<ROW>, opt?: CommonDBOptions) => Promise<number>;
|
|
69
69
|
/**
|
|
70
70
|
* Should be implemented as a Transaction (best effort), which means that
|
|
71
71
|
* either ALL or NONE of the operations should be applied.
|
|
72
72
|
*/
|
|
73
|
-
commitTransaction(tx: DBTransaction, opt?: CommonDBOptions)
|
|
73
|
+
commitTransaction: (tx: DBTransaction, opt?: CommonDBOptions) => Promise<void>;
|
|
74
74
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Saved, Unsaved } from '@naturalcycles/js-lib';
|
|
1
|
+
import { AnyObject, AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Saved, Unsaved, ZodSchema } from '@naturalcycles/js-lib';
|
|
2
2
|
import { AjvSchema, ObjectSchemaTyped, ReadableTyped } from '@naturalcycles/nodejs-lib';
|
|
3
3
|
import { DBDeleteByIdsOperation, DBModelType, DBOperation, DBPatch, DBSaveBatchOperation, RunQueryResult } from '../db.model';
|
|
4
4
|
import { DBQuery, RunnableDBQuery } from '../query/dbQuery';
|
|
@@ -8,10 +8,11 @@ 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)
|
|
11
12
|
*/
|
|
12
|
-
export declare class CommonDao<BM extends ObjectWithId<ID
|
|
13
|
-
cfg: CommonDaoCfg<BM, DBM, ID>;
|
|
14
|
-
constructor(cfg: CommonDaoCfg<BM, DBM, ID>);
|
|
13
|
+
export declare class CommonDao<BM extends Partial<ObjectWithId<ID>>, DBM extends ObjectWithId<ID> = Saved<BM>, TM extends AnyObject = BM, ID extends string | number = NonNullable<BM['id']>> {
|
|
14
|
+
cfg: CommonDaoCfg<BM, DBM, TM, ID>;
|
|
15
|
+
constructor(cfg: CommonDaoCfg<BM, DBM, TM, ID>);
|
|
15
16
|
create(part?: Partial<BM>, opt?: CommonDaoOptions): Saved<BM>;
|
|
16
17
|
getById(id: undefined | null, opt?: CommonDaoOptions): Promise<null>;
|
|
17
18
|
getById(id?: ID | null, opt?: CommonDaoOptions): Promise<Saved<BM> | null>;
|
|
@@ -19,6 +20,8 @@ export declare class CommonDao<BM extends ObjectWithId<ID>, DBM extends ObjectWi
|
|
|
19
20
|
getByIdAsDBMOrEmpty(id: ID, part?: Partial<BM>, opt?: CommonDaoOptions): Promise<DBM>;
|
|
20
21
|
getByIdAsDBM(id: undefined | null, opt?: CommonDaoOptions): Promise<null>;
|
|
21
22
|
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>;
|
|
22
25
|
getByIds(ids: ID[], opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
|
|
23
26
|
getByIdsAsDBM(ids: ID[], opt?: CommonDaoOptions): Promise<DBM[]>;
|
|
24
27
|
requireById(id: ID, opt?: CommonDaoOptions): Promise<Saved<BM>>;
|
|
@@ -39,7 +42,7 @@ export declare class CommonDao<BM extends ObjectWithId<ID>, DBM extends ObjectWi
|
|
|
39
42
|
/**
|
|
40
43
|
* Pass `table` to override table
|
|
41
44
|
*/
|
|
42
|
-
query(table?: string): RunnableDBQuery<BM, DBM, ID>;
|
|
45
|
+
query(table?: string): RunnableDBQuery<BM, DBM, TM, ID>;
|
|
43
46
|
runQuery(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<Saved<BM>[]>;
|
|
44
47
|
runQuerySingleColumn<T = any>(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<T[]>;
|
|
45
48
|
/**
|
|
@@ -51,6 +54,8 @@ export declare class CommonDao<BM extends ObjectWithId<ID>, DBM extends ObjectWi
|
|
|
51
54
|
runQueryExtended(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<RunQueryResult<Saved<BM>>>;
|
|
52
55
|
runQueryAsDBM(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<DBM[]>;
|
|
53
56
|
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>>;
|
|
54
59
|
runQueryCount(q: DBQuery<DBM>, opt?: CommonDaoOptions): Promise<number>;
|
|
55
60
|
streamQueryForEach(q: DBQuery<DBM>, mapper: AsyncMapper<Saved<BM>, void>, opt?: CommonDaoStreamForEachOptions<Saved<BM>>): Promise<void>;
|
|
56
61
|
streamQueryAsDBMForEach(q: DBQuery<DBM>, mapper: AsyncMapper<DBM, void>, opt?: CommonDaoStreamForEachOptions<DBM>): Promise<void>;
|
|
@@ -131,13 +136,19 @@ export declare class CommonDao<BM extends ObjectWithId<ID>, DBM extends ObjectWi
|
|
|
131
136
|
anyToDBM(dbm: undefined, opt?: CommonDaoOptions): undefined;
|
|
132
137
|
anyToDBM(dbm?: any, opt?: CommonDaoOptions): DBM;
|
|
133
138
|
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[];
|
|
134
145
|
/**
|
|
135
146
|
* Returns *converted value*.
|
|
136
147
|
* Validates (unless `skipValidation=true` passed).
|
|
137
148
|
*
|
|
138
149
|
* Does NOT mutate the object.
|
|
139
150
|
*/
|
|
140
|
-
validateAndConvert<IN, OUT = IN>(obj: Partial<IN>, schema: ObjectSchemaTyped<IN> | AjvSchema<IN> | undefined, modelType
|
|
151
|
+
validateAndConvert<IN, OUT = IN>(obj: Partial<IN>, schema: ObjectSchemaTyped<IN> | AjvSchema<IN> | ZodSchema<IN> | undefined, modelType: DBModelType, opt?: CommonDaoOptions): OUT;
|
|
141
152
|
getTableSchema(): Promise<JsonSchemaRootObject<DBM>>;
|
|
142
153
|
createTable(schema: JsonSchemaObject<DBM>, opt?: CommonDaoCreateOptions): Promise<void>;
|
|
143
154
|
/**
|
|
@@ -15,6 +15,7 @@ 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)
|
|
18
19
|
*/
|
|
19
20
|
class CommonDao {
|
|
20
21
|
constructor(cfg) {
|
|
@@ -79,6 +80,8 @@ class CommonDao {
|
|
|
79
80
|
beforeDBMValidate: dbm => dbm,
|
|
80
81
|
beforeDBMToBM: dbm => dbm,
|
|
81
82
|
beforeBMToDBM: bm => bm,
|
|
83
|
+
beforeTMToBM: tm => tm,
|
|
84
|
+
beforeBMToTM: bm => bm,
|
|
82
85
|
anonymize: dbm => dbm,
|
|
83
86
|
onValidationError: err => err,
|
|
84
87
|
...cfg.hooks,
|
|
@@ -136,6 +139,22 @@ class CommonDao {
|
|
|
136
139
|
this.logResult(started, op, dbm, table);
|
|
137
140
|
return dbm || null;
|
|
138
141
|
}
|
|
142
|
+
async getByIdAsTM(id, opt = {}) {
|
|
143
|
+
if (!id)
|
|
144
|
+
return null;
|
|
145
|
+
const op = `getByIdAsTM(${id})`;
|
|
146
|
+
const table = opt.table || this.cfg.table;
|
|
147
|
+
const started = this.logStarted(op, table);
|
|
148
|
+
const [dbm] = await this.cfg.db.getByIds(table, [id]);
|
|
149
|
+
if (opt.raw) {
|
|
150
|
+
this.logResult(started, op, dbm, table);
|
|
151
|
+
return dbm || null;
|
|
152
|
+
}
|
|
153
|
+
const bm = await this.dbmToBM(dbm, opt);
|
|
154
|
+
const tm = this.bmToTM(bm, opt);
|
|
155
|
+
this.logResult(started, op, tm, table);
|
|
156
|
+
return tm || null;
|
|
157
|
+
}
|
|
139
158
|
async getByIds(ids, opt = {}) {
|
|
140
159
|
const op = `getByIds ${ids.length} id(s) (${(0, js_lib_1._truncate)(ids.slice(0, 10).join(', '), 50)})`;
|
|
141
160
|
const table = opt.table || this.cfg.table;
|
|
@@ -271,6 +290,23 @@ class CommonDao {
|
|
|
271
290
|
this.logResult(started, op, dbms, q.table);
|
|
272
291
|
return { rows: dbms, ...queryResult };
|
|
273
292
|
}
|
|
293
|
+
async runQueryAsTM(q, opt) {
|
|
294
|
+
const { rows } = await this.runQueryExtendedAsTM(q, opt);
|
|
295
|
+
return rows;
|
|
296
|
+
}
|
|
297
|
+
async runQueryExtendedAsTM(q, opt = {}) {
|
|
298
|
+
q.table = opt.table || q.table;
|
|
299
|
+
const op = `runQueryAsTM(${q.pretty()})`;
|
|
300
|
+
const started = this.logStarted(op, q.table);
|
|
301
|
+
const { rows, ...queryResult } = await this.cfg.db.runQuery(q, opt);
|
|
302
|
+
const partialQuery = !!q._selectedFieldNames;
|
|
303
|
+
const tms = partialQuery || opt.raw ? rows : this.bmsToTM(await this.dbmsToBM(rows, opt), opt);
|
|
304
|
+
this.logResult(started, op, tms, q.table);
|
|
305
|
+
return {
|
|
306
|
+
rows: tms,
|
|
307
|
+
...queryResult,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
274
310
|
async runQueryCount(q, opt = {}) {
|
|
275
311
|
q.table = opt.table || q.table;
|
|
276
312
|
const op = `runQueryCount(${q.pretty()})`;
|
|
@@ -732,6 +768,38 @@ class CommonDao {
|
|
|
732
768
|
anyToDBMs(entities, opt = {}) {
|
|
733
769
|
return entities.map(entity => this.anyToDBM(entity, opt));
|
|
734
770
|
}
|
|
771
|
+
bmToTM(bm, opt) {
|
|
772
|
+
if (bm === undefined)
|
|
773
|
+
return;
|
|
774
|
+
// optimization: 1 validation is enough
|
|
775
|
+
// Validate/convert BM
|
|
776
|
+
// bm gets assigned to the new reference
|
|
777
|
+
// bm = this.validateAndConvert(bm, this.cfg.bmSchema, DBModelType.BM, opt)
|
|
778
|
+
// BM > TM
|
|
779
|
+
const tm = this.cfg.hooks.beforeBMToTM(bm);
|
|
780
|
+
// Validate/convert DBM
|
|
781
|
+
return this.validateAndConvert(tm, this.cfg.tmSchema, db_model_1.DBModelType.TM, opt);
|
|
782
|
+
}
|
|
783
|
+
bmsToTM(bms, opt = {}) {
|
|
784
|
+
// try/catch?
|
|
785
|
+
return bms.map(bm => this.bmToTM(bm, opt));
|
|
786
|
+
}
|
|
787
|
+
tmToBM(tm, opt = {}) {
|
|
788
|
+
if (!tm)
|
|
789
|
+
return;
|
|
790
|
+
// optimization: 1 validation is enough
|
|
791
|
+
// Validate/convert TM
|
|
792
|
+
// bm gets assigned to the new reference
|
|
793
|
+
// tm = this.validateAndConvert(tm, this.cfg.tmSchema, DBModelType.TM, opt)
|
|
794
|
+
// TM > BM
|
|
795
|
+
const bm = this.cfg.hooks.beforeTMToBM(tm);
|
|
796
|
+
// Validate/convert BM
|
|
797
|
+
return this.validateAndConvert(bm, this.cfg.bmSchema, db_model_1.DBModelType.BM, opt);
|
|
798
|
+
}
|
|
799
|
+
tmsToBM(tms, opt = {}) {
|
|
800
|
+
// try/catch?
|
|
801
|
+
return tms.map(tm => this.tmToBM(tm, opt));
|
|
802
|
+
}
|
|
735
803
|
/**
|
|
736
804
|
* Returns *converted value*.
|
|
737
805
|
* Validates (unless `skipValidation=true` passed).
|
|
@@ -770,7 +838,13 @@ class CommonDao {
|
|
|
770
838
|
const objectName = table + (modelType || '');
|
|
771
839
|
let error;
|
|
772
840
|
let convertedValue;
|
|
773
|
-
if (schema instanceof
|
|
841
|
+
if (schema instanceof js_lib_1.ZodSchema) {
|
|
842
|
+
// Zod schema
|
|
843
|
+
const vr = (0, js_lib_1.zSafeValidate)(obj, schema);
|
|
844
|
+
error = vr.error;
|
|
845
|
+
convertedValue = vr.data;
|
|
846
|
+
}
|
|
847
|
+
else if (schema instanceof nodejs_lib_1.AjvSchema) {
|
|
774
848
|
// Ajv schema
|
|
775
849
|
convertedValue = obj; // because Ajv mutates original object
|
|
776
850
|
error = schema.getValidationError(obj, {
|
|
@@ -1,30 +1,29 @@
|
|
|
1
|
-
import { CommonLogger, ErrorMode, ObjectWithId } from '@naturalcycles/js-lib';
|
|
1
|
+
import { CommonLogger, ErrorMode, ObjectWithId, Saved, ZodError, ZodSchema } 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
|
|
6
|
-
createRandomId()
|
|
5
|
+
export interface CommonDaoHooks<BM extends Partial<ObjectWithId<ID>>, DBM extends ObjectWithId<ID>, TM, ID extends string | number> {
|
|
6
|
+
createRandomId: () => ID;
|
|
7
7
|
/**
|
|
8
8
|
* createNaturalId hook is called (tried) first.
|
|
9
9
|
* If it doesn't exist - createRandomId is called.
|
|
10
10
|
*/
|
|
11
|
-
createNaturalId(obj: DBM | BM)
|
|
12
|
-
parseNaturalId(id: ID)
|
|
13
|
-
beforeCreate(bm: Partial<BM>)
|
|
14
|
-
beforeDBMValidate(dbm: Partial<DBM>)
|
|
15
|
-
beforeDBMToBM(dbm: DBM)
|
|
16
|
-
beforeBMToDBM(bm: BM)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
anonymize(dbm: DBM): DBM;
|
|
11
|
+
createNaturalId: (obj: DBM | BM) => ID;
|
|
12
|
+
parseNaturalId: (id: ID) => Partial<DBM>;
|
|
13
|
+
beforeCreate: (bm: Partial<BM>) => Partial<BM>;
|
|
14
|
+
beforeDBMValidate: (dbm: Partial<DBM>) => Partial<DBM>;
|
|
15
|
+
beforeDBMToBM: (dbm: DBM) => Partial<BM> | Promise<Partial<BM>>;
|
|
16
|
+
beforeBMToDBM: (bm: BM) => Partial<DBM> | Promise<Partial<DBM>>;
|
|
17
|
+
beforeTMToBM: (tm: TM) => Partial<BM>;
|
|
18
|
+
beforeBMToTM: (bm: BM) => Partial<TM>;
|
|
19
|
+
anonymize: (dbm: DBM) => DBM;
|
|
21
20
|
/**
|
|
22
21
|
* If hook is defined - allows to prevent or modify the error thrown.
|
|
23
22
|
* Return `false` to prevent throwing an error.
|
|
24
23
|
* Return original `err` to pass the error through (will be thrown in CommonDao).
|
|
25
24
|
* Return modified/new `Error` if needed.
|
|
26
25
|
*/
|
|
27
|
-
onValidationError(err: JoiValidationError | AjvValidationError)
|
|
26
|
+
onValidationError: (err: JoiValidationError | AjvValidationError | ZodError) => Error | false;
|
|
28
27
|
}
|
|
29
28
|
export declare enum CommonDaoLogLevel {
|
|
30
29
|
/**
|
|
@@ -44,14 +43,15 @@ export declare enum CommonDaoLogLevel {
|
|
|
44
43
|
*/
|
|
45
44
|
DATA_FULL = 30
|
|
46
45
|
}
|
|
47
|
-
export interface CommonDaoCfg<BM extends ObjectWithId<ID
|
|
46
|
+
export interface CommonDaoCfg<BM extends Partial<ObjectWithId<ID>>, DBM extends ObjectWithId<ID> = Saved<BM>, TM = BM, ID extends string | number = string> {
|
|
48
47
|
db: CommonDB;
|
|
49
48
|
table: string;
|
|
50
49
|
/**
|
|
51
|
-
* Joi or
|
|
50
|
+
* Joi, AjvSchema or ZodSchema is supported.
|
|
52
51
|
*/
|
|
53
|
-
dbmSchema?: ObjectSchemaTyped<DBM> | AjvSchema<DBM>;
|
|
54
|
-
bmSchema?: ObjectSchemaTyped<BM> | AjvSchema<BM>;
|
|
52
|
+
dbmSchema?: ObjectSchemaTyped<DBM> | AjvSchema<DBM> | ZodSchema<DBM>;
|
|
53
|
+
bmSchema?: ObjectSchemaTyped<BM> | AjvSchema<BM> | ZodSchema<BM>;
|
|
54
|
+
tmSchema?: ObjectSchemaTyped<TM> | AjvSchema<TM> | ZodSchema<TM>;
|
|
55
55
|
excludeFromIndexes?: (keyof DBM)[];
|
|
56
56
|
/**
|
|
57
57
|
* Defaults to false.
|
|
@@ -61,8 +61,6 @@ export interface CommonDaoCfg<BM extends ObjectWithId<ID>, DBM extends ObjectWit
|
|
|
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
|
|
66
64
|
*/
|
|
67
65
|
immutable?: boolean;
|
|
68
66
|
/**
|
|
@@ -82,7 +80,7 @@ export interface CommonDaoCfg<BM extends ObjectWithId<ID>, DBM extends ObjectWit
|
|
|
82
80
|
* @default false
|
|
83
81
|
*/
|
|
84
82
|
logStarted?: boolean;
|
|
85
|
-
hooks?: Partial<CommonDaoHooks<BM, DBM, ID>>;
|
|
83
|
+
hooks?: Partial<CommonDaoHooks<BM, DBM, TM, ID>>;
|
|
86
84
|
/**
|
|
87
85
|
* Defaults to 'string'
|
|
88
86
|
*/
|
|
@@ -96,7 +94,6 @@ export interface CommonDaoCfg<BM extends ObjectWithId<ID>, DBM extends ObjectWit
|
|
|
96
94
|
/**
|
|
97
95
|
* See the same option in CommonDB.
|
|
98
96
|
* Defaults to false normally.
|
|
99
|
-
* "Generated" means "generated by the underlying DB" (e.g MySQL autoincrement).
|
|
100
97
|
*/
|
|
101
98
|
assignGeneratedIds?: boolean;
|
|
102
99
|
/**
|
|
@@ -182,7 +179,7 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
182
179
|
/**
|
|
183
180
|
* All properties default to undefined.
|
|
184
181
|
*/
|
|
185
|
-
export interface CommonDaoSaveOptions<DBM extends
|
|
182
|
+
export interface CommonDaoSaveOptions<DBM extends ObjectWithId> extends CommonDaoOptions, CommonDBSaveOptions<DBM> {
|
|
186
183
|
/**
|
|
187
184
|
* @default false
|
|
188
185
|
*
|
package/dist/db.model.d.ts
CHANGED
package/dist/db.model.js
CHANGED
|
@@ -11,22 +11,22 @@ export interface CommonKeyValueDB {
|
|
|
11
11
|
/**
|
|
12
12
|
* Check that DB connection is working properly.
|
|
13
13
|
*/
|
|
14
|
-
ping()
|
|
14
|
+
ping: () => Promise<void>;
|
|
15
15
|
/**
|
|
16
16
|
* Will do like `create table ...` for mysql.
|
|
17
17
|
* Caution! dropIfExists defaults to false. If set to true - will actually DROP the table!
|
|
18
18
|
*/
|
|
19
|
-
createTable(table: string, opt?: CommonDBCreateOptions)
|
|
19
|
+
createTable: (table: string, opt?: CommonDBCreateOptions) => Promise<void>;
|
|
20
20
|
/**
|
|
21
21
|
* Returns an array of tuples [key, value]. Not found values are not returned (no error is thrown).
|
|
22
22
|
*
|
|
23
23
|
* Currently it is NOT required to maintain the same order as input `ids`.
|
|
24
24
|
*/
|
|
25
|
-
getByIds(table: string, ids: string[])
|
|
26
|
-
deleteByIds(table: string, ids: string[])
|
|
27
|
-
saveBatch(table: string, entries: KeyValueDBTuple[])
|
|
28
|
-
streamIds(table: string, limit?: number)
|
|
29
|
-
streamValues(table: string, limit?: number)
|
|
30
|
-
streamEntries(table: string, limit?: number)
|
|
31
|
-
count(table: string)
|
|
25
|
+
getByIds: (table: string, ids: string[]) => Promise<KeyValueDBTuple[]>;
|
|
26
|
+
deleteByIds: (table: string, ids: string[]) => Promise<void>;
|
|
27
|
+
saveBatch: (table: string, entries: KeyValueDBTuple[]) => Promise<void>;
|
|
28
|
+
streamIds: (table: string, limit?: number) => ReadableTyped<string>;
|
|
29
|
+
streamValues: (table: string, limit?: number) => ReadableTyped<Buffer>;
|
|
30
|
+
streamEntries: (table: string, limit?: number) => ReadableTyped<KeyValueDBTuple>;
|
|
31
|
+
count: (table: string) => Promise<number>;
|
|
32
32
|
}
|
|
@@ -21,9 +21,9 @@ export interface CommonKeyValueDaoCfg<T> {
|
|
|
21
21
|
*/
|
|
22
22
|
logStarted?: boolean;
|
|
23
23
|
hooks?: {
|
|
24
|
-
mapValueToBuffer
|
|
25
|
-
mapBufferToValue
|
|
26
|
-
beforeCreate
|
|
24
|
+
mapValueToBuffer?: (v: T) => Promise<Buffer>;
|
|
25
|
+
mapBufferToValue?: (b: Buffer) => Promise<T>;
|
|
26
|
+
beforeCreate?: (v: Partial<T>) => Partial<T>;
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
29
|
* Set to `true` to conveniently enable zipping+JSON.stringify
|
package/dist/query/dbQuery.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyObjectWithId, ObjectWithId, AsyncMapper, Saved } from '@naturalcycles/js-lib';
|
|
1
|
+
import { AnyObjectWithId, ObjectWithId, AsyncMapper, Saved, AnyObject } 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
|
|
27
|
+
export interface DBQueryFilter<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
28
28
|
name: keyof ROW;
|
|
29
29
|
op: DBQueryFilterOperator;
|
|
30
30
|
val: any;
|
|
31
31
|
}
|
|
32
|
-
export interface DBQueryOrder<ROW extends
|
|
32
|
+
export interface DBQueryOrder<ROW extends ObjectWithId = AnyObjectWithId> {
|
|
33
33
|
name: keyof ROW;
|
|
34
34
|
descending?: boolean;
|
|
35
35
|
}
|
|
@@ -43,14 +43,14 @@ export interface DBQueryOrder<ROW extends Partial<ObjectWithId> = AnyObjectWithI
|
|
|
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
|
|
46
|
+
export declare class DBQuery<ROW extends 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
|
|
53
|
+
static fromPlainObject<ROW extends ObjectWithId = AnyObjectWithId>(obj: Partial<DBQuery<ROW>> & {
|
|
54
54
|
table: string;
|
|
55
55
|
}): DBQuery<ROW>;
|
|
56
56
|
_filters: DBQueryFilter<ROW>[];
|
|
@@ -84,17 +84,19 @@ export declare class DBQuery<ROW extends Partial<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 ObjectWithId<ID
|
|
88
|
-
dao: CommonDao<BM, DBM, ID>;
|
|
87
|
+
export declare class RunnableDBQuery<BM extends Partial<ObjectWithId<ID>>, DBM extends ObjectWithId<ID> = Saved<BM>, TM extends AnyObject = BM, ID extends string | number = string> extends DBQuery<DBM> {
|
|
88
|
+
dao: CommonDao<BM, DBM, TM, ID>;
|
|
89
89
|
/**
|
|
90
90
|
* Pass `table` to override table.
|
|
91
91
|
*/
|
|
92
|
-
constructor(dao: CommonDao<BM, DBM, ID>, table?: string);
|
|
92
|
+
constructor(dao: CommonDao<BM, DBM, TM, 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[]>;
|
|
96
97
|
runQueryExtended(opt?: CommonDaoOptions): Promise<RunQueryResult<Saved<BM>>>;
|
|
97
98
|
runQueryExtendedAsDBM(opt?: CommonDaoOptions): Promise<RunQueryResult<DBM>>;
|
|
99
|
+
runQueryExtendedAsTM(opt?: CommonDaoOptions): Promise<RunQueryResult<TM>>;
|
|
98
100
|
runQueryCount(opt?: CommonDaoOptions): Promise<number>;
|
|
99
101
|
updateByQuery(patch: DBPatch<DBM>, opt?: CommonDaoOptions): Promise<number>;
|
|
100
102
|
streamQueryForEach(mapper: AsyncMapper<Saved<BM>, void>, opt?: CommonDaoStreamForEachOptions<Saved<BM>>): Promise<void>;
|
package/dist/query/dbQuery.js
CHANGED
|
@@ -153,12 +153,18 @@ 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
|
+
}
|
|
156
159
|
async runQueryExtended(opt) {
|
|
157
160
|
return await this.dao.runQueryExtended(this, opt);
|
|
158
161
|
}
|
|
159
162
|
async runQueryExtendedAsDBM(opt) {
|
|
160
163
|
return await this.dao.runQueryExtendedAsDBM(this, opt);
|
|
161
164
|
}
|
|
165
|
+
async runQueryExtendedAsTM(opt) {
|
|
166
|
+
return await this.dao.runQueryExtendedAsTM(this, opt);
|
|
167
|
+
}
|
|
162
168
|
async runQueryCount(opt) {
|
|
163
169
|
return await this.dao.runQueryCount(this, opt);
|
|
164
170
|
}
|
package/dist/testing/daoTest.js
CHANGED
|
@@ -13,6 +13,7 @@ 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,
|
|
16
17
|
logStarted: true,
|
|
17
18
|
logLevel: __1.CommonDaoLogLevel.DATA_FULL,
|
|
18
19
|
});
|