Skip to content

Commit

Permalink
feat: count query
Browse files Browse the repository at this point in the history
  • Loading branch information
farnabaz committed Nov 5, 2024
1 parent 92adce3 commit 691b2e3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
30 changes: 23 additions & 7 deletions src/runtime/internal/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export const collectionQureyBuilder = <T extends keyof Collections>(collection:
offset: 0,
limit: 0,
orderBy: [] as Array<string>,
// Count query
count: {
field: '' as keyof Collections[T] | '*',
distinct: false,
},
}

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

switch (operator.toUpperCase()) {
Expand Down Expand Up @@ -77,13 +82,23 @@ export const collectionQureyBuilder = <T extends keyof Collections>(collection:
return fetch(collection, buildQuery()).then(res => res || [])
},
async first(): Promise<Collections[T]> {
return fetch(collection, buildQuery()).then(res => res[0] || null)
return fetch(collection, buildQuery({ limit: 1 })).then(res => res[0] || null)
},
async count(field: keyof Collections[T] | '*' = '*', distinct: boolean = false) {
return fetch(collection, buildQuery({
count: { field: String(field), distinct },
})).then(m => m[0].count)
},
}

function buildQuery() {
function buildQuery(opts: { count?: { field: string, distinct: boolean }, limit?: number } = {}) {
let query = 'SELECT '
query += params.selectedFields.length > 0 ? params.selectedFields.map(f => `"${String(f)}"`).join(', ') : '*'
if (opts?.count) {
query += `COUNT(${opts.count.distinct ? 'DISTINCT' : ''} ${opts.count.field}) as count`
}
else {
query += params.selectedFields.length > 0 ? params.selectedFields.map(f => `"${String(f)}"`).join(', ') : '*'
}
query += ` FROM ${tables[String(collection)]}`

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

if (params.limit > 0) {
const limit = opts?.limit || params.limit
if (limit > 0) {
if (params.offset > 0) {
query += ` LIMIT ${params.limit} OFFSET ${params.offset}`
query += ` LIMIT ${limit} OFFSET ${params.offset}`
}
query += ` LIMIT ${params.limit}`
query += ` LIMIT ${limit}`
}

return query
Expand Down
3 changes: 2 additions & 1 deletion src/types/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ export type SQLOperator = '=' | '>' | '<' | '<>' | 'in' | 'BETWEEN' | 'NOT BETWE

export interface CollectionQueryBuilder<T> {
path(path: string): CollectionQueryBuilder<T>
where(field: string, operator: SQLOperator, value: unknown): CollectionQueryBuilder<T>
where(field: string, operator: SQLOperator, value?: unknown): CollectionQueryBuilder<T>
select<K extends keyof T>(...fields: K[]): CollectionQueryBuilder<Pick<T, K>>
order(field: keyof T, direction: 'ASC' | 'DESC'): CollectionQueryBuilder<T>
skip(skip: number): CollectionQueryBuilder<T>
limit(limit: number): CollectionQueryBuilder<T>
all(): Promise<T[]>
first(): Promise<T>
count(field?: keyof T | '*', distinct?: boolean): Promise<number>
}

0 comments on commit 691b2e3

Please sign in to comment.