Skip to content

Commit 691b2e3

Browse files
committed
feat: count query
1 parent 92adce3 commit 691b2e3

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

src/runtime/internal/query.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ export const collectionQureyBuilder = <T extends keyof Collections>(collection:
88
offset: 0,
99
limit: 0,
1010
orderBy: [] as Array<string>,
11+
// Count query
12+
count: {
13+
field: '' as keyof Collections[T] | '*',
14+
distinct: false,
15+
},
1116
}
1217

1318
const query: CollectionQueryBuilder<Collections[T]> = {
@@ -18,7 +23,7 @@ export const collectionQureyBuilder = <T extends keyof Collections>(collection:
1823
params.offset = skip
1924
return query
2025
},
21-
where(field: keyof Collections[T] | string, operator: SQLOperator, value: unknown): CollectionQueryBuilder<Collections[T]> {
26+
where(field: keyof Collections[T] | string, operator: SQLOperator, value?: unknown): CollectionQueryBuilder<Collections[T]> {
2227
let condition: string
2328

2429
switch (operator.toUpperCase()) {
@@ -77,13 +82,23 @@ export const collectionQureyBuilder = <T extends keyof Collections>(collection:
7782
return fetch(collection, buildQuery()).then(res => res || [])
7883
},
7984
async first(): Promise<Collections[T]> {
80-
return fetch(collection, buildQuery()).then(res => res[0] || null)
85+
return fetch(collection, buildQuery({ limit: 1 })).then(res => res[0] || null)
86+
},
87+
async count(field: keyof Collections[T] | '*' = '*', distinct: boolean = false) {
88+
return fetch(collection, buildQuery({
89+
count: { field: String(field), distinct },
90+
})).then(m => m[0].count)
8191
},
8292
}
8393

84-
function buildQuery() {
94+
function buildQuery(opts: { count?: { field: string, distinct: boolean }, limit?: number } = {}) {
8595
let query = 'SELECT '
86-
query += params.selectedFields.length > 0 ? params.selectedFields.map(f => `"${String(f)}"`).join(', ') : '*'
96+
if (opts?.count) {
97+
query += `COUNT(${opts.count.distinct ? 'DISTINCT' : ''} ${opts.count.field}) as count`
98+
}
99+
else {
100+
query += params.selectedFields.length > 0 ? params.selectedFields.map(f => `"${String(f)}"`).join(', ') : '*'
101+
}
87102
query += ` FROM ${tables[String(collection)]}`
88103

89104
if (params.conditions.length > 0) {
@@ -97,11 +112,12 @@ export const collectionQureyBuilder = <T extends keyof Collections>(collection:
97112
query += ` ORDER BY stem ASC`
98113
}
99114

100-
if (params.limit > 0) {
115+
const limit = opts?.limit || params.limit
116+
if (limit > 0) {
101117
if (params.offset > 0) {
102-
query += ` LIMIT ${params.limit} OFFSET ${params.offset}`
118+
query += ` LIMIT ${limit} OFFSET ${params.offset}`
103119
}
104-
query += ` LIMIT ${params.limit}`
120+
query += ` LIMIT ${limit}`
105121
}
106122

107123
return query

src/types/query.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ export type SQLOperator = '=' | '>' | '<' | '<>' | 'in' | 'BETWEEN' | 'NOT BETWE
22

33
export interface CollectionQueryBuilder<T> {
44
path(path: string): CollectionQueryBuilder<T>
5-
where(field: string, operator: SQLOperator, value: unknown): CollectionQueryBuilder<T>
5+
where(field: string, operator: SQLOperator, value?: unknown): CollectionQueryBuilder<T>
66
select<K extends keyof T>(...fields: K[]): CollectionQueryBuilder<Pick<T, K>>
77
order(field: keyof T, direction: 'ASC' | 'DESC'): CollectionQueryBuilder<T>
88
skip(skip: number): CollectionQueryBuilder<T>
99
limit(limit: number): CollectionQueryBuilder<T>
1010
all(): Promise<T[]>
1111
first(): Promise<T>
12+
count(field?: keyof T | '*', distinct?: boolean): Promise<number>
1213
}

0 commit comments

Comments
 (0)