fix(kingbase): honor connection identifier quotes in exports
This commit is contained in:
1 parent
cb09a5c75b
commit
9fc7721590
18 files changed
+313
-8
No files matched your search
@@ -426,6 +426,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
|
||||
}
|
||||
return buildDataGridCopyInsertStatement({
|
||||
databaseType: databaseType.value,
|
||||
identifierQuote: options.identifierQuote?.value,
|
||||
tableMeta: tableMeta.value,
|
||||
columns: data.columns,
|
||||
columnTypes: data.columnTypes,
|
||||
@@ -1250,6 +1251,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
|
||||
const exportData = sqlInsertExportData(result);
|
||||
const content = await formatSqlInsert({
|
||||
databaseType: databaseType.value,
|
||||
identifierQuote: options.identifierQuote?.value,
|
||||
schema: tableMeta.value?.schema,
|
||||
tableName: tableMeta.value?.tableName || "table_name",
|
||||
columns: exportData.columns,
|
||||
@@ -1271,6 +1273,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
|
||||
const exportData = sqlInsertExportData(result);
|
||||
const content = await formatSqlInsert({
|
||||
databaseType: databaseType.value,
|
||||
identifierQuote: options.identifierQuote?.value,
|
||||
schema: tableMeta.value?.schema,
|
||||
tableName: tableMeta.value?.tableName || "table_name",
|
||||
columns: exportData.columns,
|
||||
|
||||
@@ -4310,6 +4310,7 @@ export interface QueryResultExportRequest {
|
||||
exportColumnTypes?: Array<string | null | undefined>;
|
||||
numericColumnRightAlign?: boolean;
|
||||
columnComments?: Array<string | null> | null;
|
||||
identifierQuote?: string;
|
||||
}
|
||||
|
||||
export async function startTableExport(request: TableExportRequest, onProgress: (progress: TableExportProgress) => void): Promise<TableExportProgress> {
|
||||
|
||||
@@ -36,6 +36,7 @@ export interface DataGridSaveStatementOptions {
|
||||
|
||||
export interface DataGridCopyUpdateStatementOptions {
|
||||
databaseType?: DatabaseType;
|
||||
identifierQuote?: string;
|
||||
tableMeta: DataGridTableMeta;
|
||||
columns: string[];
|
||||
sourceColumns?: Array<string | undefined>;
|
||||
@@ -46,6 +47,7 @@ export type DataGridCopyInsertMode = "merged" | "row-by-row";
|
||||
|
||||
export interface DataGridCopyInsertStatementOptions {
|
||||
databaseType?: DatabaseType;
|
||||
identifierQuote?: string;
|
||||
tableMeta?: DataGridTableMeta;
|
||||
columns: string[];
|
||||
columnTypes?: Array<string | null | undefined>;
|
||||
|
||||
@@ -29,6 +29,7 @@ export function formatTsv(columns: string[], rows: ExportCellValue[][]): string
|
||||
|
||||
export interface FormatSqlInsertOptions {
|
||||
databaseType?: DatabaseType;
|
||||
identifierQuote?: string;
|
||||
schema?: string;
|
||||
tableName?: string;
|
||||
qualifiedTableName?: string;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
ensureConnected: vi.fn(),
|
||||
getConfig: vi.fn(),
|
||||
connectionIdentifierQuote: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/backend/api", () => ({
|
||||
saveOpenTabsState: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
vi.mock("@/stores/connectionStore", () => ({
|
||||
useConnectionStore: () => ({
|
||||
ensureConnected: mocks.ensureConnected,
|
||||
getConfig: mocks.getConfig,
|
||||
connectionIdentifierQuote: mocks.connectionIdentifierQuote,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("@/stores/settingsStore", () => ({
|
||||
useSettingsStore: () => ({
|
||||
editorSettings: {
|
||||
exportBatchSize: 1000,
|
||||
exportRowLimitEnabled: false,
|
||||
exportRowLimit: 100_000,
|
||||
globalQueryTimeoutSecs: 30,
|
||||
queryExportKeysetOptimizationEnabled: true,
|
||||
numericColumnRightAlign: true,
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
function installLocalStorage() {
|
||||
const data = new Map<string, string>();
|
||||
vi.stubGlobal("localStorage", {
|
||||
getItem: vi.fn((key: string) => data.get(key) ?? null),
|
||||
setItem: vi.fn((key: string, value: string) => data.set(key, value)),
|
||||
removeItem: vi.fn((key: string) => data.delete(key)),
|
||||
});
|
||||
}
|
||||
|
||||
describe("queryStore query result export", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
installLocalStorage();
|
||||
setActivePinia(createPinia());
|
||||
mocks.ensureConnected.mockResolvedValue(undefined);
|
||||
mocks.getConfig.mockReturnValue({ id: "kingbase-1", name: "Kingbase", db_type: "kingbase", database: "app", query_timeout_secs: 30 });
|
||||
mocks.connectionIdentifierQuote.mockReturnValue("[");
|
||||
});
|
||||
|
||||
it("passes the live connection identifier quote to backend SQL export", async () => {
|
||||
const { useQueryStore } = await import("@/stores/queryStore");
|
||||
const store = useQueryStore();
|
||||
const tabId = store.createTab("kingbase-1", "app", "Query");
|
||||
const tab = store.tabs.find((item) => item.id === tabId)!;
|
||||
tab.sql = "SELECT select FROM audit_log";
|
||||
tab.lastExecutedSql = tab.sql;
|
||||
tab.result = {
|
||||
columns: ["select"],
|
||||
rows: [["value"]],
|
||||
affected_rows: 0,
|
||||
execution_time_ms: 1,
|
||||
};
|
||||
|
||||
const request = await store.buildQueryResultExportRequest(tabId, {
|
||||
exportId: "export-1",
|
||||
filePath: "audit.sql",
|
||||
format: "sql",
|
||||
exportTableName: "audit_log",
|
||||
exportColumnTypes: ["text"],
|
||||
});
|
||||
|
||||
expect(request?.identifierQuote).toBe("[");
|
||||
expect(mocks.connectionIdentifierQuote).toHaveBeenCalledWith("kingbase-1");
|
||||
});
|
||||
});
|
||||
@@ -6084,6 +6084,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
exportTableName: options.exportTableName,
|
||||
exportColumnTypes: options.exportColumnTypes,
|
||||
numericColumnRightAlign: settings.numericColumnRightAlign,
|
||||
identifierQuote: connStore.connectionIdentifierQuote(location.connectionId),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6119,6 +6120,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
executionId: uuid(),
|
||||
numericColumnRightAlign: settings.numericColumnRightAlign,
|
||||
columnComments,
|
||||
identifierQuote: connStore.connectionIdentifierQuote(tab.connectionId),
|
||||
};
|
||||
|
||||
const tracker = useExportTracker();
|
||||
|
||||
Reference in new issue
Block a user