feat(export): support safe background query exports
This commit is contained in:
1 parent
2f44d36018
commit
a07def6042
17 files changed
+577
-195
No files matched your search
@@ -58,6 +58,7 @@ import * as api from "@/lib/backend/api";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useSettingsStore } from "@/stores/settingsStore";
|
||||
import { useSavedSqlStore } from "@/stores/savedSqlStore";
|
||||
import { useExportTracker } from "@/composables/useExportTracker";
|
||||
import { recordQueryCancellationLatency, resourceLifecycleDiagnostics } from "@/lib/diagnostics/resourceLifecycleDiagnostics";
|
||||
import { appendDebugLog } from "@/lib/backend/debugLog";
|
||||
import { formatError } from "@/lib/backend/errorUtils";
|
||||
@@ -4770,7 +4771,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
const setupSql = batchStatements[resultStatementIndex!]?.sql === tab.result.sourceStatement ? batchStatements.slice(0, resultStatementIndex).map((statement) => statement.sql) : undefined;
|
||||
const rowLimit = settings.exportRowLimitEnabled ? settings.exportRowLimit : null;
|
||||
const totalRows = typeof tab.resultTotalRowCount === "number" ? (rowLimit === null ? tab.resultTotalRowCount : Math.min(tab.resultTotalRowCount, rowLimit)) : null;
|
||||
const clientSessionId = tabClientSessionId(tab, "export");
|
||||
const clientSessionId = `${tabClientSessionId(tab, "export")}:${options.exportId}`;
|
||||
|
||||
return {
|
||||
exportId: options.exportId,
|
||||
@@ -4798,6 +4799,58 @@ export const useQueryStore = defineStore("query", () => {
|
||||
};
|
||||
}
|
||||
|
||||
async function exportQuerySqlDirect(id: string, sql: string, format: "csv" | "xlsx" | "txt", filePath: string) {
|
||||
const tab = tabs.value.find((item) => item.id === id);
|
||||
if (!tab || tab.mode !== "query" || !sql.trim()) return;
|
||||
|
||||
const connStore = useConnectionStore();
|
||||
await connStore.ensureConnected(tab.connectionId);
|
||||
const conn = connStore.getConfig(tab.connectionId);
|
||||
const settings = useSettingsStore().editorSettings;
|
||||
const effectiveDbType = effectiveDatabaseTypeForConnection(conn);
|
||||
if (!effectiveDbType) return;
|
||||
|
||||
const exportId = uuid();
|
||||
const request: api.QueryResultExportRequest = {
|
||||
exportId,
|
||||
connectionId: tab.connectionId,
|
||||
database: tab.database,
|
||||
schema: tab.schema,
|
||||
sql,
|
||||
queryBaseSql: sql,
|
||||
databaseType: effectiveDbType,
|
||||
useAgentCursor: usesAgentCursorForQuery(conn?.db_type),
|
||||
filePath,
|
||||
format,
|
||||
pageSize: settings.exportBatchSize,
|
||||
rowLimit: settings.exportRowLimitEnabled ? settings.exportRowLimit : null,
|
||||
totalRows: null,
|
||||
timeoutSecs: queryTimeoutSecsForConnection(conn),
|
||||
keysetOptimizationEnabled: settings.queryExportKeysetOptimizationEnabled,
|
||||
clientSessionId: `${tabClientSessionId(tab, "export")}:${exportId}`,
|
||||
executionId: uuid(),
|
||||
numericColumnRightAlign: settings.numericColumnRightAlign,
|
||||
};
|
||||
|
||||
const tracker = useExportTracker();
|
||||
tracker.addTask("Query Result", format, filePath, request.exportId);
|
||||
tracker.registerTaskCancelHandler(request.exportId, () => api.cancelQueryResultExport(request.exportId, request.executionId));
|
||||
|
||||
void (async () => {
|
||||
try {
|
||||
await api.startQueryResultExport(request, (progress) => tracker.updateTableExportTask(request.exportId, progress));
|
||||
} catch (error: any) {
|
||||
const task = tracker.tasks.value.find((item) => item.exportId === request.exportId);
|
||||
if (task) {
|
||||
task.status = "Error";
|
||||
task.errorMessage = error?.message || String(error);
|
||||
}
|
||||
} finally {
|
||||
tracker.unregisterTaskCancelHandler(request.exportId);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return {
|
||||
tabs,
|
||||
activeTabId,
|
||||
@@ -4900,6 +4953,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
importResultArchive,
|
||||
fetchTabResultForExport,
|
||||
buildQueryResultExportRequest,
|
||||
exportQuerySqlDirect,
|
||||
getResourceLifecycleDiagnostics: () => resourceLifecycleDiagnostics(tabs.value),
|
||||
notifyConnectionMayBeLost,
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user