@naturalcycles/db-lib
Version:
Lowest Common Denominator API to supported Databases
79 lines (78 loc) • 2.42 kB
JavaScript
import { _deepCopy } from '@naturalcycles/js-lib/object';
/**
* Transaction context.
* Has similar API than CommonDao, but all operations are performed in the context of the transaction.
*/
export class CommonDaoTransaction {
tx;
logger;
constructor(tx, logger) {
this.tx = tx;
this.logger = logger;
}
/**
* Commits the underlying DBTransaction.
* May throw.
*/
async commit() {
await this.tx.commit();
}
/**
* Perform a graceful rollback without throwing/re-throwing any error.
* Never throws.
*/
async rollback() {
try {
await this.tx.rollback();
}
catch (err) {
// graceful rollback without re-throw
this.logger.error(err);
}
}
async getById(dao, id, opt) {
return await dao.getById(id, { ...opt, tx: this.tx });
}
async getByIds(dao, ids, opt) {
return await dao.getByIds(ids, { ...opt, tx: this.tx });
}
// todo: Queries inside Transaction are not supported yet
// async runQuery<BM extends PartialObjectWithId, DBM extends ObjectWithId>(
// dao: CommonDao<BM, DBM, any>,
// q: DBQuery<DBM>,
// opt?: CommonDaoOptions,
// ): Promise<BM[]> {
// try {
// return await dao.runQuery(q, { ...opt, tx: this.tx })
// } catch (err) {
// await this.rollback()
// throw err
// }
// }
async save(dao, bm, opt) {
return await dao.save(bm, { ...opt, tx: this.tx });
}
async saveBatch(dao, bms, opt) {
return await dao.saveBatch(bms, { ...opt, tx: this.tx });
}
/**
* 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 = _deepCopy(bm);
Object.assign(bm, patch);
return await dao.save(bm, { ...opt, skipIfEquals, tx: this.tx });
}
async deleteById(dao, id, opt) {
if (!id)
return 0;
return await this.deleteByIds(dao, [id], opt);
}
async deleteByIds(dao, ids, opt) {
return await dao.deleteByIds(ids, { ...opt, tx: this.tx });
}
}