()
| 15 | } |
| 16 | |
| 17 | export function createSqlBuilder() { |
| 18 | const join = (obj: Record<string, string> | string[], joiner: string) => |
| 19 | Object.values(obj).filter(Boolean).join(joiner); |
| 20 | |
| 21 | const sb: SqlBuilderObject = { |
| 22 | where: {}, |
| 23 | from: `${TABLE_NAMES.events} e`, |
| 24 | select: {}, |
| 25 | groupBy: {}, |
| 26 | orderBy: {}, |
| 27 | having: {}, |
| 28 | joins: {}, |
| 29 | ctes: {}, |
| 30 | limit: undefined, |
| 31 | offset: undefined, |
| 32 | fill: undefined, |
| 33 | }; |
| 34 | |
| 35 | const getWhere = () => |
| 36 | Object.keys(sb.where).length ? `WHERE ${join(sb.where, ' AND ')}` : ''; |
| 37 | const getHaving = () => |
| 38 | Object.keys(sb.having).length ? `HAVING ${join(sb.having, ' AND ')}` : ''; |
| 39 | const getFrom = () => `FROM ${sb.from}`; |
| 40 | const getSelect = () => |
| 41 | `SELECT ${Object.keys(sb.select).length ? join(sb.select, ', ') : '*'}`; |
| 42 | const getGroupBy = () => |
| 43 | Object.keys(sb.groupBy).length ? `GROUP BY ${join(sb.groupBy, ', ')}` : ''; |
| 44 | const getOrderBy = () => |
| 45 | Object.keys(sb.orderBy).length ? `ORDER BY ${join(sb.orderBy, ', ')}` : ''; |
| 46 | const getLimit = () => (sb.limit ? `LIMIT ${sb.limit}` : ''); |
| 47 | const getOffset = () => (sb.offset ? `OFFSET ${sb.offset}` : ''); |
| 48 | const getJoins = () => |
| 49 | Object.keys(sb.joins).length ? join(sb.joins, ' ') : ''; |
| 50 | const getFill = () => (sb.fill ? `WITH FILL ${sb.fill}` : ''); |
| 51 | const getWith = () => { |
| 52 | const cteEntries = Object.entries(sb.ctes); |
| 53 | if (cteEntries.length === 0) return ''; |
| 54 | const cteClauses = cteEntries.map( |
| 55 | ([name, query]) => `${name} AS (${query})`, |
| 56 | ); |
| 57 | return `WITH ${cteClauses.join(', ')} `; |
| 58 | }; |
| 59 | |
| 60 | return { |
| 61 | sb, |
| 62 | join, |
| 63 | getWhere, |
| 64 | getFrom, |
| 65 | getSelect, |
| 66 | getGroupBy, |
| 67 | getOrderBy, |
| 68 | getHaving, |
| 69 | getJoins, |
| 70 | getFill, |
| 71 | getWith, |
| 72 | with: (name: string, query: string) => { |
| 73 | sb.ctes[name] = query; |
| 74 | }, |
no test coverage detected