@naturalcycles/db-lib
Advanced tools
Comparing version 9.6.0 to 9.7.0
@@ -22,3 +22,2 @@ /// <reference types="node" /> | ||
getByIdOrEmpty(id: string, part?: Partial<BM>, opt?: CommonDaoOptions): Promise<BM>; | ||
getByIdAsDBMOrEmpty(id: string, part?: Partial<BM>, opt?: CommonDaoOptions): Promise<DBM>; | ||
getByIdAsDBM(id: undefined | null, opt?: CommonDaoOptions): Promise<null>; | ||
@@ -84,6 +83,2 @@ getByIdAsDBM(id?: string | null, opt?: CommonDaoOptions): Promise<DBM | null>; | ||
/** | ||
* Mutates with id, created, updated | ||
*/ | ||
save(bm: Unsaved<BM>, opt?: CommonDaoSaveOptions<BM, DBM>): Promise<BM>; | ||
/** | ||
* 1. Applies the patch | ||
@@ -122,3 +117,7 @@ * 2. If object is the same after patching - skips saving it | ||
patchInTransaction(bm: BM, patch: Partial<BM>, opt?: CommonDaoSaveBatchOptions<DBM>): Promise<BM>; | ||
saveAsDBM(dbm: Unsaved<DBM>, opt?: CommonDaoSaveBatchOptions<DBM>): Promise<DBM>; | ||
/** | ||
* Mutates with id, created, updated | ||
*/ | ||
save(bm: Unsaved<BM>, opt?: CommonDaoSaveOptions<BM, DBM>): Promise<BM>; | ||
saveAsDBM(dbm: Unsaved<DBM>, opt?: CommonDaoSaveOptions<BM, DBM>): Promise<DBM>; | ||
saveBatch(bms: Unsaved<BM>[], opt?: CommonDaoSaveBatchOptions<DBM>): Promise<BM[]>; | ||
@@ -136,3 +135,2 @@ saveBatchAsDBM(dbms: Unsaved<DBM>[], opt?: CommonDaoSaveBatchOptions<DBM>): Promise<DBM[]>; | ||
*/ | ||
deleteById(id: undefined | null, opt?: CommonDaoOptions): Promise<0>; | ||
deleteById(id?: string | null, opt?: CommonDaoOptions): Promise<number>; | ||
@@ -201,6 +199,14 @@ deleteByIds(ids: string[], opt?: CommonDaoOptions): Promise<number>; | ||
getByIds<BM extends BaseDBEntity, DBM extends BaseDBEntity>(dao: CommonDao<BM, DBM>, ids: string[], opt?: CommonDaoOptions): Promise<BM[]>; | ||
save<BM extends BaseDBEntity, DBM extends BaseDBEntity>(dao: CommonDao<BM, DBM>, bm: Unsaved<BM>, opt?: CommonDaoSaveBatchOptions<DBM>): Promise<BM>; | ||
save<BM extends BaseDBEntity, DBM extends BaseDBEntity>(dao: CommonDao<BM, DBM>, bm: Unsaved<BM>, opt?: CommonDaoSaveOptions<BM, DBM>): Promise<BM>; | ||
saveBatch<BM extends BaseDBEntity, DBM extends BaseDBEntity>(dao: CommonDao<BM, DBM>, bms: Unsaved<BM>[], opt?: CommonDaoSaveBatchOptions<DBM>): Promise<BM[]>; | ||
/** | ||
* DaoTransaction.patch does not load from DB. | ||
* It assumes the bm was previously loaded in the same Transaction, hence could not be | ||
* concurrently modified. Hence it's safe to not sync with DB. | ||
* | ||
* So, this method is a rather simple convenience "Object.assign and then save". | ||
*/ | ||
patch<BM extends BaseDBEntity, DBM extends BaseDBEntity>(dao: CommonDao<BM, DBM>, bm: BM, patch: Partial<BM>, opt?: CommonDaoSaveOptions<BM, DBM>): Promise<BM>; | ||
deleteById(dao: CommonDao<any>, id?: string | null, opt?: CommonDaoOptions): Promise<number>; | ||
deleteByIds(dao: CommonDao<any>, ids: string[], opt?: CommonDaoOptions): Promise<number>; | ||
} |
@@ -74,9 +74,2 @@ "use strict"; | ||
} | ||
async getByIdAsDBMOrEmpty(id, part = {}, opt) { | ||
const dbm = await this.getByIdAsDBM(id, opt); | ||
if (dbm) | ||
return dbm; | ||
const bm = this.create({ ...part, id }, opt); | ||
return await this.bmToDBM(bm, opt); | ||
} | ||
async getByIdAsDBM(id, opt = {}) { | ||
@@ -456,41 +449,2 @@ if (!id) | ||
/** | ||
* Mutates with id, created, updated | ||
*/ | ||
async save(bm, opt = {}) { | ||
this.requireWriteAccess(); | ||
if (opt.skipIfEquals && (0, js_lib_1._deepJsonEquals)(bm, opt.skipIfEquals)) { | ||
// Skipping the save operation | ||
return bm; | ||
} | ||
const idWasGenerated = !bm.id && this.cfg.generateId; | ||
this.assignIdCreatedUpdated(bm, opt); // mutates | ||
(0, js_lib_1._typeCast)(bm); | ||
let dbm = await this.bmToDBM(bm, opt); // validates BM | ||
if (this.cfg.hooks.beforeSave) { | ||
dbm = (await this.cfg.hooks.beforeSave(dbm)); | ||
if (dbm === null) | ||
return bm; | ||
} | ||
const table = opt.table || this.cfg.table; | ||
if (opt.ensureUniqueId && idWasGenerated) | ||
await this.ensureUniqueId(table, dbm); | ||
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) { | ||
opt = { ...opt, saveMethod: 'insert' }; | ||
} | ||
const op = `save(${dbm.id})`; | ||
const started = this.logSaveStarted(op, bm, table); | ||
const { excludeFromIndexes } = this.cfg; | ||
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds; | ||
await (opt.tx || this.cfg.db).saveBatch(table, [dbm], { | ||
excludeFromIndexes, | ||
assignGeneratedIds, | ||
...opt, | ||
}); | ||
if (assignGeneratedIds) { | ||
bm.id = dbm.id; | ||
} | ||
this.logSaveResult(started, op, table); | ||
return bm; | ||
} | ||
/** | ||
* 1. Applies the patch | ||
@@ -590,2 +544,41 @@ * 2. If object is the same after patching - skips saving it | ||
} | ||
/** | ||
* Mutates with id, created, updated | ||
*/ | ||
async save(bm, opt = {}) { | ||
this.requireWriteAccess(); | ||
if (opt.skipIfEquals && (0, js_lib_1._deepJsonEquals)(bm, opt.skipIfEquals)) { | ||
// Skipping the save operation | ||
return bm; | ||
} | ||
const idWasGenerated = !bm.id && this.cfg.generateId; | ||
this.assignIdCreatedUpdated(bm, opt); // mutates | ||
(0, js_lib_1._typeCast)(bm); | ||
let dbm = await this.bmToDBM(bm, opt); // validates BM | ||
if (this.cfg.hooks.beforeSave) { | ||
dbm = (await this.cfg.hooks.beforeSave(dbm)); | ||
if (dbm === null) | ||
return bm; | ||
} | ||
const table = opt.table || this.cfg.table; | ||
if (opt.ensureUniqueId && idWasGenerated) | ||
await this.ensureUniqueId(table, dbm); | ||
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) { | ||
opt = { ...opt, saveMethod: 'insert' }; | ||
} | ||
const op = `save(${dbm.id})`; | ||
const started = this.logSaveStarted(op, bm, table); | ||
const { excludeFromIndexes } = this.cfg; | ||
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds; | ||
await (opt.tx || this.cfg.db).saveBatch(table, [dbm], { | ||
excludeFromIndexes, | ||
assignGeneratedIds, | ||
...opt, | ||
}); | ||
if (assignGeneratedIds) { | ||
bm.id = dbm.id; | ||
} | ||
this.logSaveResult(started, op, table); | ||
return bm; | ||
} | ||
async saveAsDBM(dbm, opt = {}) { | ||
@@ -742,13 +735,10 @@ this.requireWriteAccess(); | ||
} | ||
// DELETE | ||
/** | ||
* @returns number of deleted items | ||
*/ | ||
async deleteById(id, opt = {}) { | ||
if (!id) | ||
return 0; | ||
this.requireWriteAccess(); | ||
this.requireObjectMutability(opt); | ||
const op = `deleteById(${id})`; | ||
const table = opt.table || this.cfg.table; | ||
const started = this.logStarted(op, table); | ||
const count = await this.cfg.db.deleteByIds(table, [id], opt); | ||
this.logSaveResult(started, op, table); | ||
return count; | ||
return await this.deleteByIds([id], opt); | ||
} | ||
@@ -1067,3 +1057,3 @@ async deleteByIds(ids, opt = {}) { | ||
async save(dao, bm, opt) { | ||
return (await this.saveBatch(dao, [bm], opt))[0]; | ||
return await dao.save(bm, { ...opt, tx: this.tx }); | ||
} | ||
@@ -1073,2 +1063,14 @@ async saveBatch(dao, bms, opt) { | ||
} | ||
/** | ||
* DaoTransaction.patch does not load from DB. | ||
* It assumes the bm was previously loaded in the same Transaction, hence could not be | ||
* concurrently modified. Hence it's safe to not sync with DB. | ||
* | ||
* So, this method is a rather simple convenience "Object.assign and then save". | ||
*/ | ||
async patch(dao, bm, patch, opt) { | ||
const skipIfEquals = (0, js_lib_1._deepCopy)(bm); | ||
Object.assign(bm, patch); | ||
return await dao.save(bm, { ...opt, skipIfEquals, tx: this.tx }); | ||
} | ||
async deleteById(dao, id, opt) { | ||
@@ -1075,0 +1077,0 @@ if (!id) |
{ | ||
"name": "@naturalcycles/db-lib", | ||
"scripts": { | ||
"prepare": "husky install" | ||
"prepare": "husky" | ||
}, | ||
@@ -43,3 +43,3 @@ "dependencies": { | ||
}, | ||
"version": "9.6.0", | ||
"version": "9.7.0", | ||
"description": "Lowest Common Denominator API to supported Databases", | ||
@@ -46,0 +46,0 @@ "keywords": [ |
import { Transform } from 'node:stream' | ||
import { | ||
_assert, | ||
_deepCopy, | ||
_deepJsonEquals, | ||
@@ -134,14 +135,2 @@ _filterUndefinedValues, | ||
async getByIdAsDBMOrEmpty( | ||
id: string, | ||
part: Partial<BM> = {}, | ||
opt?: CommonDaoOptions, | ||
): Promise<DBM> { | ||
const dbm = await this.getByIdAsDBM(id, opt) | ||
if (dbm) return dbm | ||
const bm = this.create({ ...part, id }, opt) | ||
return await this.bmToDBM(bm, opt) | ||
} | ||
async getByIdAsDBM(id: undefined | null, opt?: CommonDaoOptions): Promise<null> | ||
@@ -620,47 +609,2 @@ async getByIdAsDBM(id?: string | null, opt?: CommonDaoOptions): Promise<DBM | null> | ||
/** | ||
* Mutates with id, created, updated | ||
*/ | ||
async save(bm: Unsaved<BM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<BM> { | ||
this.requireWriteAccess() | ||
if (opt.skipIfEquals && _deepJsonEquals(bm, opt.skipIfEquals)) { | ||
// Skipping the save operation | ||
return bm as BM | ||
} | ||
const idWasGenerated = !bm.id && this.cfg.generateId | ||
this.assignIdCreatedUpdated(bm, opt) // mutates | ||
_typeCast<BM>(bm) | ||
let dbm = await this.bmToDBM(bm, opt) // validates BM | ||
if (this.cfg.hooks!.beforeSave) { | ||
dbm = (await this.cfg.hooks!.beforeSave(dbm))! | ||
if (dbm === null) return bm | ||
} | ||
const table = opt.table || this.cfg.table | ||
if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, dbm) | ||
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) { | ||
opt = { ...opt, saveMethod: 'insert' } | ||
} | ||
const op = `save(${dbm.id})` | ||
const started = this.logSaveStarted(op, bm, table) | ||
const { excludeFromIndexes } = this.cfg | ||
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds | ||
await (opt.tx || this.cfg.db).saveBatch(table, [dbm], { | ||
excludeFromIndexes, | ||
assignGeneratedIds, | ||
...opt, | ||
}) | ||
if (assignGeneratedIds) { | ||
bm.id = dbm.id | ||
} | ||
this.logSaveResult(started, op, table) | ||
return bm | ||
} | ||
/** | ||
* 1. Applies the patch | ||
@@ -787,6 +731,51 @@ * 2. If object is the same after patching - skips saving it | ||
async saveAsDBM(dbm: Unsaved<DBM>, opt: CommonDaoSaveBatchOptions<DBM> = {}): Promise<DBM> { | ||
/** | ||
* Mutates with id, created, updated | ||
*/ | ||
async save(bm: Unsaved<BM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<BM> { | ||
this.requireWriteAccess() | ||
if (opt.skipIfEquals && _deepJsonEquals(bm, opt.skipIfEquals)) { | ||
// Skipping the save operation | ||
return bm as BM | ||
} | ||
const idWasGenerated = !bm.id && this.cfg.generateId | ||
this.assignIdCreatedUpdated(bm, opt) // mutates | ||
_typeCast<BM>(bm) | ||
let dbm = await this.bmToDBM(bm, opt) // validates BM | ||
if (this.cfg.hooks!.beforeSave) { | ||
dbm = (await this.cfg.hooks!.beforeSave(dbm))! | ||
if (dbm === null) return bm | ||
} | ||
const table = opt.table || this.cfg.table | ||
if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, dbm) | ||
if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) { | ||
opt = { ...opt, saveMethod: 'insert' } | ||
} | ||
const op = `save(${dbm.id})` | ||
const started = this.logSaveStarted(op, bm, table) | ||
const { excludeFromIndexes } = this.cfg | ||
const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds | ||
await (opt.tx || this.cfg.db).saveBatch(table, [dbm], { | ||
excludeFromIndexes, | ||
assignGeneratedIds, | ||
...opt, | ||
}) | ||
if (assignGeneratedIds) { | ||
bm.id = dbm.id | ||
} | ||
this.logSaveResult(started, op, table) | ||
return bm | ||
} | ||
async saveAsDBM(dbm: Unsaved<DBM>, opt: CommonDaoSaveOptions<BM, DBM> = {}): Promise<DBM> { | ||
this.requireWriteAccess() | ||
const table = opt.table || this.cfg.table | ||
// assigning id in case it misses the id | ||
@@ -985,14 +974,5 @@ // will override/set `updated` field, unless opts.preserveUpdated is set | ||
*/ | ||
async deleteById(id: undefined | null, opt?: CommonDaoOptions): Promise<0> | ||
async deleteById(id?: string | null, opt?: CommonDaoOptions): Promise<number> | ||
async deleteById(id?: string | null, opt: CommonDaoOptions = {}): Promise<number> { | ||
if (!id) return 0 | ||
this.requireWriteAccess() | ||
this.requireObjectMutability(opt) | ||
const op = `deleteById(${id})` | ||
const table = opt.table || this.cfg.table | ||
const started = this.logStarted(op, table) | ||
const count = await this.cfg.db.deleteByIds(table, [id], opt) | ||
this.logSaveResult(started, op, table) | ||
return count | ||
return await this.deleteByIds([id], opt) | ||
} | ||
@@ -1402,5 +1382,5 @@ | ||
bm: Unsaved<BM>, | ||
opt?: CommonDaoSaveBatchOptions<DBM>, | ||
opt?: CommonDaoSaveOptions<BM, DBM>, | ||
): Promise<BM> { | ||
return (await this.saveBatch(dao, [bm], opt))[0]! | ||
return await dao.save(bm, { ...opt, tx: this.tx }) | ||
} | ||
@@ -1416,2 +1396,20 @@ | ||
/** | ||
* DaoTransaction.patch does not load from DB. | ||
* It assumes the bm was previously loaded in the same Transaction, hence could not be | ||
* concurrently modified. Hence it's safe to not sync with DB. | ||
* | ||
* So, this method is a rather simple convenience "Object.assign and then save". | ||
*/ | ||
async patch<BM extends BaseDBEntity, DBM extends BaseDBEntity>( | ||
dao: CommonDao<BM, DBM>, | ||
bm: BM, | ||
patch: Partial<BM>, | ||
opt?: CommonDaoSaveOptions<BM, DBM>, | ||
): Promise<BM> { | ||
const skipIfEquals = _deepCopy(bm) | ||
Object.assign(bm, patch) | ||
return await dao.save(bm, { ...opt, skipIfEquals, tx: this.tx }) | ||
} | ||
async deleteById( | ||
@@ -1418,0 +1416,0 @@ dao: CommonDao<any>, |
418303
11008