| 121 | } |
| 122 | |
| 123 | function printTable( |
| 124 | rows: Record<string, unknown>[], |
| 125 | finalSql: string, |
| 126 | format?: string, |
| 127 | ) { |
| 128 | if (format === "json") { |
| 129 | console.log( |
| 130 | JSON.stringify({ query: finalSql, rows, count: rows.length }, null, 2), |
| 131 | ); |
| 132 | return; |
| 133 | } |
| 134 | |
| 135 | console.log(`Query: ${finalSql}`); |
| 136 | console.log(`Rows: ${rows.length}\n`); |
| 137 | |
| 138 | if (rows.length === 0) { |
| 139 | console.log("(no results)"); |
| 140 | return; |
| 141 | } |
| 142 | |
| 143 | const keys = Object.keys(rows[0]); |
| 144 | const widths = keys.map((k) => { |
| 145 | const maxVal = Math.max(...rows.map((r) => String(r[k] ?? "NULL").length)); |
| 146 | return Math.max(k.length, Math.min(maxVal, 60)); |
| 147 | }); |
| 148 | |
| 149 | const header = keys.map((k, i) => k.padEnd(widths[i])).join(" | "); |
| 150 | console.log(header); |
| 151 | console.log(widths.map((w) => "-".repeat(w)).join("-+-")); |
| 152 | |
| 153 | for (const row of rows) { |
| 154 | const line = keys |
| 155 | .map((k, i) => { |
| 156 | const val = String(row[k] ?? "NULL"); |
| 157 | return val.length > 60 |
| 158 | ? val.slice(0, 57) + "..." |
| 159 | : val.padEnd(widths[i]); |
| 160 | }) |
| 161 | .join(" | "); |
| 162 | console.log(line); |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | export default async function dbQuery(args: string[]): Promise<void> { |
| 167 | const parsed = parseArgs(args); |