I am trying to achieve a reuse pattern where query functions may receive a parameter trx=tx/task if they are participating in an existing transaction/task, and reuse that tx/task context... otherwise if trx=undefined passed in, creates a new task for the queries. The idea is for the function to be agnostic of whether it is being used singularly, or is participating in a higher-order block transaction.
What I desire (ideally) is a promise-function that will return a task context so that I can write clean like the following (which doesn't work):
async function trxRunQueries(trx:ITask<any>|undefined = undefined):Promise<any[]>
{
if(!trx)
trx=await db.task(); // if !trx then create new task context from db
const dataset1 = await trx.many(`select * from tableA`);
const dataset2 = await trx.many(`select * from tableB`);
return [dataset1,dataset2];
}
However seems like db.task() needs to execute the contextual queries in the cb parameter, but it leaves me hanging & wondering how I can achieve the desired pattern without writing the code out twice -- once with db.task(trx => ) wrapper, and another executing trx.many(...) directly.
I was wondering if it is ok to do something hacky, like below, to achieve this pattern of participating-optionally-in-a-transaction, and will it work (or is it really not a recommended way of doing things) -- or is there a better way that I am not thinking of?
async function runQueries(trx:ITask<any>):Promise<any[]>
{
const dataset1 = await trx.many(`select * from tableA`);
const dataset2 = await trx.many(`select * from tableB`);
return [dataset1,dataset2];
}
async function trxRunQueries(trx:ITask<any>|undefined = undefined ):Promise<any[]>
{
let result:any[]=[];
try {
// If trx not passed in the create task context
if(!trx)
await db.task(async trx => {result=await runQueries(trx)})
else
result=await runQueries(trx);
return result;
}
catch (err) {
throw(err);
}
}
Such pattern is implemented by pg-promise-demo, which uses event extend to extend the database protocol with context-agnostic entity repositories.