diff --git a/src/db/util/raw-model.ts b/src/db/util/raw-model.ts index 0d9951b9..19dee3b7 100644 --- a/src/db/util/raw-model.ts +++ b/src/db/util/raw-model.ts @@ -75,6 +75,14 @@ export type DestroyFn = (args: { export type TruncateFn = (trx?: Knex.Transaction) => Promise; +export type CountFn = ( + args?: { + where?: WhereCond; + trx?: Knex.Transaction; + distinct?: Array>; + } & AdditionalArgs +) => Promise; + export type ModelInternals = { readonly type: 'single-table'; readonly tableName: string; @@ -94,6 +102,7 @@ export type Model = { readonly update: UpdateFn; readonly destroy: DestroyFn; readonly truncate: TruncateFn; + readonly count: CountFn; }; export type InstanceDataOfModel> = M extends Model @@ -254,6 +263,25 @@ export const defineRawModel = await builder.truncate(); }; + const count: CountFn = async ({ where, trx, distinct } = {}) => { + const builder = trx ? masterTable().transacting(trx) : replicaTable(); + const query = builder.where(prepareCondition(where ?? {})); + + if (distinct !== undefined) { + query.countDistinct(distinct); + } else { + query.count('*'); + } + + const res = await query; + + const mappedResponse = res as Array<{ count: string }>; + + return mappedResponse.length > 0 + ? parseInt(mappedResponse[0].count, 10) + : 0; + }; + return { _internals: { type: 'single-table', @@ -268,5 +296,6 @@ export const defineRawModel = update, destroy, truncate, + count, }; };