Skip to content

Commit f75794d

Browse files
committed
feat(postgres): add distinct & columns
1 parent 404eb54 commit f75794d

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

packages/postgres/src/interfaces/PgQuery.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
1-
import type { Static, TArray, TObject } from "@sinclair/typebox";
1+
import type { Static, TArray, TObject, TPick } from "@sinclair/typebox";
22
import type { SQLWrapper } from "drizzle-orm";
33
import type { PG_MANY } from "../constants/PG_SYMBOLS.ts";
44
import type { PgQueryWhere } from "./PgQueryWhere.ts";
55

6-
export interface PgQuery<T extends TObject> {
6+
export interface PgQuery<
7+
T extends TObject,
8+
Select extends (keyof Static<T>)[] = [],
9+
> {
10+
columns?: Select;
11+
distinct?: boolean;
712
where?: PgQueryWhereWithMany<T> | SQLWrapper;
813
limit?: number;
914
offset?: number;
1015
sort?: {
1116
[key in keyof Static<T>]?: "asc" | "desc";
1217
};
18+
groupBy?: (keyof Static<T>)[];
1319
relations?: PgQueryWithMap<T>;
1420
}
1521

22+
export type PgQueryResult<
23+
T extends TObject,
24+
Select extends (keyof Static<T>)[],
25+
> = TPick<T, Select>;
26+
1627
export type PgQueryWhereWithMany<T extends TObject> = PgQueryWhere<
1728
Static<RemoveManyRelations<T>>
1829
> &
@@ -55,6 +66,8 @@ export type PgQueryWith<T extends TObject | TArray> =
5566
| {
5667
// limit?: number;
5768
// offset?: number;
69+
// sort?:
70+
// columns?: (keyof Static<T>)[];
5871
relations?: {
5972
[key: string]: PgQueryWith<T>;
6073
};

packages/postgres/src/services/Repository.ts

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import type {
4141
PgTransaction,
4242
PgTransactionConfig,
4343
PgUpdateSetSource,
44+
SelectedFields,
4445
TableConfig,
4546
} from "drizzle-orm/pg-core";
4647
import { isSQLWrapper } from "drizzle-orm/sql/sql";
@@ -62,7 +63,7 @@ import { aggregateRowsByRelation } from "../helpers/relations.ts";
6263
import type { PgTableWithColumnsAndSchema } from "../helpers/schemaToColumns.ts";
6364
import type { FilterOperators } from "../interfaces/FilterOperators.ts";
6465
import type { InferInsert } from "../interfaces/InferInsert.ts";
65-
import type { PgQuery } from "../interfaces/PgQuery.ts";
66+
import type { PgQuery, PgQueryResult } from "../interfaces/PgQuery.ts";
6667
import type { PgQueryWhere } from "../interfaces/PgQueryWhere.ts";
6768
import type { SQLLike } from "../providers/drivers/PostgresProvider.ts";
6869
import { PostgresProvider } from "../providers/drivers/PostgresProvider.ts";
@@ -283,11 +284,31 @@ export class Repository<
283284
* @param opts The statement options.
284285
* @returns The found entities.
285286
*/
286-
public async find(
287-
query: PgQuery<TTableSchema> = {},
287+
public async find<Select extends (keyof Static<TTableSchema>)[]>(
288+
query: PgQuery<TTableSchema, Select> = {},
288289
opts: StatementOptions = {},
289-
): Promise<Static<TTableSchema>[]> {
290-
const builder = this.select(opts);
290+
): Promise<Static<PgQueryResult<TTableSchema, Select>>[]> {
291+
let schema: TObject | undefined;
292+
293+
if (typeof query.columns === "object") {
294+
schema = t.pick(this.schema, query.columns) as TObject;
295+
}
296+
297+
const builder = query.distinct
298+
? (opts.tx ?? this.db)
299+
.selectDistinct(
300+
typeof query.columns === "undefined"
301+
? {}
302+
: query.columns.reduce((acc, key) => {
303+
const col = this.col(key);
304+
return {
305+
...acc,
306+
[col.name]: col,
307+
};
308+
}, {} as SelectedFields),
309+
)
310+
.from(this.table as PgTable)
311+
: this.select(opts);
291312

292313
if (query.where) {
293314
if (isSQLWrapper(query.where)) {
@@ -314,6 +335,10 @@ export class Repository<
314335
);
315336
}
316337

338+
if (query.groupBy) {
339+
builder.groupBy(...query.groupBy.map((key) => this.col(key)));
340+
}
341+
317342
if (opts.for) {
318343
if (typeof opts.for === "string") {
319344
builder.for(opts.for);
@@ -331,7 +356,7 @@ export class Repository<
331356

332357
const pgManyFields = this.withJoins(
333358
builder,
334-
query,
359+
query as any,
335360
this.schema,
336361
this.id.col,
337362
);
@@ -340,11 +365,11 @@ export class Repository<
340365
.execute()
341366
.then((rows) => {
342367
if (pgManyFields.length) {
343-
return this.aggregateRows(rows, pgManyFields, query);
368+
return this.aggregateRows(rows, pgManyFields, query as any);
344369
}
345370
return rows;
346371
})
347-
.then((rows) => rows.map((row) => this.clean(row)));
372+
.then((rows) => rows.map((row) => this.clean(row, schema)));
348373
}
349374

350375
/**

0 commit comments

Comments
 (0)