chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import type { OutputColumnMetadata } from "@internal/clickhouse";
|
||||
|
||||
/**
|
||||
* Escape a value for CSV format.
|
||||
* - Wraps in quotes if the value contains commas, quotes, or newlines
|
||||
* - Escapes quotes by doubling them
|
||||
*/
|
||||
function escapeCSVValue(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const stringValue = typeof value === "object" ? JSON.stringify(value) : String(value);
|
||||
|
||||
// Check if we need to quote the value
|
||||
if (
|
||||
stringValue.includes(",") ||
|
||||
stringValue.includes('"') ||
|
||||
stringValue.includes("\n") ||
|
||||
stringValue.includes("\r")
|
||||
) {
|
||||
// Escape quotes by doubling them and wrap in quotes
|
||||
return `"${stringValue.replace(/"/g, '""')}"`;
|
||||
}
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert query result rows to CSV format.
|
||||
*
|
||||
* @param rows - Array of row objects from query results
|
||||
* @param columns - Column metadata describing the result columns
|
||||
* @returns CSV string with header row and data rows
|
||||
*/
|
||||
export function rowsToCSV(
|
||||
rows: Record<string, unknown>[],
|
||||
columns: OutputColumnMetadata[]
|
||||
): string {
|
||||
if (columns.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const columnNames = columns.map((col) => col.name);
|
||||
|
||||
// Header row
|
||||
const headerRow = columnNames.map(escapeCSVValue).join(",");
|
||||
|
||||
// Data rows
|
||||
const dataRows = rows.map((row) =>
|
||||
columnNames.map((name) => escapeCSVValue(row[name])).join(",")
|
||||
);
|
||||
|
||||
return [headerRow, ...dataRows].join("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert query result rows to JSON format.
|
||||
*
|
||||
* @param rows - Array of row objects from query results
|
||||
* @returns Formatted JSON string
|
||||
*/
|
||||
export function rowsToJSON(rows: Record<string, unknown>[]): string {
|
||||
return JSON.stringify(rows, null, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a file download in the browser.
|
||||
*
|
||||
* @param content - The file content as a string
|
||||
* @param filename - The name for the downloaded file
|
||||
* @param mimeType - The MIME type of the file
|
||||
*/
|
||||
export function downloadFile(content: string, filename: string, mimeType: string): void {
|
||||
const blob = new Blob([content], { type: mimeType });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
Reference in New Issue
Block a user