@naturalcycles/db-lib 8.34.0 → 8.35.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/commondao/common.dao.d.ts +1 -1
- package/dist/commondao/common.dao.js +14 -16
- package/dist/commondao/common.dao.model.d.ts +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +2 -4
- package/dist/pipeline/dbPipelineBackup.js +1 -2
- package/dist/pipeline/dbPipelineCopy.js +1 -2
- package/dist/pipeline/dbPipelineRestore.js +1 -2
- package/package.json +1 -2
- package/src/commondao/common.dao.model.ts +1 -1
- package/src/commondao/common.dao.ts +32 -21
- package/src/index.ts +0 -2
- package/src/pipeline/dbPipelineBackup.ts +9 -3
- package/src/pipeline/dbPipelineCopy.ts +2 -3
- package/src/pipeline/dbPipelineRestore.ts +2 -2
- package/dist/getDB.d.ts +0 -19
- package/dist/getDB.js +0 -32
- package/src/getDB.ts +0 -50
|
@@ -85,7 +85,7 @@ export declare class CommonDao<BM extends Partial<ObjectWithId>, DBM extends Obj
|
|
|
85
85
|
* Mutates with id, created, updated
|
|
86
86
|
*/
|
|
87
87
|
save(bm: BM, opt?: CommonDaoSaveOptions<DBM>): Promise<Saved<BM>>;
|
|
88
|
-
private
|
|
88
|
+
private ensureImmutableDontExist;
|
|
89
89
|
private ensureUniqueId;
|
|
90
90
|
private throwIfObjectExists;
|
|
91
91
|
/**
|
|
@@ -442,7 +442,7 @@ class CommonDao {
|
|
|
442
442
|
if (opt.ensureUniqueId && idWasGenerated)
|
|
443
443
|
await this.ensureUniqueId(table, dbm);
|
|
444
444
|
if (this.cfg.immutable)
|
|
445
|
-
await this.
|
|
445
|
+
await this.ensureImmutableDontExist(table, [dbm.id]);
|
|
446
446
|
const op = `save(${dbm.id})`;
|
|
447
447
|
const started = this.logSaveStarted(op, bm, table);
|
|
448
448
|
await this.cfg.db.saveBatch(table, [dbm], {
|
|
@@ -452,31 +452,29 @@ class CommonDao {
|
|
|
452
452
|
this.logSaveResult(started, op, table);
|
|
453
453
|
return bm;
|
|
454
454
|
}
|
|
455
|
-
async
|
|
456
|
-
await this.throwIfObjectExists(table,
|
|
455
|
+
async ensureImmutableDontExist(table, ids) {
|
|
456
|
+
await this.throwIfObjectExists(table, ids, [
|
|
457
457
|
cnst_1.DBLibError.OBJECT_IS_IMMUTABLE,
|
|
458
458
|
{
|
|
459
459
|
code: cnst_1.DBLibError.OBJECT_IS_IMMUTABLE,
|
|
460
|
-
id: dbm.id,
|
|
461
460
|
table,
|
|
462
461
|
},
|
|
463
462
|
]);
|
|
464
463
|
}
|
|
465
464
|
async ensureUniqueId(table, dbm) {
|
|
466
465
|
// todo: retry N times
|
|
467
|
-
await this.throwIfObjectExists(table, dbm, [
|
|
466
|
+
await this.throwIfObjectExists(table, [dbm.id], [
|
|
468
467
|
cnst_1.DBLibError.OBJECT_IS_IMMUTABLE,
|
|
469
468
|
{
|
|
470
469
|
code: cnst_1.DBLibError.OBJECT_IS_IMMUTABLE,
|
|
471
|
-
id: dbm.id,
|
|
472
470
|
table,
|
|
473
471
|
},
|
|
474
472
|
]);
|
|
475
473
|
}
|
|
476
|
-
async throwIfObjectExists(table,
|
|
477
|
-
const
|
|
478
|
-
if (existing)
|
|
479
|
-
throw new js_lib_1.AppError(errorMeta[0], errorMeta[1]);
|
|
474
|
+
async throwIfObjectExists(table, ids, errorMeta) {
|
|
475
|
+
const existing = await this.cfg.db.getByIds(table, ids);
|
|
476
|
+
if (existing.length > 0)
|
|
477
|
+
throw new js_lib_1.AppError(errorMeta[0], { ...errorMeta[1], ids: existing.map(i => i.id) });
|
|
480
478
|
}
|
|
481
479
|
/**
|
|
482
480
|
* Loads the row by id.
|
|
@@ -512,7 +510,7 @@ class CommonDao {
|
|
|
512
510
|
if (opt.ensureUniqueId && idWasGenerated)
|
|
513
511
|
await this.ensureUniqueId(table, dbm);
|
|
514
512
|
if (this.cfg.immutable)
|
|
515
|
-
await this.
|
|
513
|
+
await this.ensureImmutableDontExist(table, [dbm.id]);
|
|
516
514
|
}
|
|
517
515
|
const op = `saveAsDBM(${dbm.id})`;
|
|
518
516
|
const started = this.logSaveStarted(op, dbm, table);
|
|
@@ -531,7 +529,7 @@ class CommonDao {
|
|
|
531
529
|
if (opt.ensureUniqueId)
|
|
532
530
|
throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
|
|
533
531
|
if (this.cfg.immutable)
|
|
534
|
-
|
|
532
|
+
await this.ensureImmutableDontExist(table, dbms.map(dbm => dbm.id));
|
|
535
533
|
const op = `saveBatch ${dbms.length} row(s) (${(0, js_lib_1._truncate)(dbms
|
|
536
534
|
.slice(0, 10)
|
|
537
535
|
.map(bm => bm.id)
|
|
@@ -553,7 +551,7 @@ class CommonDao {
|
|
|
553
551
|
if (opt.ensureUniqueId)
|
|
554
552
|
throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
|
|
555
553
|
if (this.cfg.immutable)
|
|
556
|
-
|
|
554
|
+
await this.ensureImmutableDontExist(table, dbms.map(dbm => dbm.id));
|
|
557
555
|
}
|
|
558
556
|
const op = `saveBatchAsDBM ${dbms.length} row(s) (${(0, js_lib_1._truncate)(dbms
|
|
559
557
|
.slice(0, 10)
|
|
@@ -571,7 +569,7 @@ class CommonDao {
|
|
|
571
569
|
if (!id)
|
|
572
570
|
return 0;
|
|
573
571
|
this.requireWriteAccess();
|
|
574
|
-
if (!opt.
|
|
572
|
+
if (!opt.allowMutability)
|
|
575
573
|
this.requireObjectMutability();
|
|
576
574
|
const op = `deleteById(${id})`;
|
|
577
575
|
const table = opt.table || this.cfg.table;
|
|
@@ -582,7 +580,7 @@ class CommonDao {
|
|
|
582
580
|
}
|
|
583
581
|
async deleteByIds(ids, opt = {}) {
|
|
584
582
|
this.requireWriteAccess();
|
|
585
|
-
if (!opt.
|
|
583
|
+
if (!opt.allowMutability)
|
|
586
584
|
this.requireObjectMutability();
|
|
587
585
|
const op = `deleteByIds(${ids.join(', ')})`;
|
|
588
586
|
const table = opt.table || this.cfg.table;
|
|
@@ -598,7 +596,7 @@ class CommonDao {
|
|
|
598
596
|
*/
|
|
599
597
|
async deleteByQuery(q, opt = {}) {
|
|
600
598
|
this.requireWriteAccess();
|
|
601
|
-
if (!opt.
|
|
599
|
+
if (!opt.allowMutability)
|
|
602
600
|
this.requireObjectMutability();
|
|
603
601
|
q.table = opt.table || q.table;
|
|
604
602
|
const op = `deleteByQuery(${q.pretty()})`;
|
|
@@ -140,7 +140,7 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
140
140
|
/**
|
|
141
141
|
* @default false (for streams). Setting to true enables deletion of immutable objects
|
|
142
142
|
*/
|
|
143
|
-
|
|
143
|
+
allowMutability?: boolean;
|
|
144
144
|
/**
|
|
145
145
|
* If true - data will be anonymized (by calling a BaseDao.anonymize() hook that you can extend in your Dao implementation).
|
|
146
146
|
* Only applicable to loading/querying/streaming_loading operations (n/a for saving).
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { CommonDB } from './common.db';
|
|
|
7
7
|
import { CommonDao } from './commondao/common.dao';
|
|
8
8
|
import { CommonDaoAnonymizeHook, CommonDaoBeforeBMToDBMHook, CommonDaoBeforeBMToTMHook, CommonDaoBeforeCreateHook, CommonDaoBeforeDBMToBMHook, CommonDaoBeforeDBMValidateHook, CommonDaoBeforeTMToBMHook, CommonDaoCfg, CommonDaoCreateIdHook, CommonDaoCreateOptions, CommonDaoLogLevel, CommonDaoOptions, CommonDaoParseNaturalIdHook, CommonDaoSaveOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions } from './commondao/common.dao.model';
|
|
9
9
|
import { CommonDBAdapter, CommonDBCreateOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, DBDeleteByIdsOperation, DBModelType, DBOperation, DBRelation, DBSaveBatchOperation, RunQueryResult } from './db.model';
|
|
10
|
-
import { getDB } from './getDB';
|
|
11
10
|
import { CommonKeyValueDao, CommonKeyValueDaoCfg } from './kv/commonKeyValueDao';
|
|
12
11
|
import { CommonKeyValueDB, KeyValueDBTuple } from './kv/commonKeyValueDB';
|
|
13
12
|
import { createdUpdatedFields, createdUpdatedIdFields, deserializeJsonField, serializeJsonField } from './model.util';
|
|
@@ -19,4 +18,4 @@ import { DBTransaction, RunnableDBTransaction } from './transaction/dbTransactio
|
|
|
19
18
|
import { commitDBTransactionSimple, mergeDBOperations } from './transaction/dbTransaction.util';
|
|
20
19
|
export * from './kv/commonKeyValueDaoMemoCache';
|
|
21
20
|
export type { DBQueryFilterOperator, DBQueryFilter, DBQueryOrder, CommonDaoCreateOptions, CommonDaoOptions, CommonDaoSaveOptions, CommonDaoStreamForEachOptions, CommonDaoStreamOptions, CommonDBOptions, CommonDBSaveOptions, CommonDBStreamOptions, CommonDBCreateOptions, CommonDB, RunQueryResult, CommonDaoCfg, CommonDaoCreateIdHook, CommonDaoParseNaturalIdHook, CommonDaoBeforeCreateHook, CommonDaoBeforeDBMValidateHook, CommonDaoBeforeDBMToBMHook, CommonDaoBeforeBMToDBMHook, CommonDaoBeforeTMToBMHook, CommonDaoBeforeBMToTMHook, CommonDaoAnonymizeHook, InMemoryDBCfg, InMemoryKeyValueDBCfg, DBPipelineBackupOptions, DBPipelineRestoreOptions, DBPipelineCopyOptions, CommonDBAdapter, DBOperation, DBSaveBatchOperation, DBDeleteByIdsOperation, CommonKeyValueDB, CommonKeyValueDaoCfg, KeyValueDBTuple, };
|
|
22
|
-
export { DBQuery, dbQueryFilterOperatorValues, RunnableDBQuery, CommonDaoLogLevel, DBRelation, DBModelType, CommonDao, createdUpdatedFields, createdUpdatedIdFields, InMemoryDB, InMemoryKeyValueDB, queryInMemory, serializeJsonField, deserializeJsonField, dbPipelineBackup, dbPipelineRestore, dbPipelineCopy,
|
|
21
|
+
export { DBQuery, dbQueryFilterOperatorValues, RunnableDBQuery, CommonDaoLogLevel, DBRelation, DBModelType, CommonDao, createdUpdatedFields, createdUpdatedIdFields, InMemoryDB, InMemoryKeyValueDB, queryInMemory, serializeJsonField, deserializeJsonField, dbPipelineBackup, dbPipelineRestore, dbPipelineCopy, DBLibError, BaseCommonDB, DBTransaction, RunnableDBTransaction, mergeDBOperations, commitDBTransactionSimple, CommonKeyValueDao, };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CommonKeyValueDao = exports.commitDBTransactionSimple = exports.mergeDBOperations = exports.RunnableDBTransaction = exports.DBTransaction = exports.BaseCommonDB = exports.DBLibError = exports.
|
|
3
|
+
exports.CommonKeyValueDao = exports.commitDBTransactionSimple = exports.mergeDBOperations = exports.RunnableDBTransaction = exports.DBTransaction = exports.BaseCommonDB = exports.DBLibError = exports.dbPipelineCopy = exports.dbPipelineRestore = exports.dbPipelineBackup = exports.deserializeJsonField = exports.serializeJsonField = exports.queryInMemory = exports.InMemoryKeyValueDB = exports.InMemoryDB = exports.createdUpdatedIdFields = exports.createdUpdatedFields = exports.CommonDao = exports.DBModelType = exports.DBRelation = exports.CommonDaoLogLevel = exports.RunnableDBQuery = exports.dbQueryFilterOperatorValues = exports.DBQuery = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const inMemory_db_1 = require("./adapter/inmemory/inMemory.db");
|
|
6
6
|
Object.defineProperty(exports, "InMemoryDB", { enumerable: true, get: function () { return inMemory_db_1.InMemoryDB; } });
|
|
@@ -19,8 +19,6 @@ Object.defineProperty(exports, "CommonDaoLogLevel", { enumerable: true, get: fun
|
|
|
19
19
|
const db_model_1 = require("./db.model");
|
|
20
20
|
Object.defineProperty(exports, "DBModelType", { enumerable: true, get: function () { return db_model_1.DBModelType; } });
|
|
21
21
|
Object.defineProperty(exports, "DBRelation", { enumerable: true, get: function () { return db_model_1.DBRelation; } });
|
|
22
|
-
const getDB_1 = require("./getDB");
|
|
23
|
-
Object.defineProperty(exports, "getDB", { enumerable: true, get: function () { return getDB_1.getDB; } });
|
|
24
22
|
const commonKeyValueDao_1 = require("./kv/commonKeyValueDao");
|
|
25
23
|
Object.defineProperty(exports, "CommonKeyValueDao", { enumerable: true, get: function () { return commonKeyValueDao_1.CommonKeyValueDao; } });
|
|
26
24
|
const model_util_1 = require("./model.util");
|
|
@@ -44,4 +42,4 @@ Object.defineProperty(exports, "RunnableDBTransaction", { enumerable: true, get:
|
|
|
44
42
|
const dbTransaction_util_1 = require("./transaction/dbTransaction.util");
|
|
45
43
|
Object.defineProperty(exports, "commitDBTransactionSimple", { enumerable: true, get: function () { return dbTransaction_util_1.commitDBTransactionSimple; } });
|
|
46
44
|
Object.defineProperty(exports, "mergeDBOperations", { enumerable: true, get: function () { return dbTransaction_util_1.mergeDBOperations; } });
|
|
47
|
-
|
|
45
|
+
tslib_1.__exportStar(require("./kv/commonKeyValueDaoMemoCache"), exports);
|
|
@@ -5,7 +5,6 @@ const zlib_1 = require("zlib");
|
|
|
5
5
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
6
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
7
7
|
const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
|
|
8
|
-
const time_lib_1 = require("@naturalcycles/time-lib");
|
|
9
8
|
const fs = require("fs-extra");
|
|
10
9
|
const index_1 = require("../index");
|
|
11
10
|
/**
|
|
@@ -22,7 +21,7 @@ async function dbPipelineBackup(opt) {
|
|
|
22
21
|
const strict = errorMode !== js_lib_1.ErrorMode.SUPPRESS;
|
|
23
22
|
const gzip = opt.gzip !== false; // default to true
|
|
24
23
|
let { tables } = opt;
|
|
25
|
-
const sinceUpdatedStr = sinceUpdated ? ' since ' + (0, colors_1.grey)(
|
|
24
|
+
const sinceUpdatedStr = sinceUpdated ? ' since ' + (0, colors_1.grey)((0, js_lib_1.localTime)(sinceUpdated).toPretty()) : '';
|
|
26
25
|
console.log(`>> ${(0, colors_1.dimWhite)('dbPipelineBackup')} started in ${(0, colors_1.grey)(outputDirPath)}...${sinceUpdatedStr}`);
|
|
27
26
|
fs.ensureDirSync(outputDirPath);
|
|
28
27
|
if (!tables) {
|
|
@@ -4,7 +4,6 @@ exports.dbPipelineCopy = void 0;
|
|
|
4
4
|
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
|
-
const time_lib_1 = require("@naturalcycles/time-lib");
|
|
8
7
|
const dbQuery_1 = require("../query/dbQuery");
|
|
9
8
|
/**
|
|
10
9
|
* Pipeline from input stream(s) to CommonDB .saveBatch().
|
|
@@ -15,7 +14,7 @@ const dbQuery_1 = require("../query/dbQuery");
|
|
|
15
14
|
async function dbPipelineCopy(opt) {
|
|
16
15
|
const { batchSize = 100, dbInput, dbOutput, concurrency = 16, limit = 0, sinceUpdated, mapperPerTable = {}, saveOptionsPerTable = {}, transformMapOptions, errorMode = js_lib_1.ErrorMode.SUPPRESS, } = opt;
|
|
17
16
|
let { tables } = opt;
|
|
18
|
-
const sinceUpdatedStr = sinceUpdated ? ' since ' + (0, colors_1.grey)(
|
|
17
|
+
const sinceUpdatedStr = sinceUpdated ? ' since ' + (0, colors_1.grey)((0, js_lib_1.localTime)(sinceUpdated).toPretty()) : '';
|
|
19
18
|
console.log(`>> ${(0, colors_1.dimWhite)('dbPipelineCopy')} started...${sinceUpdatedStr}`);
|
|
20
19
|
if (!tables) {
|
|
21
20
|
tables = await dbInput.getTables();
|
|
@@ -5,7 +5,6 @@ const zlib_1 = require("zlib");
|
|
|
5
5
|
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
6
6
|
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
7
7
|
const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
|
|
8
|
-
const time_lib_1 = require("@naturalcycles/time-lib");
|
|
9
8
|
const fs = require("fs-extra");
|
|
10
9
|
/**
|
|
11
10
|
* Pipeline from NDJSON files in a folder (optionally gzipped) to CommonDB.
|
|
@@ -18,7 +17,7 @@ async function dbPipelineRestore(opt) {
|
|
|
18
17
|
const { db, concurrency = 16, batchSize = 100, limit, sinceUpdated, inputDirPath, mapperPerTable = {}, saveOptionsPerTable = {}, transformMapOptions, errorMode = js_lib_1.ErrorMode.SUPPRESS, recreateTables = false, } = opt;
|
|
19
18
|
const strict = errorMode !== js_lib_1.ErrorMode.SUPPRESS;
|
|
20
19
|
const onlyTables = opt.tables && new Set(opt.tables);
|
|
21
|
-
const sinceUpdatedStr = sinceUpdated ? ' since ' + (0, colors_1.grey)(
|
|
20
|
+
const sinceUpdatedStr = sinceUpdated ? ' since ' + (0, colors_1.grey)((0, js_lib_1.localTime)(sinceUpdated).toPretty()) : '';
|
|
22
21
|
console.log(`>> ${(0, colors_1.dimWhite)('dbPipelineRestore')} started in ${(0, colors_1.grey)(inputDirPath)}...${sinceUpdatedStr}`);
|
|
23
22
|
fs.ensureDirSync(inputDirPath);
|
|
24
23
|
const tablesToGzip = new Set();
|
package/package.json
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@naturalcycles/js-lib": "^14.0.0",
|
|
8
8
|
"@naturalcycles/nodejs-lib": "^12.0.0",
|
|
9
|
-
"@naturalcycles/time-lib": "^3.0.1",
|
|
10
9
|
"fs-extra": "^10.0.0"
|
|
11
10
|
},
|
|
12
11
|
"devDependencies": {
|
|
@@ -43,7 +42,7 @@
|
|
|
43
42
|
"engines": {
|
|
44
43
|
"node": ">=14.15"
|
|
45
44
|
},
|
|
46
|
-
"version": "8.
|
|
45
|
+
"version": "8.35.0",
|
|
47
46
|
"description": "Lowest Common Denominator API to supported Databases",
|
|
48
47
|
"keywords": [
|
|
49
48
|
"db",
|
|
@@ -174,7 +174,7 @@ export interface CommonDaoOptions extends CommonDBOptions {
|
|
|
174
174
|
/**
|
|
175
175
|
* @default false (for streams). Setting to true enables deletion of immutable objects
|
|
176
176
|
*/
|
|
177
|
-
|
|
177
|
+
allowMutability?: boolean
|
|
178
178
|
|
|
179
179
|
/**
|
|
180
180
|
* If true - data will be anonymized (by calling a BaseDao.anonymize() hook that you can extend in your Dao implementation).
|
|
@@ -601,7 +601,7 @@ export class CommonDao<
|
|
|
601
601
|
const dbm = await this.bmToDBM(bm, opt)
|
|
602
602
|
const table = opt.table || this.cfg.table
|
|
603
603
|
if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, dbm)
|
|
604
|
-
if (this.cfg.immutable) await this.
|
|
604
|
+
if (this.cfg.immutable) await this.ensureImmutableDontExist(table, [dbm.id])
|
|
605
605
|
const op = `save(${dbm.id})`
|
|
606
606
|
const started = this.logSaveStarted(op, bm, table)
|
|
607
607
|
await this.cfg.db.saveBatch(table, [dbm], {
|
|
@@ -613,12 +613,11 @@ export class CommonDao<
|
|
|
613
613
|
return bm as any
|
|
614
614
|
}
|
|
615
615
|
|
|
616
|
-
private async
|
|
617
|
-
await this.throwIfObjectExists(table,
|
|
616
|
+
private async ensureImmutableDontExist(table: string, ids: string[]): Promise<void> {
|
|
617
|
+
await this.throwIfObjectExists(table, ids, [
|
|
618
618
|
DBLibError.OBJECT_IS_IMMUTABLE,
|
|
619
619
|
{
|
|
620
620
|
code: DBLibError.OBJECT_IS_IMMUTABLE,
|
|
621
|
-
id: dbm.id,
|
|
622
621
|
table,
|
|
623
622
|
},
|
|
624
623
|
])
|
|
@@ -626,23 +625,27 @@ export class CommonDao<
|
|
|
626
625
|
|
|
627
626
|
private async ensureUniqueId(table: string, dbm: DBM): Promise<void> {
|
|
628
627
|
// todo: retry N times
|
|
629
|
-
await this.throwIfObjectExists(
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
628
|
+
await this.throwIfObjectExists(
|
|
629
|
+
table,
|
|
630
|
+
[dbm.id],
|
|
631
|
+
[
|
|
632
|
+
DBLibError.OBJECT_IS_IMMUTABLE,
|
|
633
|
+
{
|
|
634
|
+
code: DBLibError.OBJECT_IS_IMMUTABLE,
|
|
635
|
+
table,
|
|
636
|
+
},
|
|
637
|
+
],
|
|
638
|
+
)
|
|
637
639
|
}
|
|
638
640
|
|
|
639
641
|
private async throwIfObjectExists(
|
|
640
642
|
table: string,
|
|
641
|
-
|
|
643
|
+
ids: string[],
|
|
642
644
|
errorMeta: [DBLibError, any],
|
|
643
645
|
): Promise<void> {
|
|
644
|
-
const
|
|
645
|
-
if (existing
|
|
646
|
+
const existing = await this.cfg.db.getByIds<DBM>(table, ids)
|
|
647
|
+
if (existing.length > 0)
|
|
648
|
+
throw new AppError(errorMeta[0], { ...errorMeta[1], ids: existing.map(i => i.id) })
|
|
646
649
|
}
|
|
647
650
|
|
|
648
651
|
/**
|
|
@@ -696,7 +699,7 @@ export class CommonDao<
|
|
|
696
699
|
this.assignIdCreatedUpdated(dbm, opt) // mutates
|
|
697
700
|
dbm = this.anyToDBM(dbm, opt)
|
|
698
701
|
if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, dbm)
|
|
699
|
-
if (this.cfg.immutable) await this.
|
|
702
|
+
if (this.cfg.immutable) await this.ensureImmutableDontExist(table, [dbm.id])
|
|
700
703
|
}
|
|
701
704
|
const op = `saveAsDBM(${dbm.id})`
|
|
702
705
|
const started = this.logSaveStarted(op, dbm, table)
|
|
@@ -715,7 +718,11 @@ export class CommonDao<
|
|
|
715
718
|
const dbms = await this.bmsToDBM(bms, opt)
|
|
716
719
|
if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
|
|
717
720
|
if (this.cfg.immutable)
|
|
718
|
-
|
|
721
|
+
await this.ensureImmutableDontExist(
|
|
722
|
+
table,
|
|
723
|
+
dbms.map(dbm => dbm.id),
|
|
724
|
+
)
|
|
725
|
+
|
|
719
726
|
const op = `saveBatch ${dbms.length} row(s) (${_truncate(
|
|
720
727
|
dbms
|
|
721
728
|
.slice(0, 10)
|
|
@@ -742,7 +749,11 @@ export class CommonDao<
|
|
|
742
749
|
dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt)) // mutates
|
|
743
750
|
dbms = this.anyToDBMs(dbms, opt)
|
|
744
751
|
if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
|
|
745
|
-
if (this.cfg.immutable)
|
|
752
|
+
if (this.cfg.immutable)
|
|
753
|
+
await this.ensureImmutableDontExist(
|
|
754
|
+
table,
|
|
755
|
+
dbms.map(dbm => dbm.id),
|
|
756
|
+
)
|
|
746
757
|
}
|
|
747
758
|
const op = `saveBatchAsDBM ${dbms.length} row(s) (${_truncate(
|
|
748
759
|
dbms
|
|
@@ -771,7 +782,7 @@ export class CommonDao<
|
|
|
771
782
|
async deleteById(id?: string, opt: CommonDaoOptions = {}): Promise<number> {
|
|
772
783
|
if (!id) return 0
|
|
773
784
|
this.requireWriteAccess()
|
|
774
|
-
if (!opt.
|
|
785
|
+
if (!opt.allowMutability) this.requireObjectMutability()
|
|
775
786
|
const op = `deleteById(${id})`
|
|
776
787
|
const table = opt.table || this.cfg.table
|
|
777
788
|
const started = this.logStarted(op, table)
|
|
@@ -782,7 +793,7 @@ export class CommonDao<
|
|
|
782
793
|
|
|
783
794
|
async deleteByIds(ids: string[], opt: CommonDaoOptions = {}): Promise<number> {
|
|
784
795
|
this.requireWriteAccess()
|
|
785
|
-
if (!opt.
|
|
796
|
+
if (!opt.allowMutability) this.requireObjectMutability()
|
|
786
797
|
const op = `deleteByIds(${ids.join(', ')})`
|
|
787
798
|
const table = opt.table || this.cfg.table
|
|
788
799
|
const started = this.logStarted(op, table)
|
|
@@ -801,7 +812,7 @@ export class CommonDao<
|
|
|
801
812
|
opt: CommonDaoStreamForEachOptions<DBM> & { stream?: boolean } = {},
|
|
802
813
|
): Promise<number> {
|
|
803
814
|
this.requireWriteAccess()
|
|
804
|
-
if (!opt.
|
|
815
|
+
if (!opt.allowMutability) this.requireObjectMutability()
|
|
805
816
|
q.table = opt.table || q.table
|
|
806
817
|
const op = `deleteByQuery(${q.pretty()})`
|
|
807
818
|
const started = this.logStarted(op, q.table)
|
package/src/index.ts
CHANGED
|
@@ -36,7 +36,6 @@ import {
|
|
|
36
36
|
DBSaveBatchOperation,
|
|
37
37
|
RunQueryResult,
|
|
38
38
|
} from './db.model'
|
|
39
|
-
import { getDB } from './getDB'
|
|
40
39
|
import { CommonKeyValueDao, CommonKeyValueDaoCfg } from './kv/commonKeyValueDao'
|
|
41
40
|
import { CommonKeyValueDB, KeyValueDBTuple } from './kv/commonKeyValueDB'
|
|
42
41
|
import {
|
|
@@ -117,7 +116,6 @@ export {
|
|
|
117
116
|
dbPipelineBackup,
|
|
118
117
|
dbPipelineRestore,
|
|
119
118
|
dbPipelineCopy,
|
|
120
|
-
getDB,
|
|
121
119
|
DBLibError,
|
|
122
120
|
BaseCommonDB,
|
|
123
121
|
DBTransaction,
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { createGzip, ZlibOptions } from 'zlib'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AppError,
|
|
4
|
+
AsyncMapper,
|
|
5
|
+
ErrorMode,
|
|
6
|
+
pMap,
|
|
7
|
+
_passthroughMapper,
|
|
8
|
+
localTime,
|
|
9
|
+
} from '@naturalcycles/js-lib'
|
|
3
10
|
import {
|
|
4
11
|
NDJsonStats,
|
|
5
12
|
transformLogProgress,
|
|
@@ -11,7 +18,6 @@ import {
|
|
|
11
18
|
_pipeline,
|
|
12
19
|
} from '@naturalcycles/nodejs-lib'
|
|
13
20
|
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/dist/colors'
|
|
14
|
-
import { dayjs } from '@naturalcycles/time-lib'
|
|
15
21
|
import * as fs from 'fs-extra'
|
|
16
22
|
import { CommonDB } from '../common.db'
|
|
17
23
|
import { DBQuery } from '../index'
|
|
@@ -144,7 +150,7 @@ export async function dbPipelineBackup(opt: DBPipelineBackupOptions): Promise<ND
|
|
|
144
150
|
|
|
145
151
|
let { tables } = opt
|
|
146
152
|
|
|
147
|
-
const sinceUpdatedStr = sinceUpdated ? ' since ' + grey(
|
|
153
|
+
const sinceUpdatedStr = sinceUpdated ? ' since ' + grey(localTime(sinceUpdated).toPretty()) : ''
|
|
148
154
|
|
|
149
155
|
console.log(
|
|
150
156
|
`>> ${dimWhite('dbPipelineBackup')} started in ${grey(outputDirPath)}...${sinceUpdatedStr}`,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AsyncMapper, ErrorMode, pMap, _passthroughMapper } from '@naturalcycles/js-lib'
|
|
1
|
+
import { AsyncMapper, ErrorMode, pMap, _passthroughMapper, localTime } from '@naturalcycles/js-lib'
|
|
2
2
|
import {
|
|
3
3
|
NDJsonStats,
|
|
4
4
|
transformBuffer,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
_pipeline,
|
|
12
12
|
} from '@naturalcycles/nodejs-lib'
|
|
13
13
|
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/dist/colors'
|
|
14
|
-
import { dayjs } from '@naturalcycles/time-lib'
|
|
15
14
|
import { CommonDB } from '../common.db'
|
|
16
15
|
import { CommonDBSaveOptions } from '../db.model'
|
|
17
16
|
import { DBQuery } from '../query/dbQuery'
|
|
@@ -103,7 +102,7 @@ export async function dbPipelineCopy(opt: DBPipelineCopyOptions): Promise<NDJson
|
|
|
103
102
|
|
|
104
103
|
let { tables } = opt
|
|
105
104
|
|
|
106
|
-
const sinceUpdatedStr = sinceUpdated ? ' since ' + grey(
|
|
105
|
+
const sinceUpdatedStr = sinceUpdated ? ' since ' + grey(localTime(sinceUpdated).toPretty()) : ''
|
|
107
106
|
|
|
108
107
|
console.log(`>> ${dimWhite('dbPipelineCopy')} started...${sinceUpdatedStr}`)
|
|
109
108
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
_mapValues,
|
|
8
8
|
_passthroughMapper,
|
|
9
9
|
SavedDBEntity,
|
|
10
|
+
localTime,
|
|
10
11
|
} from '@naturalcycles/js-lib'
|
|
11
12
|
import {
|
|
12
13
|
NDJsonStats,
|
|
@@ -24,7 +25,6 @@ import {
|
|
|
24
25
|
_pipeline,
|
|
25
26
|
} from '@naturalcycles/nodejs-lib'
|
|
26
27
|
import { boldWhite, dimWhite, grey, yellow } from '@naturalcycles/nodejs-lib/dist/colors'
|
|
27
|
-
import { dayjs } from '@naturalcycles/time-lib'
|
|
28
28
|
import * as fs from 'fs-extra'
|
|
29
29
|
import { CommonDB } from '../common.db'
|
|
30
30
|
import { CommonDBSaveOptions } from '../index'
|
|
@@ -133,7 +133,7 @@ export async function dbPipelineRestore(opt: DBPipelineRestoreOptions): Promise<
|
|
|
133
133
|
const strict = errorMode !== ErrorMode.SUPPRESS
|
|
134
134
|
const onlyTables = opt.tables && new Set(opt.tables)
|
|
135
135
|
|
|
136
|
-
const sinceUpdatedStr = sinceUpdated ? ' since ' + grey(
|
|
136
|
+
const sinceUpdatedStr = sinceUpdated ? ' since ' + grey(localTime(sinceUpdated).toPretty()) : ''
|
|
137
137
|
|
|
138
138
|
console.log(
|
|
139
139
|
`>> ${dimWhite('dbPipelineRestore')} started in ${grey(inputDirPath)}...${sinceUpdatedStr}`,
|
package/dist/getDB.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { CommonDB } from './common.db';
|
|
2
|
-
/**
|
|
3
|
-
* Returns pre-configured DB
|
|
4
|
-
*
|
|
5
|
-
* @param index defaults to 1
|
|
6
|
-
*
|
|
7
|
-
* Requires process.env.DB${index} to be set to the name of the adapter, e.g `mysql-lib` or `db-lib/adapter/inmemory`.
|
|
8
|
-
* Requires (by most adapters) process.env.SECRET_DB${index} to contain a "connection string" to that DB. Usually a JSON.stringified object,
|
|
9
|
-
* but depends on the adapter.
|
|
10
|
-
*/
|
|
11
|
-
export declare function getDB(index?: number): CommonDB;
|
|
12
|
-
declare global {
|
|
13
|
-
namespace NodeJS {
|
|
14
|
-
interface ProcessEnv {
|
|
15
|
-
DB1?: string;
|
|
16
|
-
DB2?: string;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
package/dist/getDB.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getDB = void 0;
|
|
4
|
-
const js_lib_1 = require("@naturalcycles/js-lib");
|
|
5
|
-
const nodejs_lib_1 = require("@naturalcycles/nodejs-lib");
|
|
6
|
-
const colors_1 = require("@naturalcycles/nodejs-lib/dist/colors");
|
|
7
|
-
/**
|
|
8
|
-
* Returns pre-configured DB
|
|
9
|
-
*
|
|
10
|
-
* @param index defaults to 1
|
|
11
|
-
*
|
|
12
|
-
* Requires process.env.DB${index} to be set to the name of the adapter, e.g `mysql-lib` or `db-lib/adapter/inmemory`.
|
|
13
|
-
* Requires (by most adapters) process.env.SECRET_DB${index} to contain a "connection string" to that DB. Usually a JSON.stringified object,
|
|
14
|
-
* but depends on the adapter.
|
|
15
|
-
*/
|
|
16
|
-
function getDB(index = 1) {
|
|
17
|
-
return _getDB(index);
|
|
18
|
-
}
|
|
19
|
-
exports.getDB = getDB;
|
|
20
|
-
// Extra function to provide index=1 as default (since memo doesn't work well with default arguments)
|
|
21
|
-
const _getDB = (0, js_lib_1._memoFn)((index) => {
|
|
22
|
-
const libName = process.env[`DB${index}`];
|
|
23
|
-
if (!libName) {
|
|
24
|
-
throw new Error(`getDB(${(0, colors_1.yellow)(index)}), but process.env.${(0, colors_1.white)('DB' + index)} is not defined!`);
|
|
25
|
-
}
|
|
26
|
-
const lib = require(libName);
|
|
27
|
-
if (!lib.getDBAdapter) {
|
|
28
|
-
throw new Error(`DB${index}=${libName}, but require('${libName}').getDBAdapter() is not defined`);
|
|
29
|
-
}
|
|
30
|
-
const cfg = (0, nodejs_lib_1.secretOptional)(`SECRET_DB${index}`);
|
|
31
|
-
return lib.getDBAdapter(cfg);
|
|
32
|
-
});
|
package/src/getDB.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { _memoFn } from '@naturalcycles/js-lib'
|
|
2
|
-
import { secretOptional } from '@naturalcycles/nodejs-lib'
|
|
3
|
-
import { white, yellow } from '@naturalcycles/nodejs-lib/dist/colors'
|
|
4
|
-
import { CommonDB } from './common.db'
|
|
5
|
-
import { CommonDBAdapter } from './db.model'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Returns pre-configured DB
|
|
9
|
-
*
|
|
10
|
-
* @param index defaults to 1
|
|
11
|
-
*
|
|
12
|
-
* Requires process.env.DB${index} to be set to the name of the adapter, e.g `mysql-lib` or `db-lib/adapter/inmemory`.
|
|
13
|
-
* Requires (by most adapters) process.env.SECRET_DB${index} to contain a "connection string" to that DB. Usually a JSON.stringified object,
|
|
14
|
-
* but depends on the adapter.
|
|
15
|
-
*/
|
|
16
|
-
export function getDB(index = 1): CommonDB {
|
|
17
|
-
return _getDB(index)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Extra function to provide index=1 as default (since memo doesn't work well with default arguments)
|
|
21
|
-
const _getDB = _memoFn((index: number) => {
|
|
22
|
-
const libName = process.env[`DB${index}`]
|
|
23
|
-
|
|
24
|
-
if (!libName) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`getDB(${yellow(index)}), but process.env.${white('DB' + index)} is not defined!`,
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const lib: CommonDBAdapter = require(libName)
|
|
31
|
-
|
|
32
|
-
if (!lib.getDBAdapter) {
|
|
33
|
-
throw new Error(
|
|
34
|
-
`DB${index}=${libName}, but require('${libName}').getDBAdapter() is not defined`,
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const cfg = secretOptional(`SECRET_DB${index}`)
|
|
39
|
-
|
|
40
|
-
return lib.getDBAdapter(cfg)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
declare global {
|
|
44
|
-
namespace NodeJS {
|
|
45
|
-
interface ProcessEnv {
|
|
46
|
-
DB1?: string
|
|
47
|
-
DB2?: string
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|