( pg: PGliteInterface, query: string, params?: any[] | null, tx?: Transaction | PGliteInterface, )
| 130 | * @returns The formatted query |
| 131 | */ |
| 132 | export async function formatQuery( |
| 133 | pg: PGliteInterface, |
| 134 | query: string, |
| 135 | params?: any[] | null, |
| 136 | tx?: Transaction | PGliteInterface, |
| 137 | ) { |
| 138 | if (!params || params.length === 0) { |
| 139 | // no params so no formatting needed |
| 140 | return query |
| 141 | } |
| 142 | |
| 143 | tx = tx ?? pg |
| 144 | |
| 145 | // Get the types of the parameters |
| 146 | let dataTypeIDs: number[] |
| 147 | try { |
| 148 | await pg.execProtocol(serializeProtocol.parse({ text: query }), { |
| 149 | syncToFs: false, |
| 150 | }) |
| 151 | |
| 152 | dataTypeIDs = parseDescribeStatementResults( |
| 153 | ( |
| 154 | await pg.execProtocol(serializeProtocol.describe({ type: 'S' }), { |
| 155 | syncToFs: false, |
| 156 | }) |
| 157 | ).messages, |
| 158 | ) |
| 159 | } finally { |
| 160 | await pg.execProtocol(serializeProtocol.sync(), { syncToFs: false }) |
| 161 | } |
| 162 | |
| 163 | // replace $1, $2, etc with %1L, %2L, etc |
| 164 | const subbedQuery = query.replace(/\$([0-9]+)/g, (_, num) => { |
| 165 | return '%' + num + 'L' |
| 166 | }) |
| 167 | |
| 168 | const ret = await tx.query<{ |
| 169 | query: string |
| 170 | }>( |
| 171 | `SELECT format($1, ${params.map((_, i) => `$${i + 2}`).join(', ')}) as query`, |
| 172 | [subbedQuery, ...params], |
| 173 | { paramTypes: [TEXT, ...dataTypeIDs] }, |
| 174 | ) |
| 175 | return ret.rows[0].query |
| 176 | } |
| 177 | |
| 178 | /** |
| 179 | * Debounce a function to ensure that only one instance of the function is running at |
no test coverage detected