52 lines
2.1 KiB
TypeScript
52 lines
2.1 KiB
TypeScript
import type { DatabaseType, QueryResult } from "@/types/database";
|
|
import * as api from "@/lib/backend/api";
|
|
import { escapeCsvField, type CsvQuoteMode } from "@/lib/export/csvQuoteMode";
|
|
import type { SqlInsertMode } from "@/lib/export/sqlInsertMode";
|
|
|
|
export type ExportCellValue = string | number | boolean | null;
|
|
|
|
export function formatCsv(columns: string[], rows: ExportCellValue[][], quoteMode: CsvQuoteMode = "all"): string {
|
|
const header = columns.map((column) => escapeCsvField(column, quoteMode)).join(",");
|
|
const body = rows.map((row) => row.map((cell) => (cell === null ? "" : escapeCsvField(String(cell), quoteMode))).join(",")).join("\n");
|
|
return `${header}\n${body}`;
|
|
}
|
|
|
|
// Tab-separated values with a header row, mirroring Navicat's "Text File (*.txt)"
|
|
// export: fields are joined by a tab, NULL becomes empty, and a field is only
|
|
// wrapped in double quotes (with " doubled) when it contains a tab, newline,
|
|
// or quote - i.e. the minimum needed to round-trip the value.
|
|
export function formatTsv(columns: string[], rows: ExportCellValue[][]): string {
|
|
const esc = (value: ExportCellValue) => {
|
|
const text = value === null ? "" : String(value);
|
|
if (text.includes("\t") || text.includes("\n") || text.includes("\r") || text.includes('"')) {
|
|
return `"${text.replace(/"/g, '""')}"`;
|
|
}
|
|
return text;
|
|
};
|
|
const header = columns.map(esc).join("\t");
|
|
const body = rows.map((row) => row.map(esc).join("\t")).join("\n");
|
|
return `${header}\n${body}`;
|
|
}
|
|
|
|
export interface FormatSqlInsertOptions {
|
|
databaseType?: DatabaseType;
|
|
identifierQuote?: string;
|
|
schema?: string;
|
|
tableName?: string;
|
|
qualifiedTableName?: string;
|
|
columns: string[];
|
|
columnTypes?: Array<string | null | undefined>;
|
|
spatialColumns?: QueryResult["spatial_columns"];
|
|
spatialValues?: QueryResult["spatial_values"];
|
|
rows: ExportCellValue[][];
|
|
insertMode?: SqlInsertMode;
|
|
excludeColumns?: string[];
|
|
}
|
|
|
|
export function formatSqlInsert({ insertMode = "batch", ...options }: FormatSqlInsertOptions): Promise<string> {
|
|
return api.buildExportSqlInsert({
|
|
...options,
|
|
batchSize: insertMode === "single" ? 1 : undefined,
|
|
});
|
|
}
|