Skip to content

Commit

Permalink
Add 'distinct' clause
Browse files Browse the repository at this point in the history
  • Loading branch information
manelcecs committed Aug 6, 2024
1 parent 016bb6b commit 65a279b
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/db/util/raw-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ export type FindFn<F extends FieldDefinition, AdditionalArgs = {}> = (
*/
skipValidation?: boolean;
trx?: Knex.Transaction<any, any>;
/**
* Uses `DISTINCT ON`, which is a feature unique to PostgreSQL.
*
* Keeps only the first row of each set of rows where the given (set of) column(s) is unique.
* Note that the “first row” of each set is unpredictable unless `ORDER BY` is used to
* ensure that the desired row appears first. If ordering is used, there is an important
* constraint, because the first expression of `ORDER BY` must be present **somewhere** in
* `DISTINCT ON` expressions. But, not all expressions of `ORDER BY` need to be in `DISTINCT ON`.
*/
distinct?: Array<keyof InstanceDataOf<F>>;
} & AdditionalArgs
) => Promise<Array<InstanceDataOf<F>>>;

Expand Down Expand Up @@ -160,6 +170,7 @@ export const defineRawModel =
orderBy,
skipValidation = false,
trx,
distinct,
} = {}) => {
const builder = trx ? masterTable().transacting(trx) : replicaTable();
const query = builder.where(prepareCondition(where ?? {})).select('*');
Expand All @@ -179,6 +190,18 @@ export const defineRawModel =
query.orderBy(orderBy);
}

if (distinct && distinct.length >= 1) {
if (
(orderBy?.length ?? 0) >= 1 &&
orderBy?.at(0)?.column !== distinct.at(0)
) {
throw new Error(
'SELECT DISTINCT ON expressions must match initial ORDER BY expression'
);
}
query.distinctOn(distinct);
}

const res = await query;

if (skipValidation) {
Expand Down

0 comments on commit 65a279b

Please sign in to comment.