@naturalcycles/db-lib 8.23.0 → 8.24.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/cachedb/cache.db.d.ts +1 -3
- package/dist/adapter/cachedb/cache.db.js +15 -14
- package/dist/adapter/cachedb/cache.db.model.d.ts +5 -1
- package/dist/adapter/file/file.db.js +3 -3
- package/dist/adapter/file/file.db.model.d.ts +5 -1
- package/dist/adapter/inmemory/inMemory.db.d.ts +5 -1
- package/dist/adapter/inmemory/inMemory.db.js +6 -6
- package/dist/commondao/common.dao.d.ts +2 -2
- package/dist/commondao/common.dao.js +16 -13
- package/dist/commondao/common.dao.model.d.ts +15 -2
- package/dist/commondao/common.dao.model.js +9 -0
- package/dist/pipeline/dbPipelineBackup.js +0 -1
- package/dist/pipeline/dbPipelineRestore.js +1 -1
- package/package.json +1 -1
- package/readme.md +1 -6
- package/src/adapter/cachedb/cache.db.model.ts +6 -1
- package/src/adapter/cachedb/cache.db.ts +19 -15
- package/src/adapter/file/file.db.model.ts +6 -1
- package/src/adapter/file/file.db.ts +4 -5
- package/src/adapter/inmemory/inMemory.db.ts +16 -8
- package/src/commondao/common.dao.model.ts +20 -2
- package/src/commondao/common.dao.ts +34 -32
- package/src/pipeline/dbPipelineBackup.ts +0 -2
- package/src/pipeline/dbPipelineRestore.ts +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Readable } from 'stream';
|
|
3
3
|
import { JsonSchemaObject, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
|
|
4
|
-
import { IDebugger } from '@naturalcycles/nodejs-lib';
|
|
5
4
|
import { BaseCommonDB } from '../../base.common.db';
|
|
6
5
|
import { CommonDB } from '../../common.db';
|
|
7
6
|
import { RunQueryResult } from '../../db.model';
|
|
@@ -14,9 +13,8 @@ import { CacheDBCfg, CacheDBCreateOptions, CacheDBOptions, CacheDBStreamOptions
|
|
|
14
13
|
* Queries always hit downstream (unless `onlyCache` is passed)
|
|
15
14
|
*/
|
|
16
15
|
export declare class CacheDB extends BaseCommonDB implements CommonDB {
|
|
17
|
-
cfg: CacheDBCfg;
|
|
18
16
|
constructor(cfg: CacheDBCfg);
|
|
19
|
-
|
|
17
|
+
cfg: CacheDBCfg;
|
|
20
18
|
ping(): Promise<void>;
|
|
21
19
|
/**
|
|
22
20
|
* Resets InMemory DB data
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CacheDB = void 0;
|
|
4
4
|
const stream_1 = require("stream");
|
|
5
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
5
|
const base_common_db_1 = require("../../base.common.db");
|
|
7
6
|
/**
|
|
8
7
|
* CommonDB implementation that proxies requests to downstream CommonDB
|
|
@@ -13,8 +12,10 @@ const base_common_db_1 = require("../../base.common.db");
|
|
|
13
12
|
class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
14
13
|
constructor(cfg) {
|
|
15
14
|
super();
|
|
16
|
-
this.cfg =
|
|
17
|
-
|
|
15
|
+
this.cfg = {
|
|
16
|
+
logger: console,
|
|
17
|
+
...cfg,
|
|
18
|
+
};
|
|
18
19
|
}
|
|
19
20
|
async ping() {
|
|
20
21
|
await Promise.all([this.cfg.cacheDB.ping(), this.cfg.downstreamDB.ping()]);
|
|
@@ -49,7 +50,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
49
50
|
results.forEach(r => (resultMap[r.id] = r));
|
|
50
51
|
missingIds.push(...ids.filter(id => !resultMap[id]));
|
|
51
52
|
if (this.cfg.logCached) {
|
|
52
|
-
this.log(`${table}.getByIds ${results.length} rows from cache: [${results
|
|
53
|
+
this.cfg.logger?.log(`${table}.getByIds ${results.length} rows from cache: [${results
|
|
53
54
|
.map(r => r.id)
|
|
54
55
|
.join(', ')}]`);
|
|
55
56
|
}
|
|
@@ -58,7 +59,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
58
59
|
const results = await this.cfg.downstreamDB.getByIds(table, missingIds, opt);
|
|
59
60
|
results.forEach(r => (resultMap[r.id] = r));
|
|
60
61
|
if (this.cfg.logDownstream) {
|
|
61
|
-
this.log(`${table}.getByIds ${results.length} rows from downstream: [${results
|
|
62
|
+
this.cfg.logger?.log(`${table}.getByIds ${results.length} rows from downstream: [${results
|
|
62
63
|
.map(r => r.id)
|
|
63
64
|
.join(', ')}]`);
|
|
64
65
|
}
|
|
@@ -76,13 +77,13 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
76
77
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
77
78
|
deletedIds = await this.cfg.downstreamDB.deleteByIds(table, ids, opt);
|
|
78
79
|
if (this.cfg.logDownstream) {
|
|
79
|
-
this.log(`${table}.deleteByIds ${deletedIds} rows from downstream`);
|
|
80
|
+
this.cfg.logger?.log(`${table}.deleteByIds ${deletedIds} rows from downstream`);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
83
84
|
const cacheResult = this.cfg.cacheDB.deleteByIds(table, ids, opt).then(deletedFromCache => {
|
|
84
85
|
if (this.cfg.logCached) {
|
|
85
|
-
this.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`);
|
|
86
|
+
this.cfg.logger?.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`);
|
|
86
87
|
}
|
|
87
88
|
});
|
|
88
89
|
if (this.cfg.awaitCache)
|
|
@@ -94,7 +95,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
94
95
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
95
96
|
await this.cfg.downstreamDB.saveBatch(table, rows, opt);
|
|
96
97
|
if (this.cfg.logDownstream) {
|
|
97
|
-
this.log(`${table}.saveBatch ${rows.length} rows to downstream: [${rows
|
|
98
|
+
this.cfg.logger?.log(`${table}.saveBatch ${rows.length} rows to downstream: [${rows
|
|
98
99
|
.map(r => r.id)
|
|
99
100
|
.join(', ')}]`);
|
|
100
101
|
}
|
|
@@ -102,7 +103,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
102
103
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
103
104
|
const cacheResult = this.cfg.cacheDB.saveBatch(table, rows, opt).then(() => {
|
|
104
105
|
if (this.cfg.logCached) {
|
|
105
|
-
this.log(`${table}.saveBatch ${rows.length} rows to cache: [${rows.map(r => r.id).join(', ')}]`);
|
|
106
|
+
this.cfg.logger?.log(`${table}.saveBatch ${rows.length} rows to cache: [${rows.map(r => r.id).join(', ')}]`);
|
|
106
107
|
}
|
|
107
108
|
});
|
|
108
109
|
if (this.cfg.awaitCache)
|
|
@@ -113,7 +114,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
113
114
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
114
115
|
const { rows, ...queryResult } = await this.cfg.downstreamDB.runQuery(q, opt);
|
|
115
116
|
if (this.cfg.logDownstream) {
|
|
116
|
-
this.log(`${q.table}.runQuery ${rows.length} rows from downstream`);
|
|
117
|
+
this.cfg.logger?.log(`${q.table}.runQuery ${rows.length} rows from downstream`);
|
|
117
118
|
}
|
|
118
119
|
// Don't save to cache if it was a projection query
|
|
119
120
|
if (!opt.skipCache && !opt.skipCache && !q._selectedFieldNames) {
|
|
@@ -127,7 +128,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
127
128
|
return { rows: [] };
|
|
128
129
|
const { rows, ...queryResult } = await this.cfg.cacheDB.runQuery(q, opt);
|
|
129
130
|
if (this.cfg.logCached) {
|
|
130
|
-
this.log(`${q.table}.runQuery ${rows.length} rows from cache`);
|
|
131
|
+
this.cfg.logger?.log(`${q.table}.runQuery ${rows.length} rows from cache`);
|
|
131
132
|
}
|
|
132
133
|
return { rows, ...queryResult };
|
|
133
134
|
}
|
|
@@ -137,7 +138,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
137
138
|
}
|
|
138
139
|
const count = await this.cfg.cacheDB.runQueryCount(q, opt);
|
|
139
140
|
if (this.cfg.logCached) {
|
|
140
|
-
this.log(`${q.table}.runQueryCount ${count} rows from cache`);
|
|
141
|
+
this.cfg.logger?.log(`${q.table}.runQueryCount ${count} rows from cache`);
|
|
141
142
|
}
|
|
142
143
|
return count;
|
|
143
144
|
}
|
|
@@ -175,7 +176,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
175
176
|
if (!opt.onlyCache && !this.cfg.onlyCache) {
|
|
176
177
|
const deletedIds = await this.cfg.downstreamDB.deleteByQuery(q, opt);
|
|
177
178
|
if (this.cfg.logDownstream) {
|
|
178
|
-
this.log(`${q.table}.deleteByQuery ${deletedIds} rows from downstream and cache`);
|
|
179
|
+
this.cfg.logger?.log(`${q.table}.deleteByQuery ${deletedIds} rows from downstream and cache`);
|
|
179
180
|
}
|
|
180
181
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
181
182
|
const cacheResult = this.cfg.cacheDB.deleteByQuery(q, opt);
|
|
@@ -188,7 +189,7 @@ class CacheDB extends base_common_db_1.BaseCommonDB {
|
|
|
188
189
|
return 0;
|
|
189
190
|
const deletedIds = await this.cfg.cacheDB.deleteByQuery(q, opt);
|
|
190
191
|
if (this.cfg.logCached) {
|
|
191
|
-
this.log(`${q.table}.deleteByQuery ${deletedIds} rows from cache`);
|
|
192
|
+
this.cfg.logger?.log(`${q.table}.deleteByQuery ${deletedIds} rows from cache`);
|
|
192
193
|
}
|
|
193
194
|
return deletedIds;
|
|
194
195
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ObjectWithId } from '@naturalcycles/js-lib';
|
|
1
|
+
import { CommonLogger, ObjectWithId } from '@naturalcycles/js-lib';
|
|
2
2
|
import { CommonDB } from '../../common.db';
|
|
3
3
|
import { CommonDBCreateOptions, CommonDBSaveOptions, CommonDBStreamOptions } from '../../db.model';
|
|
4
4
|
export interface CacheDBCfg {
|
|
@@ -32,6 +32,10 @@ export interface CacheDBCfg {
|
|
|
32
32
|
* @default false
|
|
33
33
|
*/
|
|
34
34
|
logDownstream?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Defaults to `console`.
|
|
37
|
+
*/
|
|
38
|
+
logger?: CommonLogger;
|
|
35
39
|
}
|
|
36
40
|
export interface CacheDBOptions<ROW extends ObjectWithId> extends CommonDBSaveOptions<ROW> {
|
|
37
41
|
/**
|
|
@@ -5,7 +5,6 @@ const js_lib_1 = require("@naturalcycles/js-lib");
|
|
|
5
5
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
6
|
const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
|
|
7
7
|
const __1 = require("../..");
|
|
8
|
-
const log = (0, nodejs_lib_1.Debug)('nc:db-lib:filedb');
|
|
9
8
|
/**
|
|
10
9
|
* Provides barebone implementation for "whole file" based CommonDB.
|
|
11
10
|
* "whole file" means that the persistence layer doesn't allow any querying,
|
|
@@ -22,6 +21,7 @@ class FileDB extends __1.BaseCommonDB {
|
|
|
22
21
|
this.cfg = {
|
|
23
22
|
sortObjects: true,
|
|
24
23
|
logFinished: true,
|
|
24
|
+
logger: console,
|
|
25
25
|
...cfg,
|
|
26
26
|
};
|
|
27
27
|
}
|
|
@@ -183,14 +183,14 @@ class FileDB extends __1.BaseCommonDB {
|
|
|
183
183
|
}
|
|
184
184
|
logStarted(op) {
|
|
185
185
|
if (this.cfg.logStarted) {
|
|
186
|
-
log(`>> ${op}`);
|
|
186
|
+
this.cfg.logger?.log(`>> ${op}`);
|
|
187
187
|
}
|
|
188
188
|
return Date.now();
|
|
189
189
|
}
|
|
190
190
|
logFinished(started, op) {
|
|
191
191
|
if (!this.cfg.logFinished)
|
|
192
192
|
return;
|
|
193
|
-
log(`<< ${op} ${(0, colors_1.dimGrey)(`in ${(0, js_lib_1._since)(started)}`)}`);
|
|
193
|
+
this.cfg.logger?.log(`<< ${op} ${(0, colors_1.dimGrey)(`in ${(0, js_lib_1._since)(started)}`)}`);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
exports.FileDB = FileDB;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ObjectWithId } from '@naturalcycles/js-lib';
|
|
1
|
+
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 {
|
|
@@ -18,6 +18,10 @@ export interface FileDBCfg {
|
|
|
18
18
|
* If true - will run `sortObjectDeep()` on each object to achieve deterministic sort
|
|
19
19
|
*/
|
|
20
20
|
sortObjects?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Defaults to `console`.
|
|
23
|
+
*/
|
|
24
|
+
logger?: CommonLogger;
|
|
21
25
|
/**
|
|
22
26
|
* @default false
|
|
23
27
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JsonSchemaObject, StringMap, JsonSchemaRootObject, ObjectWithId } from '@naturalcycles/js-lib';
|
|
1
|
+
import { JsonSchemaObject, StringMap, JsonSchemaRootObject, ObjectWithId, CommonLogger } from '@naturalcycles/js-lib';
|
|
2
2
|
import { ReadableTyped } from '@naturalcycles/nodejs-lib';
|
|
3
3
|
import { CommonDB, DBTransaction } from '../..';
|
|
4
4
|
import { CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, RunQueryResult } from '../../db.model';
|
|
@@ -30,6 +30,10 @@ export interface InMemoryDBCfg {
|
|
|
30
30
|
* @default true
|
|
31
31
|
*/
|
|
32
32
|
persistZip: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Defaults to `console`.
|
|
35
|
+
*/
|
|
36
|
+
logger?: CommonLogger;
|
|
33
37
|
}
|
|
34
38
|
export declare class InMemoryDB implements CommonDB {
|
|
35
39
|
constructor(cfg?: Partial<InMemoryDBCfg>);
|
|
@@ -8,7 +8,6 @@ const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
|
8
8
|
const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
|
|
9
9
|
const fs = require("fs-extra");
|
|
10
10
|
const __1 = require("../..");
|
|
11
|
-
const log = (0, nodejs_lib_1.Debug)('nc:db-lib:inmemorydb');
|
|
12
11
|
class InMemoryDB {
|
|
13
12
|
constructor(cfg) {
|
|
14
13
|
// data[table][id] > {id: 'a', created: ... }
|
|
@@ -19,6 +18,7 @@ class InMemoryDB {
|
|
|
19
18
|
persistenceEnabled: false,
|
|
20
19
|
persistZip: true,
|
|
21
20
|
persistentStoragePath: './tmp/inmemorydb',
|
|
21
|
+
logger: console,
|
|
22
22
|
...cfg,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
@@ -36,7 +36,7 @@ class InMemoryDB {
|
|
|
36
36
|
async resetCache(_table) {
|
|
37
37
|
if (_table) {
|
|
38
38
|
const table = this.cfg.tablesPrefix + _table;
|
|
39
|
-
log(`reset ${table}`);
|
|
39
|
+
this.cfg.logger?.log(`reset ${table}`);
|
|
40
40
|
this.data[table] = {};
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
@@ -44,7 +44,7 @@ class InMemoryDB {
|
|
|
44
44
|
(await this.getTables()).forEach(table => {
|
|
45
45
|
this.data[table] = {};
|
|
46
46
|
});
|
|
47
|
-
log('reset');
|
|
47
|
+
this.cfg.logger?.log('reset');
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
async getTables() {
|
|
@@ -76,7 +76,7 @@ class InMemoryDB {
|
|
|
76
76
|
this.data[table] = this.data[table] || {};
|
|
77
77
|
rows.forEach(r => {
|
|
78
78
|
if (!r.id) {
|
|
79
|
-
|
|
79
|
+
this.cfg.logger?.warn({ rows });
|
|
80
80
|
throw new Error(`InMemoryDB: id doesn't exist for row`);
|
|
81
81
|
}
|
|
82
82
|
// JSON parse/stringify (deep clone) is to:
|
|
@@ -160,7 +160,7 @@ class InMemoryDB {
|
|
|
160
160
|
fs.createWriteStream(fname),
|
|
161
161
|
]);
|
|
162
162
|
});
|
|
163
|
-
log(`flushToDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to save ${(0, colors_1.yellow)(tables)} tables`);
|
|
163
|
+
this.cfg.logger?.log(`flushToDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to save ${(0, colors_1.yellow)(tables)} tables`);
|
|
164
164
|
}
|
|
165
165
|
/**
|
|
166
166
|
* Restores all tables (all namespaces) at once.
|
|
@@ -189,7 +189,7 @@ class InMemoryDB {
|
|
|
189
189
|
]);
|
|
190
190
|
this.data[table] = (0, js_lib_1._by)(rows, r => r.id);
|
|
191
191
|
});
|
|
192
|
-
log(`restoreFromDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to read ${(0, colors_1.yellow)(files.length)} tables`);
|
|
192
|
+
this.cfg.logger?.log(`restoreFromDisk took ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))} to read ${(0, colors_1.yellow)(files.length)} tables`);
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
exports.InMemoryDB = InMemoryDB;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AsyncMapper, JsonSchemaObject, JsonSchemaRootObject,
|
|
1
|
+
import { AsyncMapper, JsonSchemaObject, JsonSchemaRootObject, ObjectWithId, Saved } from '@naturalcycles/js-lib';
|
|
2
2
|
import { AjvSchema, ObjectSchemaTyped, ReadableTyped } from '@naturalcycles/nodejs-lib';
|
|
3
3
|
import { DBModelType, RunQueryResult } from '../db.model';
|
|
4
4
|
import { DBQuery, RunnableDBQuery } from '../query/dbQuery';
|
|
@@ -137,7 +137,7 @@ export declare class CommonDao<BM extends Partial<ObjectWithId>, DBM extends Obj
|
|
|
137
137
|
*
|
|
138
138
|
* Does NOT mutate the object.
|
|
139
139
|
*/
|
|
140
|
-
validateAndConvert<IN, OUT = IN>(obj: IN
|
|
140
|
+
validateAndConvert<IN, OUT = IN>(obj: Partial<IN>, schema: ObjectSchemaTyped<IN> | AjvSchema<IN> | undefined, modelType: DBModelType, opt?: CommonDaoOptions): OUT;
|
|
141
141
|
getTableSchema(): Promise<JsonSchemaRootObject<DBM>>;
|
|
142
142
|
createTable(schema: JsonSchemaObject<DBM>, opt?: CommonDaoCreateOptions): Promise<void>;
|
|
143
143
|
/**
|
|
@@ -7,8 +7,9 @@ const cnst_1 = require("../cnst");
|
|
|
7
7
|
const db_model_1 = require("../db.model");
|
|
8
8
|
const dbQuery_1 = require("../query/dbQuery");
|
|
9
9
|
const common_dao_model_1 = require("./common.dao.model");
|
|
10
|
-
const log = (0, nodejs_lib_1.Debug)('nc:db-lib:commondao');
|
|
11
10
|
/* eslint-disable no-dupe-class-members */
|
|
11
|
+
const isGAE = !!process.env['GAE_INSTANCE'];
|
|
12
|
+
const isCI = !!process.env['CI'];
|
|
12
13
|
/**
|
|
13
14
|
* Lowest common denominator API between supported Databases.
|
|
14
15
|
*
|
|
@@ -20,8 +21,12 @@ class CommonDao {
|
|
|
20
21
|
constructor(cfg) {
|
|
21
22
|
this.cfg = cfg;
|
|
22
23
|
this.cfg = {
|
|
23
|
-
|
|
24
|
+
// Default is to NOT log in AppEngine and in CI,
|
|
25
|
+
// otherwise to log Operations
|
|
26
|
+
// e.g in Dev (local machine), Test - it will log operations (useful for debugging)
|
|
27
|
+
logLevel: isGAE || isCI ? common_dao_model_1.CommonDaoLogLevel.NONE : common_dao_model_1.CommonDaoLogLevel.OPERATIONS,
|
|
24
28
|
createdUpdated: true,
|
|
29
|
+
logger: console,
|
|
25
30
|
...cfg,
|
|
26
31
|
hooks: {
|
|
27
32
|
createId: () => (0, nodejs_lib_1.stringId)(),
|
|
@@ -234,7 +239,7 @@ class CommonDao {
|
|
|
234
239
|
const started = this.logStarted(op, q.table);
|
|
235
240
|
const count = await this.cfg.db.runQueryCount(q, opt);
|
|
236
241
|
if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
|
|
237
|
-
log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
|
|
242
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
|
|
238
243
|
}
|
|
239
244
|
return count;
|
|
240
245
|
}
|
|
@@ -269,7 +274,7 @@ class CommonDao {
|
|
|
269
274
|
(0, nodejs_lib_1.writableVoid)(),
|
|
270
275
|
]);
|
|
271
276
|
if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
|
|
272
|
-
log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
|
|
277
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
|
|
273
278
|
}
|
|
274
279
|
}
|
|
275
280
|
async streamQueryAsDBMForEach(q, mapper, opt = {}) {
|
|
@@ -301,7 +306,7 @@ class CommonDao {
|
|
|
301
306
|
(0, nodejs_lib_1.writableVoid)(),
|
|
302
307
|
]);
|
|
303
308
|
if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
|
|
304
|
-
log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
|
|
309
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${(0, js_lib_1._since)(started)}`);
|
|
305
310
|
}
|
|
306
311
|
}
|
|
307
312
|
/**
|
|
@@ -384,7 +389,7 @@ class CommonDao {
|
|
|
384
389
|
(0, nodejs_lib_1.writableVoid)(),
|
|
385
390
|
]);
|
|
386
391
|
if (this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.OPERATIONS) {
|
|
387
|
-
log(`<< ${q.table}.${op}: ${count} id(s) in ${(0, js_lib_1._since)(started)}`);
|
|
392
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} id(s) in ${(0, js_lib_1._since)(started)}`);
|
|
388
393
|
}
|
|
389
394
|
}
|
|
390
395
|
assignIdCreatedUpdated(obj, opt = {}) {
|
|
@@ -732,8 +737,6 @@ class CommonDao {
|
|
|
732
737
|
async ping() {
|
|
733
738
|
await this.cfg.db.ping();
|
|
734
739
|
}
|
|
735
|
-
// todo: logging
|
|
736
|
-
// todo: bmToDBM, etc. How?
|
|
737
740
|
// transaction(): DBTransaction {
|
|
738
741
|
// return this.cfg.db.transaction()
|
|
739
742
|
// }
|
|
@@ -745,7 +748,7 @@ class CommonDao {
|
|
|
745
748
|
if (Array.isArray(res)) {
|
|
746
749
|
logRes = `${res.length} row(s)`;
|
|
747
750
|
if (res.length && this.cfg.logLevel >= common_dao_model_1.CommonDaoLogLevel.DATA_FULL) {
|
|
748
|
-
args.push('\n', res.slice(0, 10)); // max 10 items
|
|
751
|
+
args.push('\n', ...res.slice(0, 10)); // max 10 items
|
|
749
752
|
}
|
|
750
753
|
}
|
|
751
754
|
else if (res) {
|
|
@@ -757,16 +760,16 @@ class CommonDao {
|
|
|
757
760
|
else {
|
|
758
761
|
logRes = `undefined`;
|
|
759
762
|
}
|
|
760
|
-
log(
|
|
763
|
+
this.cfg.logger?.log(`<< ${table}.${op}: ${logRes} in ${(0, js_lib_1._since)(started)}`, ...args);
|
|
761
764
|
}
|
|
762
765
|
logSaveResult(started, op, table) {
|
|
763
766
|
if (!this.cfg.logLevel)
|
|
764
767
|
return;
|
|
765
|
-
log(`<< ${table}.${op} in ${(0, js_lib_1._since)(started)}`);
|
|
768
|
+
this.cfg.logger?.log(`<< ${table}.${op} in ${(0, js_lib_1._since)(started)}`);
|
|
766
769
|
}
|
|
767
770
|
logStarted(op, table, force = false) {
|
|
768
771
|
if (this.cfg.logStarted || force) {
|
|
769
|
-
log(`>> ${table}.${op}`);
|
|
772
|
+
this.cfg.logger?.log(`>> ${table}.${op}`);
|
|
770
773
|
}
|
|
771
774
|
return Date.now();
|
|
772
775
|
}
|
|
@@ -786,7 +789,7 @@ class CommonDao {
|
|
|
786
789
|
args.push(items);
|
|
787
790
|
}
|
|
788
791
|
}
|
|
789
|
-
log(...args);
|
|
792
|
+
this.cfg.logger?.log(...args);
|
|
790
793
|
}
|
|
791
794
|
return Date.now();
|
|
792
795
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ErrorMode, ObjectWithId } from '@naturalcycles/js-lib';
|
|
1
|
+
import { CommonLogger, ErrorMode, ObjectWithId, Saved } 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';
|
|
@@ -34,11 +34,20 @@ export declare enum CommonDaoLogLevel {
|
|
|
34
34
|
* Same as undefined
|
|
35
35
|
*/
|
|
36
36
|
NONE = 0,
|
|
37
|
+
/**
|
|
38
|
+
* Log operations (e.g "getById returned 1 row"), but not data
|
|
39
|
+
*/
|
|
37
40
|
OPERATIONS = 10,
|
|
41
|
+
/**
|
|
42
|
+
* Log operations and data for single operations (e.g getById), but not batch operations.
|
|
43
|
+
*/
|
|
38
44
|
DATA_SINGLE = 20,
|
|
45
|
+
/**
|
|
46
|
+
* Log EVERYTHING - all data passing in and out (max 10 rows). Very verbose!
|
|
47
|
+
*/
|
|
39
48
|
DATA_FULL = 30
|
|
40
49
|
}
|
|
41
|
-
export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId
|
|
50
|
+
export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends ObjectWithId = Saved<BM>, TM = BM> {
|
|
42
51
|
db: CommonDB;
|
|
43
52
|
table: string;
|
|
44
53
|
/**
|
|
@@ -53,6 +62,10 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends Obje
|
|
|
53
62
|
* Set to true to limit DB writing (will throw an error is such case).
|
|
54
63
|
*/
|
|
55
64
|
readOnly?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Defaults to `console`
|
|
67
|
+
*/
|
|
68
|
+
logger?: CommonLogger;
|
|
56
69
|
/**
|
|
57
70
|
* @default OPERATIONS
|
|
58
71
|
*/
|
|
@@ -7,7 +7,16 @@ var CommonDaoLogLevel;
|
|
|
7
7
|
* Same as undefined
|
|
8
8
|
*/
|
|
9
9
|
CommonDaoLogLevel[CommonDaoLogLevel["NONE"] = 0] = "NONE";
|
|
10
|
+
/**
|
|
11
|
+
* Log operations (e.g "getById returned 1 row"), but not data
|
|
12
|
+
*/
|
|
10
13
|
CommonDaoLogLevel[CommonDaoLogLevel["OPERATIONS"] = 10] = "OPERATIONS";
|
|
14
|
+
/**
|
|
15
|
+
* Log operations and data for single operations (e.g getById), but not batch operations.
|
|
16
|
+
*/
|
|
11
17
|
CommonDaoLogLevel[CommonDaoLogLevel["DATA_SINGLE"] = 20] = "DATA_SINGLE";
|
|
18
|
+
/**
|
|
19
|
+
* Log EVERYTHING - all data passing in and out (max 10 rows). Very verbose!
|
|
20
|
+
*/
|
|
12
21
|
CommonDaoLogLevel[CommonDaoLogLevel["DATA_FULL"] = 30] = "DATA_FULL";
|
|
13
22
|
})(CommonDaoLogLevel = exports.CommonDaoLogLevel || (exports.CommonDaoLogLevel = {}));
|
|
@@ -8,7 +8,6 @@ const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
|
|
|
8
8
|
const time_lib_1 = require("@naturalcycles/time-lib");
|
|
9
9
|
const fs = require("fs-extra");
|
|
10
10
|
const index_1 = require("../index");
|
|
11
|
-
// const log = Debug('nc:db-lib:pipeline')
|
|
12
11
|
/**
|
|
13
12
|
* Pipeline from input stream(s) to a NDJSON file (optionally gzipped).
|
|
14
13
|
* File is overwritten (by default).
|
|
@@ -78,7 +78,7 @@ async function dbPipelineRestore(opt) {
|
|
|
78
78
|
...opt,
|
|
79
79
|
metric: table,
|
|
80
80
|
}),
|
|
81
|
-
(0, nodejs_lib_1.transformLimit)(limit),
|
|
81
|
+
(0, nodejs_lib_1.transformLimit)({ limit }),
|
|
82
82
|
...(sinceUpdated
|
|
83
83
|
? [(0, nodejs_lib_1.transformFilterSync)(r => r.updated >= sinceUpdated)]
|
|
84
84
|
: []),
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -295,11 +295,6 @@ Passing empty array will actually return an array of empty objects (documented e
|
|
|
295
295
|
.select(['id']) //=> [ { id: 'id1' }, { id: 'id2' }, ... ]
|
|
296
296
|
```
|
|
297
297
|
|
|
298
|
-
# DEBUG namespaces
|
|
299
|
-
|
|
300
|
-
- `nc:db-lib:commondao`
|
|
301
|
-
- `nc:db-lib:inmemorydb`
|
|
302
|
-
|
|
303
298
|
# Exports
|
|
304
299
|
|
|
305
300
|
- `/` root
|
|
@@ -315,6 +310,6 @@ Passing empty array will actually return an array of empty objects (documented e
|
|
|
315
310
|
# Packaging
|
|
316
311
|
|
|
317
312
|
- `engines.node >= LTS`
|
|
318
|
-
- `main: dist/index.js`: commonjs,
|
|
313
|
+
- `main: dist/index.js`: commonjs, es2020
|
|
319
314
|
- `types: dist/index.d.ts`: typescript types
|
|
320
315
|
- `/src` folder with source `*.ts` files included
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ObjectWithId } from '@naturalcycles/js-lib'
|
|
1
|
+
import { CommonLogger, ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
2
|
import { CommonDB } from '../../common.db'
|
|
3
3
|
import { CommonDBCreateOptions, CommonDBSaveOptions, CommonDBStreamOptions } from '../../db.model'
|
|
4
4
|
|
|
@@ -38,6 +38,11 @@ export interface CacheDBCfg {
|
|
|
38
38
|
* @default false
|
|
39
39
|
*/
|
|
40
40
|
logDownstream?: boolean
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Defaults to `console`.
|
|
44
|
+
*/
|
|
45
|
+
logger?: CommonLogger
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
export interface CacheDBOptions<ROW extends ObjectWithId> extends CommonDBSaveOptions<ROW> {
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
ObjectWithId,
|
|
6
6
|
StringMap,
|
|
7
7
|
} from '@naturalcycles/js-lib'
|
|
8
|
-
import { Debug, IDebugger } from '@naturalcycles/nodejs-lib'
|
|
9
8
|
import { BaseCommonDB } from '../../base.common.db'
|
|
10
9
|
import { CommonDB } from '../../common.db'
|
|
11
10
|
import { RunQueryResult } from '../../db.model'
|
|
@@ -24,12 +23,15 @@ import {
|
|
|
24
23
|
* Queries always hit downstream (unless `onlyCache` is passed)
|
|
25
24
|
*/
|
|
26
25
|
export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
27
|
-
constructor(
|
|
26
|
+
constructor(cfg: CacheDBCfg) {
|
|
28
27
|
super()
|
|
29
|
-
this.
|
|
28
|
+
this.cfg = {
|
|
29
|
+
logger: console,
|
|
30
|
+
...cfg,
|
|
31
|
+
}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
cfg: CacheDBCfg
|
|
33
35
|
|
|
34
36
|
override async ping(): Promise<void> {
|
|
35
37
|
await Promise.all([this.cfg.cacheDB.ping(), this.cfg.downstreamDB.ping()])
|
|
@@ -84,7 +86,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
84
86
|
missingIds.push(...ids.filter(id => !resultMap[id]))
|
|
85
87
|
|
|
86
88
|
if (this.cfg.logCached) {
|
|
87
|
-
this.log(
|
|
89
|
+
this.cfg.logger?.log(
|
|
88
90
|
`${table}.getByIds ${results.length} rows from cache: [${results
|
|
89
91
|
.map(r => r.id)
|
|
90
92
|
.join(', ')}]`,
|
|
@@ -97,7 +99,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
97
99
|
results.forEach(r => (resultMap[r.id] = r))
|
|
98
100
|
|
|
99
101
|
if (this.cfg.logDownstream) {
|
|
100
|
-
this.log(
|
|
102
|
+
this.cfg.logger?.log(
|
|
101
103
|
`${table}.getByIds ${results.length} rows from downstream: [${results
|
|
102
104
|
.map(r => r.id)
|
|
103
105
|
.join(', ')}]`,
|
|
@@ -125,14 +127,14 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
125
127
|
deletedIds = await this.cfg.downstreamDB.deleteByIds(table, ids, opt)
|
|
126
128
|
|
|
127
129
|
if (this.cfg.logDownstream) {
|
|
128
|
-
this.log(`${table}.deleteByIds ${deletedIds} rows from downstream`)
|
|
130
|
+
this.cfg.logger?.log(`${table}.deleteByIds ${deletedIds} rows from downstream`)
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
133
135
|
const cacheResult = this.cfg.cacheDB.deleteByIds(table, ids, opt).then(deletedFromCache => {
|
|
134
136
|
if (this.cfg.logCached) {
|
|
135
|
-
this.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`)
|
|
137
|
+
this.cfg.logger?.log(`${table}.deleteByIds ${deletedFromCache} rows from cache`)
|
|
136
138
|
}
|
|
137
139
|
})
|
|
138
140
|
if (this.cfg.awaitCache) await cacheResult
|
|
@@ -150,7 +152,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
150
152
|
await this.cfg.downstreamDB.saveBatch(table, rows, opt)
|
|
151
153
|
|
|
152
154
|
if (this.cfg.logDownstream) {
|
|
153
|
-
this.log(
|
|
155
|
+
this.cfg.logger?.log(
|
|
154
156
|
`${table}.saveBatch ${rows.length} rows to downstream: [${rows
|
|
155
157
|
.map(r => r.id)
|
|
156
158
|
.join(', ')}]`,
|
|
@@ -161,7 +163,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
161
163
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
162
164
|
const cacheResult = this.cfg.cacheDB.saveBatch(table, rows, opt).then(() => {
|
|
163
165
|
if (this.cfg.logCached) {
|
|
164
|
-
this.log(
|
|
166
|
+
this.cfg.logger?.log(
|
|
165
167
|
`${table}.saveBatch ${rows.length} rows to cache: [${rows.map(r => r.id).join(', ')}]`,
|
|
166
168
|
)
|
|
167
169
|
}
|
|
@@ -178,7 +180,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
178
180
|
const { rows, ...queryResult } = await this.cfg.downstreamDB.runQuery(q, opt)
|
|
179
181
|
|
|
180
182
|
if (this.cfg.logDownstream) {
|
|
181
|
-
this.log(`${q.table}.runQuery ${rows.length} rows from downstream`)
|
|
183
|
+
this.cfg.logger?.log(`${q.table}.runQuery ${rows.length} rows from downstream`)
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
// Don't save to cache if it was a projection query
|
|
@@ -194,7 +196,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
194
196
|
const { rows, ...queryResult } = await this.cfg.cacheDB.runQuery(q, opt)
|
|
195
197
|
|
|
196
198
|
if (this.cfg.logCached) {
|
|
197
|
-
this.log(`${q.table}.runQuery ${rows.length} rows from cache`)
|
|
199
|
+
this.cfg.logger?.log(`${q.table}.runQuery ${rows.length} rows from cache`)
|
|
198
200
|
}
|
|
199
201
|
|
|
200
202
|
return { rows, ...queryResult }
|
|
@@ -211,7 +213,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
211
213
|
const count = await this.cfg.cacheDB.runQueryCount(q, opt)
|
|
212
214
|
|
|
213
215
|
if (this.cfg.logCached) {
|
|
214
|
-
this.log(`${q.table}.runQueryCount ${count} rows from cache`)
|
|
216
|
+
this.cfg.logger?.log(`${q.table}.runQueryCount ${count} rows from cache`)
|
|
215
217
|
}
|
|
216
218
|
|
|
217
219
|
return count
|
|
@@ -264,7 +266,9 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
264
266
|
const deletedIds = await this.cfg.downstreamDB.deleteByQuery(q, opt)
|
|
265
267
|
|
|
266
268
|
if (this.cfg.logDownstream) {
|
|
267
|
-
this.log(
|
|
269
|
+
this.cfg.logger?.log(
|
|
270
|
+
`${q.table}.deleteByQuery ${deletedIds} rows from downstream and cache`,
|
|
271
|
+
)
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
if (!opt.skipCache && !this.cfg.skipCache) {
|
|
@@ -280,7 +284,7 @@ export class CacheDB extends BaseCommonDB implements CommonDB {
|
|
|
280
284
|
const deletedIds = await this.cfg.cacheDB.deleteByQuery(q, opt)
|
|
281
285
|
|
|
282
286
|
if (this.cfg.logCached) {
|
|
283
|
-
this.log(`${q.table}.deleteByQuery ${deletedIds} rows from cache`)
|
|
287
|
+
this.cfg.logger?.log(`${q.table}.deleteByQuery ${deletedIds} rows from cache`)
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
return deletedIds
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ObjectWithId } from '@naturalcycles/js-lib'
|
|
1
|
+
import { CommonLogger, ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
2
|
import { DBSaveBatchOperation } from '../../db.model'
|
|
3
3
|
import type { DBQueryOrder } from '../../query/dbQuery'
|
|
4
4
|
|
|
@@ -23,6 +23,11 @@ export interface FileDBCfg {
|
|
|
23
23
|
*/
|
|
24
24
|
sortObjects?: boolean
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Defaults to `console`.
|
|
28
|
+
*/
|
|
29
|
+
logger?: CommonLogger
|
|
30
|
+
|
|
26
31
|
/**
|
|
27
32
|
* @default false
|
|
28
33
|
*/
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
ObjectWithId,
|
|
15
15
|
AnyObjectWithId,
|
|
16
16
|
} from '@naturalcycles/js-lib'
|
|
17
|
-
import {
|
|
17
|
+
import { readableCreate, ReadableTyped } from '@naturalcycles/nodejs-lib'
|
|
18
18
|
import { dimGrey } from '@naturalcycles/nodejs-lib/dist/colors'
|
|
19
19
|
import { BaseCommonDB, DBSaveBatchOperation, queryInMemory } from '../..'
|
|
20
20
|
import { CommonDB } from '../../common.db'
|
|
@@ -28,8 +28,6 @@ import { DBQuery } from '../../query/dbQuery'
|
|
|
28
28
|
import { DBTransaction } from '../../transaction/dbTransaction'
|
|
29
29
|
import { FileDBCfg } from './file.db.model'
|
|
30
30
|
|
|
31
|
-
const log = Debug('nc:db-lib:filedb')
|
|
32
|
-
|
|
33
31
|
/**
|
|
34
32
|
* Provides barebone implementation for "whole file" based CommonDB.
|
|
35
33
|
* "whole file" means that the persistence layer doesn't allow any querying,
|
|
@@ -46,6 +44,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
46
44
|
this.cfg = {
|
|
47
45
|
sortObjects: true,
|
|
48
46
|
logFinished: true,
|
|
47
|
+
logger: console,
|
|
49
48
|
...cfg,
|
|
50
49
|
}
|
|
51
50
|
}
|
|
@@ -271,13 +270,13 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
271
270
|
|
|
272
271
|
private logStarted(op: string): number {
|
|
273
272
|
if (this.cfg.logStarted) {
|
|
274
|
-
log(`>> ${op}`)
|
|
273
|
+
this.cfg.logger?.log(`>> ${op}`)
|
|
275
274
|
}
|
|
276
275
|
return Date.now()
|
|
277
276
|
}
|
|
278
277
|
|
|
279
278
|
private logFinished(started: number, op: string): void {
|
|
280
279
|
if (!this.cfg.logFinished) return
|
|
281
|
-
log(`<< ${op} ${dimGrey(`in ${_since(started)}`)}`)
|
|
280
|
+
this.cfg.logger?.log(`<< ${op} ${dimGrey(`in ${_since(started)}`)}`)
|
|
282
281
|
}
|
|
283
282
|
}
|
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
JsonSchemaRootObject,
|
|
12
12
|
ObjectWithId,
|
|
13
13
|
_stringMapValues,
|
|
14
|
+
CommonLogger,
|
|
14
15
|
} from '@naturalcycles/js-lib'
|
|
15
16
|
import {
|
|
16
17
|
bufferReviver,
|
|
17
|
-
Debug,
|
|
18
18
|
ReadableTyped,
|
|
19
19
|
transformJsonParse,
|
|
20
20
|
transformSplit,
|
|
@@ -63,9 +63,12 @@ export interface InMemoryDBCfg {
|
|
|
63
63
|
* @default true
|
|
64
64
|
*/
|
|
65
65
|
persistZip: boolean
|
|
66
|
-
}
|
|
67
66
|
|
|
68
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Defaults to `console`.
|
|
69
|
+
*/
|
|
70
|
+
logger?: CommonLogger
|
|
71
|
+
}
|
|
69
72
|
|
|
70
73
|
export class InMemoryDB implements CommonDB {
|
|
71
74
|
constructor(cfg?: Partial<InMemoryDBCfg>) {
|
|
@@ -75,6 +78,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
75
78
|
persistenceEnabled: false,
|
|
76
79
|
persistZip: true,
|
|
77
80
|
persistentStoragePath: './tmp/inmemorydb',
|
|
81
|
+
logger: console,
|
|
78
82
|
...cfg,
|
|
79
83
|
}
|
|
80
84
|
}
|
|
@@ -100,13 +104,13 @@ export class InMemoryDB implements CommonDB {
|
|
|
100
104
|
async resetCache(_table?: string): Promise<void> {
|
|
101
105
|
if (_table) {
|
|
102
106
|
const table = this.cfg.tablesPrefix + _table
|
|
103
|
-
log(`reset ${table}`)
|
|
107
|
+
this.cfg.logger?.log(`reset ${table}`)
|
|
104
108
|
this.data[table] = {}
|
|
105
109
|
} else {
|
|
106
110
|
;(await this.getTables()).forEach(table => {
|
|
107
111
|
this.data[table] = {}
|
|
108
112
|
})
|
|
109
|
-
log('reset')
|
|
113
|
+
this.cfg.logger?.log('reset')
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
|
|
@@ -157,7 +161,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
157
161
|
|
|
158
162
|
rows.forEach(r => {
|
|
159
163
|
if (!r.id) {
|
|
160
|
-
|
|
164
|
+
this.cfg.logger?.warn({ rows })
|
|
161
165
|
throw new Error(`InMemoryDB: id doesn't exist for row`)
|
|
162
166
|
}
|
|
163
167
|
|
|
@@ -266,7 +270,9 @@ export class InMemoryDB implements CommonDB {
|
|
|
266
270
|
])
|
|
267
271
|
})
|
|
268
272
|
|
|
269
|
-
log(
|
|
273
|
+
this.cfg.logger?.log(
|
|
274
|
+
`flushToDisk took ${dimGrey(_since(started))} to save ${yellow(tables)} tables`,
|
|
275
|
+
)
|
|
270
276
|
}
|
|
271
277
|
|
|
272
278
|
/**
|
|
@@ -306,6 +312,8 @@ export class InMemoryDB implements CommonDB {
|
|
|
306
312
|
this.data[table] = _by(rows, r => r.id)
|
|
307
313
|
})
|
|
308
314
|
|
|
309
|
-
log(
|
|
315
|
+
this.cfg.logger?.log(
|
|
316
|
+
`restoreFromDisk took ${dimGrey(_since(started))} to read ${yellow(files.length)} tables`,
|
|
317
|
+
)
|
|
310
318
|
}
|
|
311
319
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ErrorMode, ObjectWithId } from '@naturalcycles/js-lib'
|
|
1
|
+
import { CommonLogger, ErrorMode, ObjectWithId, Saved } from '@naturalcycles/js-lib'
|
|
2
2
|
import {
|
|
3
3
|
AjvSchema,
|
|
4
4
|
AjvValidationError,
|
|
@@ -46,12 +46,25 @@ export enum CommonDaoLogLevel {
|
|
|
46
46
|
* Same as undefined
|
|
47
47
|
*/
|
|
48
48
|
NONE = 0,
|
|
49
|
+
/**
|
|
50
|
+
* Log operations (e.g "getById returned 1 row"), but not data
|
|
51
|
+
*/
|
|
49
52
|
OPERATIONS = 10,
|
|
53
|
+
/**
|
|
54
|
+
* Log operations and data for single operations (e.g getById), but not batch operations.
|
|
55
|
+
*/
|
|
50
56
|
DATA_SINGLE = 20,
|
|
57
|
+
/**
|
|
58
|
+
* Log EVERYTHING - all data passing in and out (max 10 rows). Very verbose!
|
|
59
|
+
*/
|
|
51
60
|
DATA_FULL = 30,
|
|
52
61
|
}
|
|
53
62
|
|
|
54
|
-
export interface CommonDaoCfg<
|
|
63
|
+
export interface CommonDaoCfg<
|
|
64
|
+
BM extends Partial<ObjectWithId>,
|
|
65
|
+
DBM extends ObjectWithId = Saved<BM>,
|
|
66
|
+
TM = BM,
|
|
67
|
+
> {
|
|
55
68
|
db: CommonDB
|
|
56
69
|
table: string
|
|
57
70
|
|
|
@@ -70,6 +83,11 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId>, DBM extends Obje
|
|
|
70
83
|
*/
|
|
71
84
|
readOnly?: boolean
|
|
72
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Defaults to `console`
|
|
88
|
+
*/
|
|
89
|
+
logger?: CommonLogger
|
|
90
|
+
|
|
73
91
|
/**
|
|
74
92
|
* @default OPERATIONS
|
|
75
93
|
*/
|
|
@@ -1,36 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
|
+
_filterNullishValues,
|
|
3
|
+
_filterUndefinedValues,
|
|
4
|
+
_passthroughPredicate,
|
|
5
|
+
_since,
|
|
6
|
+
_truncate,
|
|
7
|
+
_uniqBy,
|
|
2
8
|
AppError,
|
|
3
9
|
AsyncMapper,
|
|
4
10
|
ErrorMode,
|
|
5
11
|
JsonSchemaObject,
|
|
6
|
-
_passthroughPredicate,
|
|
7
|
-
_since,
|
|
8
|
-
_truncate,
|
|
9
|
-
pMap,
|
|
10
12
|
JsonSchemaRootObject,
|
|
11
|
-
Saved,
|
|
12
|
-
_uniqBy,
|
|
13
13
|
ObjectWithId,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
pMap,
|
|
15
|
+
Saved,
|
|
16
16
|
} from '@naturalcycles/js-lib'
|
|
17
17
|
import {
|
|
18
|
+
_pipeline,
|
|
18
19
|
AjvSchema,
|
|
19
20
|
AjvValidationError,
|
|
20
|
-
Debug,
|
|
21
21
|
getValidationResult,
|
|
22
22
|
JoiValidationError,
|
|
23
23
|
ObjectSchemaTyped,
|
|
24
24
|
ReadableTyped,
|
|
25
25
|
stringId,
|
|
26
|
+
transformBuffer,
|
|
26
27
|
transformLogProgress,
|
|
27
28
|
transformMap,
|
|
28
29
|
transformMapSimple,
|
|
29
30
|
transformMapSync,
|
|
30
31
|
transformTap,
|
|
31
32
|
writableVoid,
|
|
32
|
-
_pipeline,
|
|
33
|
-
transformBuffer,
|
|
34
33
|
} from '@naturalcycles/nodejs-lib'
|
|
35
34
|
import { DBLibError } from '../cnst'
|
|
36
35
|
import { DBModelType, RunQueryResult } from '../db.model'
|
|
@@ -45,10 +44,11 @@ import {
|
|
|
45
44
|
CommonDaoStreamOptions,
|
|
46
45
|
} from './common.dao.model'
|
|
47
46
|
|
|
48
|
-
const log = Debug('nc:db-lib:commondao')
|
|
49
|
-
|
|
50
47
|
/* eslint-disable no-dupe-class-members */
|
|
51
48
|
|
|
49
|
+
const isGAE = !!process.env['GAE_INSTANCE']
|
|
50
|
+
const isCI = !!process.env['CI']
|
|
51
|
+
|
|
52
52
|
/**
|
|
53
53
|
* Lowest common denominator API between supported Databases.
|
|
54
54
|
*
|
|
@@ -63,8 +63,12 @@ export class CommonDao<
|
|
|
63
63
|
> {
|
|
64
64
|
constructor(public cfg: CommonDaoCfg<BM, DBM, TM>) {
|
|
65
65
|
this.cfg = {
|
|
66
|
-
|
|
66
|
+
// Default is to NOT log in AppEngine and in CI,
|
|
67
|
+
// otherwise to log Operations
|
|
68
|
+
// e.g in Dev (local machine), Test - it will log operations (useful for debugging)
|
|
69
|
+
logLevel: isGAE || isCI ? CommonDaoLogLevel.NONE : CommonDaoLogLevel.OPERATIONS,
|
|
67
70
|
createdUpdated: true,
|
|
71
|
+
logger: console,
|
|
68
72
|
...cfg,
|
|
69
73
|
hooks: {
|
|
70
74
|
createId: () => stringId(),
|
|
@@ -323,7 +327,7 @@ export class CommonDao<
|
|
|
323
327
|
const started = this.logStarted(op, q.table)
|
|
324
328
|
const count = await this.cfg.db.runQueryCount(q, opt)
|
|
325
329
|
if (this.cfg.logLevel! >= CommonDaoLogLevel.OPERATIONS) {
|
|
326
|
-
log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`)
|
|
330
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`)
|
|
327
331
|
}
|
|
328
332
|
return count
|
|
329
333
|
}
|
|
@@ -369,7 +373,7 @@ export class CommonDao<
|
|
|
369
373
|
])
|
|
370
374
|
|
|
371
375
|
if (this.cfg.logLevel! >= CommonDaoLogLevel.OPERATIONS) {
|
|
372
|
-
log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`)
|
|
376
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`)
|
|
373
377
|
}
|
|
374
378
|
}
|
|
375
379
|
|
|
@@ -412,7 +416,7 @@ export class CommonDao<
|
|
|
412
416
|
])
|
|
413
417
|
|
|
414
418
|
if (this.cfg.logLevel! >= CommonDaoLogLevel.OPERATIONS) {
|
|
415
|
-
log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`)
|
|
419
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} row(s) in ${_since(started)}`)
|
|
416
420
|
}
|
|
417
421
|
}
|
|
418
422
|
|
|
@@ -518,7 +522,7 @@ export class CommonDao<
|
|
|
518
522
|
])
|
|
519
523
|
|
|
520
524
|
if (this.cfg.logLevel! >= CommonDaoLogLevel.OPERATIONS) {
|
|
521
|
-
log(`<< ${q.table}.${op}: ${count} id(s) in ${_since(started)}`)
|
|
525
|
+
this.cfg.logger?.log(`<< ${q.table}.${op}: ${count} id(s) in ${_since(started)}`)
|
|
522
526
|
}
|
|
523
527
|
}
|
|
524
528
|
|
|
@@ -899,9 +903,9 @@ export class CommonDao<
|
|
|
899
903
|
* Does NOT mutate the object.
|
|
900
904
|
*/
|
|
901
905
|
validateAndConvert<IN, OUT = IN>(
|
|
902
|
-
obj: IN
|
|
903
|
-
schema
|
|
904
|
-
modelType
|
|
906
|
+
obj: Partial<IN>,
|
|
907
|
+
schema: ObjectSchemaTyped<IN> | AjvSchema<IN> | undefined,
|
|
908
|
+
modelType: DBModelType,
|
|
905
909
|
opt: CommonDaoOptions = {},
|
|
906
910
|
): OUT {
|
|
907
911
|
// `raw` option completely bypasses any processing
|
|
@@ -924,12 +928,12 @@ export class CommonDao<
|
|
|
924
928
|
|
|
925
929
|
// Pre-validation hooks
|
|
926
930
|
if (modelType === DBModelType.DBM) {
|
|
927
|
-
obj = this.cfg.hooks!.beforeDBMValidate!(obj as any) as
|
|
931
|
+
obj = this.cfg.hooks!.beforeDBMValidate!(obj as any) as IN
|
|
928
932
|
}
|
|
929
933
|
|
|
930
934
|
// Return as is if no schema is passed or if `skipConversion` is set
|
|
931
935
|
if (!schema || opt.skipConversion) {
|
|
932
|
-
return obj as
|
|
936
|
+
return obj as OUT
|
|
933
937
|
}
|
|
934
938
|
|
|
935
939
|
// This will Convert and Validate
|
|
@@ -943,12 +947,12 @@ export class CommonDao<
|
|
|
943
947
|
// Ajv schema
|
|
944
948
|
convertedValue = obj // because Ajv mutates original object
|
|
945
949
|
|
|
946
|
-
error = schema.getValidationError(obj, {
|
|
950
|
+
error = schema.getValidationError(obj as IN, {
|
|
947
951
|
objectName,
|
|
948
952
|
})
|
|
949
953
|
} else {
|
|
950
954
|
// Joi
|
|
951
|
-
const vr = getValidationResult<IN, OUT>(obj, schema, objectName)
|
|
955
|
+
const vr = getValidationResult<IN, OUT>(obj as IN, schema, objectName)
|
|
952
956
|
error = vr.error
|
|
953
957
|
convertedValue = vr.value
|
|
954
958
|
}
|
|
@@ -979,8 +983,6 @@ export class CommonDao<
|
|
|
979
983
|
await this.cfg.db.ping()
|
|
980
984
|
}
|
|
981
985
|
|
|
982
|
-
// todo: logging
|
|
983
|
-
// todo: bmToDBM, etc. How?
|
|
984
986
|
// transaction(): DBTransaction {
|
|
985
987
|
// return this.cfg.db.transaction()
|
|
986
988
|
// }
|
|
@@ -994,7 +996,7 @@ export class CommonDao<
|
|
|
994
996
|
if (Array.isArray(res)) {
|
|
995
997
|
logRes = `${res.length} row(s)`
|
|
996
998
|
if (res.length && this.cfg.logLevel >= CommonDaoLogLevel.DATA_FULL) {
|
|
997
|
-
args.push('\n', res.slice(0, 10)) // max 10 items
|
|
999
|
+
args.push('\n', ...res.slice(0, 10)) // max 10 items
|
|
998
1000
|
}
|
|
999
1001
|
} else if (res) {
|
|
1000
1002
|
logRes = `1 row`
|
|
@@ -1005,17 +1007,17 @@ export class CommonDao<
|
|
|
1005
1007
|
logRes = `undefined`
|
|
1006
1008
|
}
|
|
1007
1009
|
|
|
1008
|
-
log(
|
|
1010
|
+
this.cfg.logger?.log(`<< ${table}.${op}: ${logRes} in ${_since(started)}`, ...args)
|
|
1009
1011
|
}
|
|
1010
1012
|
|
|
1011
1013
|
protected logSaveResult(started: number, op: string, table: string): void {
|
|
1012
1014
|
if (!this.cfg.logLevel) return
|
|
1013
|
-
log(`<< ${table}.${op} in ${_since(started)}`)
|
|
1015
|
+
this.cfg.logger?.log(`<< ${table}.${op} in ${_since(started)}`)
|
|
1014
1016
|
}
|
|
1015
1017
|
|
|
1016
1018
|
protected logStarted(op: string, table: string, force = false): number {
|
|
1017
1019
|
if (this.cfg.logStarted || force) {
|
|
1018
|
-
log(`>> ${table}.${op}`)
|
|
1020
|
+
this.cfg.logger?.log(`>> ${table}.${op}`)
|
|
1019
1021
|
}
|
|
1020
1022
|
return Date.now()
|
|
1021
1023
|
}
|
|
@@ -1035,7 +1037,7 @@ export class CommonDao<
|
|
|
1035
1037
|
}
|
|
1036
1038
|
}
|
|
1037
1039
|
|
|
1038
|
-
log(...args)
|
|
1040
|
+
this.cfg.logger?.log(...args)
|
|
1039
1041
|
}
|
|
1040
1042
|
|
|
1041
1043
|
return Date.now()
|
|
@@ -115,8 +115,6 @@ export interface DBPipelineBackupOptions extends TransformLogProgressOptions {
|
|
|
115
115
|
sortObjects?: boolean
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
// const log = Debug('nc:db-lib:pipeline')
|
|
119
|
-
|
|
120
118
|
/**
|
|
121
119
|
* Pipeline from input stream(s) to a NDJSON file (optionally gzipped).
|
|
122
120
|
* File is overwritten (by default).
|
|
@@ -209,7 +209,7 @@ export async function dbPipelineRestore(opt: DBPipelineRestoreOptions): Promise<
|
|
|
209
209
|
...opt,
|
|
210
210
|
metric: table,
|
|
211
211
|
}),
|
|
212
|
-
transformLimit(limit),
|
|
212
|
+
transformLimit({ limit }),
|
|
213
213
|
...(sinceUpdated
|
|
214
214
|
? [transformFilterSync<SavedDBEntity>(r => r.updated >= sinceUpdated)]
|
|
215
215
|
: []),
|