-
Notifications
You must be signed in to change notification settings - Fork 382
Open
Labels
apiRelated to library's APIRelated to library's APIenhancementNew feature or requestNew feature or request
Description
I have a helper function that takes a baseQuery: SelectQueryBuilder and paginates it, returning two queries: one with limit/offset, and another that selects a count.
To make this resilient to GROUP BY clauses in the baseQuery, I want to do
countQuery = db.selectFrom(baseQuery.as("__base")).select(eb => eb.fn.countAll().as("count"))But—unless I'm mistaken, this will "remove" the count query from whatever transaction the baseQuery might be part of. That is, the following does not work as desired (every query in the same transaction):
db.transaction().execute((tx) => {
const baseQuery = tx.selectFrom(...)
const { pageQuery, countQuery } = paginate(baseQuery);
// Not actually in the transaction (I think).
countQuery.execute()
})To address this, I either have to thread tx into the paginate function, or I can do a trick with baseQuery.withPlugin() to wrap:
const countQuery = baseQuery.withPlugin({
transformQuery(args) {
const baseQuery = new ExpressionWrapper(args.node);
const eb = expressionBuilder();
const countQuery = eb.selectFrom(baseQuery.as('__base')).select(eb => eb.fn.countAll().as('count'));
return countQuery.toOperationNode();
},
async transformResult(args) {
return args.result;
}
});which I think works.
It would be nice to have some canonical solution to this. A few initial ideas:
- Add
SelectQueryBuilder.wrap():baseQuery.wrap((eb, query) => eb.selectFrom(query)...) - Expose
SelectQueryBuilder.dbor something like it - Accept an optional argument in
execute()that lets you pin the execution to a given transaction.
Thanks for reading! Kysely is so awesome 😄
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
apiRelated to library's APIRelated to library's APIenhancementNew feature or requestNew feature or request