@naturalcycles/db-lib 10.4.1 → 10.6.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.js +2 -2
- package/dist/adapter/file/localFile.persistence.plugin.js +4 -4
- package/dist/adapter/inmemory/inMemory.db.js +5 -5
- package/dist/commondao/common.dao.d.ts +4 -4
- package/dist/kv/commonKeyValueDao.js +1 -1
- package/dist/pipeline/dbPipelineBackup.d.ts +1 -1
- package/dist/pipeline/dbPipelineBackup.js +4 -3
- package/dist/pipeline/dbPipelineCopy.js +1 -1
- package/dist/pipeline/dbPipelineRestore.d.ts +1 -1
- package/dist/pipeline/dbPipelineRestore.js +4 -3
- package/dist/query/dbQuery.d.ts +4 -4
- package/dist/testing/keyValueDBTest.js +1 -1
- package/dist/testing/keyValueDaoTest.js +1 -1
- package/package.json +2 -2
- package/src/adapter/file/file.db.ts +2 -2
- package/src/adapter/file/localFile.persistence.plugin.ts +8 -4
- package/src/adapter/inmemory/inMemory.db.ts +11 -5
- package/src/commondao/common.dao.ts +4 -4
- package/src/kv/commonKeyValueDao.ts +1 -1
- package/src/pipeline/dbPipelineBackup.ts +7 -6
- package/src/pipeline/dbPipelineCopy.ts +1 -1
- package/src/pipeline/dbPipelineRestore.ts +7 -6
- package/src/query/dbQuery.ts +4 -4
- package/src/testing/keyValueDBTest.ts +1 -1
- package/src/testing/keyValueDaoTest.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _assert, _by, _deepEquals, _filterUndefinedValues, _since, _sortBy, _sortObjectDeep, _stringMapValues, generateJsonSchemaFromData, localTime, } from '@naturalcycles/js-lib';
|
|
2
|
-
import { dimGrey } from '@naturalcycles/nodejs-lib';
|
|
2
|
+
import { dimGrey } from '@naturalcycles/nodejs-lib/colors';
|
|
3
3
|
import { readableCreate } from '@naturalcycles/nodejs-lib/stream';
|
|
4
4
|
import { BaseCommonDB } from '../../base.common.db.js';
|
|
5
5
|
import { commonDBFullSupport } from '../../common.db.js';
|
|
@@ -148,7 +148,7 @@ export class FileDB extends BaseCommonDB {
|
|
|
148
148
|
sortRows(rows) {
|
|
149
149
|
rows = rows.map(r => _filterUndefinedValues(r));
|
|
150
150
|
if (this.cfg.sortOnSave) {
|
|
151
|
-
_sortBy(rows, r => r[this.cfg.sortOnSave.name], true);
|
|
151
|
+
_sortBy(rows, r => r[this.cfg.sortOnSave.name], { mutate: true });
|
|
152
152
|
if (this.cfg.sortOnSave.descending)
|
|
153
153
|
rows.reverse(); // mutates
|
|
154
154
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { pMap } from '@naturalcycles/js-lib';
|
|
3
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
4
|
-
import { _pipeline } from '@naturalcycles/nodejs-lib/stream';
|
|
3
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
4
|
+
import { _pipeline, createReadStreamAsNDJSON, createWriteStreamAsNDJSON, } from '@naturalcycles/nodejs-lib/stream';
|
|
5
5
|
/**
|
|
6
6
|
* Persists in local filesystem as ndjson.
|
|
7
7
|
*/
|
|
@@ -26,7 +26,7 @@ export class LocalFilePersistencePlugin {
|
|
|
26
26
|
const filePath = `${this.cfg.storagePath}/${table}.${ext}`;
|
|
27
27
|
if (!(await fs2.pathExistsAsync(filePath)))
|
|
28
28
|
return [];
|
|
29
|
-
return await
|
|
29
|
+
return await createReadStreamAsNDJSON(filePath).toArray();
|
|
30
30
|
}
|
|
31
31
|
async saveFiles(ops) {
|
|
32
32
|
await pMap(ops, async (op) => await this.saveFile(op.table, op.rows), { concurrency: 32 });
|
|
@@ -35,6 +35,6 @@ export class LocalFilePersistencePlugin {
|
|
|
35
35
|
await fs2.ensureDirAsync(this.cfg.storagePath);
|
|
36
36
|
const ext = `ndjson${this.cfg.gzip ? '.gz' : ''}`;
|
|
37
37
|
const filePath = `${this.cfg.storagePath}/${table}.${ext}`;
|
|
38
|
-
await _pipeline([Readable.from(rows), ...
|
|
38
|
+
await _pipeline([Readable.from(rows), ...createWriteStreamAsNDJSON(filePath)]);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Readable } from 'node:stream';
|
|
2
2
|
import { _assert, _by, _deepCopy, _isEmptyObject, _since, _sortObjectDeep, _stringMapEntries, _stringMapValues, generateJsonSchemaFromData, localTime, pMap, } from '@naturalcycles/js-lib';
|
|
3
|
-
import { dimGrey, yellow } from '@naturalcycles/nodejs-lib';
|
|
4
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
5
|
-
import { _pipeline, bufferReviver } from '@naturalcycles/nodejs-lib/stream';
|
|
3
|
+
import { dimGrey, yellow } from '@naturalcycles/nodejs-lib/colors';
|
|
4
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
5
|
+
import { _pipeline, bufferReviver, createReadStreamAsNDJSON, createWriteStreamAsNDJSON, } from '@naturalcycles/nodejs-lib/stream';
|
|
6
6
|
import { commonDBFullSupport, CommonDBType } from '../../common.db.js';
|
|
7
7
|
import { queryInMemory } from './queryInMemory.js';
|
|
8
8
|
export class InMemoryDB {
|
|
@@ -183,7 +183,7 @@ export class InMemoryDB {
|
|
|
183
183
|
return; // 0 rows
|
|
184
184
|
tables++;
|
|
185
185
|
const fname = `${persistentStoragePath}/${table}.ndjson${persistZip ? '.gz' : ''}`;
|
|
186
|
-
await _pipeline([Readable.from(rows), ...
|
|
186
|
+
await _pipeline([Readable.from(rows), ...createWriteStreamAsNDJSON(fname)]);
|
|
187
187
|
});
|
|
188
188
|
this.cfg.logger.log(`flushToDisk took ${dimGrey(_since(started))} to save ${yellow(tables)} tables`);
|
|
189
189
|
}
|
|
@@ -201,7 +201,7 @@ export class InMemoryDB {
|
|
|
201
201
|
await pMap(files, async (file) => {
|
|
202
202
|
const fname = `${persistentStoragePath}/${file}`;
|
|
203
203
|
const table = file.split('.ndjson')[0];
|
|
204
|
-
const rows = await
|
|
204
|
+
const rows = await createReadStreamAsNDJSON(fname).toArray();
|
|
205
205
|
this.data[table] = _by(rows, r => r.id);
|
|
206
206
|
});
|
|
207
207
|
this.cfg.logger.log(`restoreFromDisk took ${dimGrey(_since(started))} to read ${yellow(files.length)} tables`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Transform } from 'node:stream';
|
|
2
|
-
import type {
|
|
2
|
+
import type { AsyncIndexedMapper, BaseDBEntity, CommonLogger, JsonSchemaObject, JsonSchemaRootObject, StringMap, UnixTimestampMillis, Unsaved } from '@naturalcycles/js-lib';
|
|
3
3
|
import { ZodType } from '@naturalcycles/js-lib/zod';
|
|
4
4
|
import { AjvSchema } from '@naturalcycles/nodejs-lib/ajv';
|
|
5
5
|
import { type ObjectSchema } from '@naturalcycles/nodejs-lib/joi';
|
|
@@ -55,8 +55,8 @@ export declare class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity
|
|
|
55
55
|
runQueryAsDBM(q: DBQuery<DBM>, opt?: CommonDaoReadOptions): Promise<DBM[]>;
|
|
56
56
|
runQueryExtendedAsDBM(q: DBQuery<DBM>, opt?: CommonDaoReadOptions): Promise<RunQueryResult<DBM>>;
|
|
57
57
|
runQueryCount(q: DBQuery<DBM>, opt?: CommonDaoReadOptions): Promise<number>;
|
|
58
|
-
streamQueryForEach(q: DBQuery<DBM>, mapper:
|
|
59
|
-
streamQueryAsDBMForEach(q: DBQuery<DBM>, mapper:
|
|
58
|
+
streamQueryForEach(q: DBQuery<DBM>, mapper: AsyncIndexedMapper<BM, void>, opt?: CommonDaoStreamForEachOptions<BM>): Promise<void>;
|
|
59
|
+
streamQueryAsDBMForEach(q: DBQuery<DBM>, mapper: AsyncIndexedMapper<DBM, void>, opt?: CommonDaoStreamForEachOptions<DBM>): Promise<void>;
|
|
60
60
|
/**
|
|
61
61
|
* Stream as Readable, to be able to .pipe() it further with support of backpressure.
|
|
62
62
|
*/
|
|
@@ -73,7 +73,7 @@ export declare class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity
|
|
|
73
73
|
streamQuery(q: DBQuery<DBM>, opt?: CommonDaoStreamOptions<BM>): ReadableTyped<BM>;
|
|
74
74
|
queryIds(q: DBQuery<DBM>, opt?: CommonDaoReadOptions): Promise<ID[]>;
|
|
75
75
|
streamQueryIds(q: DBQuery<DBM>, opt?: CommonDaoStreamOptions<ID>): ReadableTyped<ID>;
|
|
76
|
-
streamQueryIdsForEach(q: DBQuery<DBM>, mapper:
|
|
76
|
+
streamQueryIdsForEach(q: DBQuery<DBM>, mapper: AsyncIndexedMapper<ID, void>, opt?: CommonDaoStreamForEachOptions<ID>): Promise<void>;
|
|
77
77
|
/**
|
|
78
78
|
* Mutates!
|
|
79
79
|
* "Returns", just to have a type of "Saved"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppError, pMap } from '@naturalcycles/js-lib';
|
|
2
|
-
import { deflateString, inflateToString } from '@naturalcycles/nodejs-lib';
|
|
2
|
+
import { deflateString, inflateToString } from '@naturalcycles/nodejs-lib/zip';
|
|
3
3
|
export const commonKeyValueDaoDeflatedJsonTransformer = {
|
|
4
4
|
valueToBuffer: async (v) => await deflateString(JSON.stringify(v)),
|
|
5
5
|
bufferToValue: async (buf) => JSON.parse(await inflateToString(buf)),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AsyncMapper, StringMap, UnixTimestamp } from '@naturalcycles/js-lib';
|
|
2
2
|
import { ErrorMode } from '@naturalcycles/js-lib';
|
|
3
|
-
import type
|
|
3
|
+
import { type TransformLogProgressOptions, type TransformMapOptions } from '@naturalcycles/nodejs-lib/stream';
|
|
4
4
|
import { NDJsonStats } from '@naturalcycles/nodejs-lib/stream';
|
|
5
5
|
import type { CommonDB } from '../common.db.js';
|
|
6
6
|
import { DBQuery } from '../query/dbQuery.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _passthroughMapper, AppError, ErrorMode, localTime, pMap } from '@naturalcycles/js-lib';
|
|
2
|
-
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib';
|
|
3
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
2
|
+
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/colors';
|
|
3
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
4
|
+
import { createWriteStreamAsNDJSON, } from '@naturalcycles/nodejs-lib/stream';
|
|
4
5
|
import { _pipeline, NDJsonStats, transformLogProgress, transformMap, transformTap, } from '@naturalcycles/nodejs-lib/stream';
|
|
5
6
|
import { DBQuery } from '../query/dbQuery.js';
|
|
6
7
|
/**
|
|
@@ -68,7 +69,7 @@ export async function dbPipelineBackup(opt) {
|
|
|
68
69
|
transformTap(() => {
|
|
69
70
|
rows++;
|
|
70
71
|
}),
|
|
71
|
-
...
|
|
72
|
+
...createWriteStreamAsNDJSON(filePath),
|
|
72
73
|
]);
|
|
73
74
|
const { size: sizeBytes } = await fs2.statAsync(filePath);
|
|
74
75
|
const stats = NDJsonStats.create({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _passthroughMapper, ErrorMode, localTime, pMap } from '@naturalcycles/js-lib';
|
|
2
|
-
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib';
|
|
2
|
+
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/colors';
|
|
3
3
|
import { _pipeline, NDJsonStats, transformChunk, transformLogProgress, transformMap, transformTap, writableForEach, } from '@naturalcycles/nodejs-lib/stream';
|
|
4
4
|
import { DBQuery } from '../query/dbQuery.js';
|
|
5
5
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AsyncMapper, UnixTimestamp } from '@naturalcycles/js-lib';
|
|
2
2
|
import { ErrorMode } from '@naturalcycles/js-lib';
|
|
3
|
-
import type
|
|
3
|
+
import { type TransformLogProgressOptions, type TransformMapOptions } from '@naturalcycles/nodejs-lib/stream';
|
|
4
4
|
import { NDJsonStats } from '@naturalcycles/nodejs-lib/stream';
|
|
5
5
|
import type { CommonDB } from '../common.db.js';
|
|
6
6
|
import type { CommonDBSaveOptions } from '../db.model.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { _hb, _mapValues, _passthroughMapper, ErrorMode, localTime, pMap, } from '@naturalcycles/js-lib';
|
|
2
|
-
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib';
|
|
3
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
2
|
+
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/colors';
|
|
3
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
|
|
4
|
+
import { createReadStreamAsNDJSON, } from '@naturalcycles/nodejs-lib/stream';
|
|
4
5
|
import { _pipeline, NDJsonStats, transformChunk, transformFilterSync, transformLogProgress, transformMap, transformTap, writableForEach, } from '@naturalcycles/nodejs-lib/stream';
|
|
5
6
|
/**
|
|
6
7
|
* Pipeline from NDJSON files in a folder (optionally gzipped) to CommonDB.
|
|
@@ -62,7 +63,7 @@ export async function dbPipelineRestore(opt) {
|
|
|
62
63
|
const sizeBytes = sizeByTable[table];
|
|
63
64
|
console.log(`<< ${grey(filePath)} ${dimWhite(_hb(sizeBytes))} started...`);
|
|
64
65
|
await _pipeline([
|
|
65
|
-
|
|
66
|
+
createReadStreamAsNDJSON(filePath).take(limit || Number.POSITIVE_INFINITY),
|
|
66
67
|
transformTap(() => rows++),
|
|
67
68
|
transformLogProgress({
|
|
68
69
|
logEvery: 1000,
|
package/dist/query/dbQuery.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AsyncIndexedMapper, BaseDBEntity, ObjectWithId } from '@naturalcycles/js-lib';
|
|
2
2
|
import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream';
|
|
3
3
|
import type { CommonDao } from '../commondao/common.dao.js';
|
|
4
4
|
import type { CommonDaoOptions, CommonDaoReadOptions, CommonDaoStreamDeleteOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions } from '../commondao/common.dao.model.js';
|
|
@@ -100,12 +100,12 @@ export declare class RunnableDBQuery<BM extends BaseDBEntity, DBM extends BaseDB
|
|
|
100
100
|
runQueryExtendedAsDBM(opt?: CommonDaoReadOptions): Promise<RunQueryResult<DBM>>;
|
|
101
101
|
runQueryCount(opt?: CommonDaoReadOptions): Promise<number>;
|
|
102
102
|
patchByQuery(patch: Partial<DBM>, opt?: CommonDaoOptions): Promise<number>;
|
|
103
|
-
streamQueryForEach(mapper:
|
|
104
|
-
streamQueryAsDBMForEach(mapper:
|
|
103
|
+
streamQueryForEach(mapper: AsyncIndexedMapper<BM, void>, opt?: CommonDaoStreamForEachOptions<BM>): Promise<void>;
|
|
104
|
+
streamQueryAsDBMForEach(mapper: AsyncIndexedMapper<DBM, void>, opt?: CommonDaoStreamForEachOptions<DBM>): Promise<void>;
|
|
105
105
|
streamQuery(opt?: CommonDaoStreamOptions<BM>): ReadableTyped<BM>;
|
|
106
106
|
streamQueryAsDBM(opt?: CommonDaoStreamOptions<DBM>): ReadableTyped<DBM>;
|
|
107
107
|
queryIds(opt?: CommonDaoReadOptions): Promise<ID[]>;
|
|
108
108
|
streamQueryIds(opt?: CommonDaoStreamOptions<ID>): ReadableTyped<ID>;
|
|
109
|
-
streamQueryIdsForEach(mapper:
|
|
109
|
+
streamQueryIdsForEach(mapper: AsyncIndexedMapper<ID, void>, opt?: CommonDaoStreamForEachOptions<ID>): Promise<void>;
|
|
110
110
|
deleteByQuery(opt?: CommonDaoStreamDeleteOptions<DBM>): Promise<number>;
|
|
111
111
|
}
|
|
@@ -39,7 +39,7 @@ export async function runCommonKeyValueDBTest(db) {
|
|
|
39
39
|
test('saveBatch, then getByIds', async () => {
|
|
40
40
|
await db.saveBatch(TEST_TABLE, testEntries);
|
|
41
41
|
const entries = await db.getByIds(TEST_TABLE, testIds);
|
|
42
|
-
_sortBy(entries, e => e[0], true);
|
|
42
|
+
_sortBy(entries, e => e[0], { mutate: true });
|
|
43
43
|
expect(entries).toEqual(testEntries);
|
|
44
44
|
});
|
|
45
45
|
if (support.count) {
|
|
@@ -41,7 +41,7 @@ export async function runCommonKeyValueDaoTest(db) {
|
|
|
41
41
|
await dao.saveBatch(testEntries);
|
|
42
42
|
const entries = await dao.getByIds(testIds);
|
|
43
43
|
// console.log(typeof entries[0]![1], entries[0]![1])
|
|
44
|
-
_sortBy(entries, e => e[0], true);
|
|
44
|
+
_sortBy(entries, e => e[0], { mutate: true });
|
|
45
45
|
expect(entries).toEqual(testEntries); // Jest doesn't allow to compare Buffers directly
|
|
46
46
|
// expect(entries.map(e => e[0])).toEqual(testEntries.map(e => e[0]))
|
|
47
47
|
// expect(entries.map(e => e[1].toString())).toEqual(testEntries.map(e => e[1].toString()))
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/db-lib",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "10.
|
|
4
|
+
"version": "10.6.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@naturalcycles/js-lib": "^15",
|
|
7
7
|
"@naturalcycles/nodejs-lib": "^15"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
|
-
"@naturalcycles/dev-lib": "19.
|
|
10
|
+
"@naturalcycles/dev-lib": "19.6.0"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
generateJsonSchemaFromData,
|
|
12
12
|
localTime,
|
|
13
13
|
} from '@naturalcycles/js-lib'
|
|
14
|
-
import { dimGrey } from '@naturalcycles/nodejs-lib'
|
|
14
|
+
import { dimGrey } from '@naturalcycles/nodejs-lib/colors'
|
|
15
15
|
import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream'
|
|
16
16
|
import { readableCreate } from '@naturalcycles/nodejs-lib/stream'
|
|
17
17
|
import { BaseCommonDB } from '../../base.common.db.js'
|
|
@@ -228,7 +228,7 @@ export class FileDB extends BaseCommonDB implements CommonDB {
|
|
|
228
228
|
rows = rows.map(r => _filterUndefinedValues(r))
|
|
229
229
|
|
|
230
230
|
if (this.cfg.sortOnSave) {
|
|
231
|
-
_sortBy(rows, r => r[this.cfg.sortOnSave!.name as keyof ROW], true)
|
|
231
|
+
_sortBy(rows, r => r[this.cfg.sortOnSave!.name as keyof ROW] as string, { mutate: true })
|
|
232
232
|
if (this.cfg.sortOnSave.descending) rows.reverse() // mutates
|
|
233
233
|
}
|
|
234
234
|
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { Readable } from 'node:stream'
|
|
2
2
|
import type { ObjectWithId } from '@naturalcycles/js-lib'
|
|
3
3
|
import { pMap } from '@naturalcycles/js-lib'
|
|
4
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
5
|
-
import {
|
|
4
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
|
|
5
|
+
import {
|
|
6
|
+
_pipeline,
|
|
7
|
+
createReadStreamAsNDJSON,
|
|
8
|
+
createWriteStreamAsNDJSON,
|
|
9
|
+
} from '@naturalcycles/nodejs-lib/stream'
|
|
6
10
|
import type { DBSaveBatchOperation } from '../../db.model.js'
|
|
7
11
|
import type { FileDBPersistencePlugin } from './file.db.model.js'
|
|
8
12
|
|
|
@@ -47,7 +51,7 @@ export class LocalFilePersistencePlugin implements FileDBPersistencePlugin {
|
|
|
47
51
|
|
|
48
52
|
if (!(await fs2.pathExistsAsync(filePath))) return []
|
|
49
53
|
|
|
50
|
-
return await
|
|
54
|
+
return await createReadStreamAsNDJSON(filePath).toArray()
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
async saveFiles(ops: DBSaveBatchOperation<any>[]): Promise<void> {
|
|
@@ -59,6 +63,6 @@ export class LocalFilePersistencePlugin implements FileDBPersistencePlugin {
|
|
|
59
63
|
const ext = `ndjson${this.cfg.gzip ? '.gz' : ''}`
|
|
60
64
|
const filePath = `${this.cfg.storagePath}/${table}.${ext}`
|
|
61
65
|
|
|
62
|
-
await _pipeline([Readable.from(rows), ...
|
|
66
|
+
await _pipeline([Readable.from(rows), ...createWriteStreamAsNDJSON(filePath)])
|
|
63
67
|
}
|
|
64
68
|
}
|
|
@@ -20,9 +20,15 @@ import {
|
|
|
20
20
|
localTime,
|
|
21
21
|
pMap,
|
|
22
22
|
} from '@naturalcycles/js-lib'
|
|
23
|
-
import { dimGrey, yellow } from '@naturalcycles/nodejs-lib'
|
|
24
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
25
|
-
import {
|
|
23
|
+
import { dimGrey, yellow } from '@naturalcycles/nodejs-lib/colors'
|
|
24
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
|
|
25
|
+
import {
|
|
26
|
+
_pipeline,
|
|
27
|
+
bufferReviver,
|
|
28
|
+
createReadStreamAsNDJSON,
|
|
29
|
+
createWriteStreamAsNDJSON,
|
|
30
|
+
type ReadableTyped,
|
|
31
|
+
} from '@naturalcycles/nodejs-lib/stream'
|
|
26
32
|
import type { CommonDB, CommonDBSupport } from '../../common.db.js'
|
|
27
33
|
import { commonDBFullSupport, CommonDBType } from '../../common.db.js'
|
|
28
34
|
import type {
|
|
@@ -329,7 +335,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
329
335
|
tables++
|
|
330
336
|
const fname = `${persistentStoragePath}/${table}.ndjson${persistZip ? '.gz' : ''}`
|
|
331
337
|
|
|
332
|
-
await _pipeline([Readable.from(rows), ...
|
|
338
|
+
await _pipeline([Readable.from(rows), ...createWriteStreamAsNDJSON(fname)])
|
|
333
339
|
})
|
|
334
340
|
|
|
335
341
|
this.cfg.logger!.log(
|
|
@@ -357,7 +363,7 @@ export class InMemoryDB implements CommonDB {
|
|
|
357
363
|
const fname = `${persistentStoragePath}/${file}`
|
|
358
364
|
const table = file.split('.ndjson')[0]!
|
|
359
365
|
|
|
360
|
-
const rows = await
|
|
366
|
+
const rows = await createReadStreamAsNDJSON(fname).toArray()
|
|
361
367
|
|
|
362
368
|
this.data[table] = _by(rows, r => r.id)
|
|
363
369
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Transform } from 'node:stream'
|
|
2
2
|
import type {
|
|
3
|
-
|
|
3
|
+
AsyncIndexedMapper,
|
|
4
4
|
BaseDBEntity,
|
|
5
5
|
CommonLogger,
|
|
6
6
|
JsonSchemaObject,
|
|
@@ -358,7 +358,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
|
|
|
358
358
|
|
|
359
359
|
async streamQueryForEach(
|
|
360
360
|
q: DBQuery<DBM>,
|
|
361
|
-
mapper:
|
|
361
|
+
mapper: AsyncIndexedMapper<BM, void>,
|
|
362
362
|
opt: CommonDaoStreamForEachOptions<BM> = {},
|
|
363
363
|
): Promise<void> {
|
|
364
364
|
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property
|
|
@@ -408,7 +408,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
|
|
|
408
408
|
|
|
409
409
|
async streamQueryAsDBMForEach(
|
|
410
410
|
q: DBQuery<DBM>,
|
|
411
|
-
mapper:
|
|
411
|
+
mapper: AsyncIndexedMapper<DBM, void>,
|
|
412
412
|
opt: CommonDaoStreamForEachOptions<DBM> = {},
|
|
413
413
|
): Promise<void> {
|
|
414
414
|
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property
|
|
@@ -581,7 +581,7 @@ export class CommonDao<BM extends BaseDBEntity, DBM extends BaseDBEntity = BM, I
|
|
|
581
581
|
|
|
582
582
|
async streamQueryIdsForEach(
|
|
583
583
|
q: DBQuery<DBM>,
|
|
584
|
-
mapper:
|
|
584
|
+
mapper: AsyncIndexedMapper<ID, void>,
|
|
585
585
|
opt: CommonDaoStreamForEachOptions<ID> = {},
|
|
586
586
|
): Promise<void> {
|
|
587
587
|
this.validateQueryIndexes(q) // throws if query uses `excludeFromIndexes` property
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CommonLogger, KeyValueTuple } from '@naturalcycles/js-lib'
|
|
2
2
|
import { AppError, pMap } from '@naturalcycles/js-lib'
|
|
3
|
-
import { deflateString, inflateToString } from '@naturalcycles/nodejs-lib'
|
|
4
3
|
import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream'
|
|
4
|
+
import { deflateString, inflateToString } from '@naturalcycles/nodejs-lib/zip'
|
|
5
5
|
import type { CommonDaoLogLevel } from '../commondao/common.dao.model.js'
|
|
6
6
|
import type { CommonDBCreateOptions } from '../db.model.js'
|
|
7
7
|
import type {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { AsyncMapper, StringMap, UnixTimestamp } from '@naturalcycles/js-lib'
|
|
2
2
|
import { _passthroughMapper, AppError, ErrorMode, localTime, pMap } from '@naturalcycles/js-lib'
|
|
3
|
-
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib'
|
|
4
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/colors'
|
|
4
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
|
|
5
|
+
import {
|
|
6
|
+
createWriteStreamAsNDJSON,
|
|
7
|
+
type TransformLogProgressOptions,
|
|
8
|
+
type TransformMapOptions,
|
|
8
9
|
} from '@naturalcycles/nodejs-lib/stream'
|
|
9
10
|
import {
|
|
10
11
|
_pipeline,
|
|
@@ -223,7 +224,7 @@ export async function dbPipelineBackup(opt: DBPipelineBackupOptions): Promise<ND
|
|
|
223
224
|
transformTap(() => {
|
|
224
225
|
rows++
|
|
225
226
|
}),
|
|
226
|
-
...
|
|
227
|
+
...createWriteStreamAsNDJSON(filePath),
|
|
227
228
|
])
|
|
228
229
|
|
|
229
230
|
const { size: sizeBytes } = await fs2.statAsync(filePath)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AsyncMapper, BaseDBEntity, UnixTimestamp } from '@naturalcycles/js-lib'
|
|
2
2
|
import { _passthroughMapper, ErrorMode, localTime, pMap } from '@naturalcycles/js-lib'
|
|
3
|
-
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib'
|
|
3
|
+
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/colors'
|
|
4
4
|
import type {
|
|
5
5
|
TransformLogProgressOptions,
|
|
6
6
|
TransformMapOptions,
|
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
localTime,
|
|
13
13
|
pMap,
|
|
14
14
|
} from '@naturalcycles/js-lib'
|
|
15
|
-
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib'
|
|
16
|
-
import { fs2 } from '@naturalcycles/nodejs-lib/
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/colors'
|
|
16
|
+
import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
|
|
17
|
+
import {
|
|
18
|
+
createReadStreamAsNDJSON,
|
|
19
|
+
type TransformLogProgressOptions,
|
|
20
|
+
type TransformMapOptions,
|
|
20
21
|
} from '@naturalcycles/nodejs-lib/stream'
|
|
21
22
|
import {
|
|
22
23
|
_pipeline,
|
|
@@ -200,7 +201,7 @@ export async function dbPipelineRestore(opt: DBPipelineRestoreOptions): Promise<
|
|
|
200
201
|
console.log(`<< ${grey(filePath)} ${dimWhite(_hb(sizeBytes))} started...`)
|
|
201
202
|
|
|
202
203
|
await _pipeline([
|
|
203
|
-
|
|
204
|
+
createReadStreamAsNDJSON(filePath).take(limit || Number.POSITIVE_INFINITY),
|
|
204
205
|
transformTap(() => rows++),
|
|
205
206
|
transformLogProgress({
|
|
206
207
|
logEvery: 1000,
|
package/src/query/dbQuery.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AsyncIndexedMapper, BaseDBEntity, ObjectWithId } from '@naturalcycles/js-lib'
|
|
2
2
|
import { _objectAssign, _truncate } from '@naturalcycles/js-lib'
|
|
3
3
|
import type { ReadableTyped } from '@naturalcycles/nodejs-lib/stream'
|
|
4
4
|
import type { CommonDao } from '../commondao/common.dao.js'
|
|
@@ -276,14 +276,14 @@ export class RunnableDBQuery<
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
async streamQueryForEach(
|
|
279
|
-
mapper:
|
|
279
|
+
mapper: AsyncIndexedMapper<BM, void>,
|
|
280
280
|
opt?: CommonDaoStreamForEachOptions<BM>,
|
|
281
281
|
): Promise<void> {
|
|
282
282
|
await this.dao.streamQueryForEach(this, mapper, opt)
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
async streamQueryAsDBMForEach(
|
|
286
|
-
mapper:
|
|
286
|
+
mapper: AsyncIndexedMapper<DBM, void>,
|
|
287
287
|
opt?: CommonDaoStreamForEachOptions<DBM>,
|
|
288
288
|
): Promise<void> {
|
|
289
289
|
await this.dao.streamQueryAsDBMForEach(this, mapper, opt)
|
|
@@ -306,7 +306,7 @@ export class RunnableDBQuery<
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
async streamQueryIdsForEach(
|
|
309
|
-
mapper:
|
|
309
|
+
mapper: AsyncIndexedMapper<ID, void>,
|
|
310
310
|
opt?: CommonDaoStreamForEachOptions<ID>,
|
|
311
311
|
): Promise<void> {
|
|
312
312
|
await this.dao.streamQueryIdsForEach(this, mapper, opt)
|
|
@@ -54,7 +54,7 @@ export async function runCommonKeyValueDBTest(db: CommonKeyValueDB): Promise<voi
|
|
|
54
54
|
await db.saveBatch(TEST_TABLE, testEntries)
|
|
55
55
|
|
|
56
56
|
const entries = await db.getByIds(TEST_TABLE, testIds)
|
|
57
|
-
_sortBy(entries, e => e[0], true)
|
|
57
|
+
_sortBy(entries, e => e[0], { mutate: true })
|
|
58
58
|
expect(entries).toEqual(testEntries)
|
|
59
59
|
})
|
|
60
60
|
|
|
@@ -54,7 +54,7 @@ export async function runCommonKeyValueDaoTest(db: CommonKeyValueDB): Promise<vo
|
|
|
54
54
|
const entries = await dao.getByIds(testIds)
|
|
55
55
|
// console.log(typeof entries[0]![1], entries[0]![1])
|
|
56
56
|
|
|
57
|
-
_sortBy(entries, e => e[0], true)
|
|
57
|
+
_sortBy(entries, e => e[0], { mutate: true })
|
|
58
58
|
expect(entries).toEqual(testEntries) // Jest doesn't allow to compare Buffers directly
|
|
59
59
|
// expect(entries.map(e => e[0])).toEqual(testEntries.map(e => e[0]))
|
|
60
60
|
// expect(entries.map(e => e[1].toString())).toEqual(testEntries.map(e => e[1].toString()))
|