Skip to content
This repository was archived by the owner on May 25, 2025. It is now read-only.

Commit bc27d6b

Browse files
feat: support DISTINCT and GROUP BY
1 parent ef8eaab commit bc27d6b

File tree

3 files changed

+832
-925
lines changed

3 files changed

+832
-925
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"devDependencies": {
1414
"@naturalcycles/dev-lib": "^12.7.5",
1515
"@types/node": "^17.0.5",
16-
"dotenv": "^10.0.0",
16+
"dotenv": "^14.1.0",
1717
"jest": "^27.2.4"
1818
},
1919
"files": [

src/query.util.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function dbQueryToSQLSelect(q: DBQuery<any>): string {
1616
tokens.push(...whereTokens(q))
1717

1818
// order
19-
tokens.push(...orderTokens(q))
19+
tokens.push(...groupOrderTokens(q))
2020

2121
// offset/limit
2222
tokens.push(...offsetLimitTokens(q))
@@ -155,7 +155,13 @@ function selectTokens(q: DBQuery): string[] {
155155
}
156156

157157
// We don't do `escapeId` cause it'll ruin e.g SELECT `count *` FROM ...
158-
return [`SELECT`, fields.map(f => mapNameToMySQL(f)).join(', '), `FROM`, mysql.escapeId(q.table)]
158+
return [
159+
`SELECT`,
160+
q._distinct && ('DISTINCT' as any),
161+
fields.map(f => mapNameToMySQL(f)).join(', '),
162+
`FROM`,
163+
mysql.escapeId(q.table),
164+
].filter(Boolean)
159165
}
160166

161167
function offsetLimitTokens(q: DBQuery<any>): string[] {
@@ -173,12 +179,21 @@ function offsetLimitTokens(q: DBQuery<any>): string[] {
173179
return tokens
174180
}
175181

176-
function orderTokens(q: DBQuery): string[] {
177-
if (!q._orders.length) return []
178-
return [
179-
`ORDER BY`,
180-
q._orders.map(o => `\`${o.name}\` ${o.descending ? 'DESC' : 'ASC'}`).join(', '),
181-
]
182+
function groupOrderTokens(q: DBQuery): string[] {
183+
const t: string[] = []
184+
185+
if (q._groupByFieldNames?.length) {
186+
t.push(`GROUP BY`, q._groupByFieldNames.map(c => `\`${c}\``).join(', '))
187+
}
188+
189+
if (q._orders.length) {
190+
t.push(
191+
`ORDER BY`,
192+
q._orders.map(o => `\`${o.name}\` ${o.descending ? 'DESC' : 'ASC'}`).join(', '),
193+
)
194+
}
195+
196+
return t
182197
}
183198

184199
const OP_MAP: Partial<Record<DBQueryFilterOperator, string>> = {

0 commit comments

Comments
 (0)