feat(export): apply connection query timeout to database backup
This commit is contained in:
5 files changed
+155
-91
No files matched your search
@@ -3746,6 +3746,10 @@ onUnmounted(() => {
|
||||
setConnectionDialogOpen(false);
|
||||
openSettings('tunnels');
|
||||
"
|
||||
@open-connection-settings="
|
||||
setConnectionDialogOpen(false);
|
||||
openConnectionSettings($event, 'advanced');
|
||||
"
|
||||
@open-lineage-target="openLineageTarget"
|
||||
@open-database-search-target="openDatabaseSearchTarget"
|
||||
@open-diagram-target="openDiagramTarget"
|
||||
|
||||
@@ -17,8 +17,9 @@ import { buildSelectedTablesPayload, isDatabaseExportTableSelectionValid } from
|
||||
import { isTauriRuntime } from "@/lib/backend/tauriRuntime";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Download, Square, CheckSquare, Search, X, Loader2 } from "@lucide/vue";
|
||||
import { Download, Square, CheckSquare, Search, X, Loader2, Wrench } from "@lucide/vue";
|
||||
import { formatDataTransferDuration, useExportTracker } from "@/composables/useExportTracker";
|
||||
import { isQueryTimeoutErrorMessage } from "@/lib/sql/queryError";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { toast } = useToast();
|
||||
@@ -35,6 +36,10 @@ const props = defineProps<{
|
||||
prefillAllDatabases?: boolean;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
openConnectionSettings: [connectionId: string];
|
||||
}>();
|
||||
|
||||
// Connection / Database / Schema selectors
|
||||
const connectionId = ref("");
|
||||
const database = ref("");
|
||||
@@ -72,6 +77,7 @@ const exportProgress = ref<ExportProgress | null>(null);
|
||||
const exportId = ref("");
|
||||
const exportDone = ref(false);
|
||||
const exportError = ref<string | null>(null);
|
||||
const exportWarning = ref<string | null>(null);
|
||||
const exportCancelled = ref(false);
|
||||
const exportStartedAt = ref<number | null>(null);
|
||||
const exportFinishedAt = ref<number | null>(null);
|
||||
@@ -163,6 +169,8 @@ function toastDatabaseExportCompletion(errorCount: number, errorSummary: string
|
||||
toast(t("databaseExport.exportSuccess"), 3000);
|
||||
}
|
||||
|
||||
const canChangeQueryTimeout = computed(() => !!connectionId.value && !!exportWarning.value && isQueryTimeoutErrorMessage(exportWarning.value));
|
||||
|
||||
async function loadDatabases(connId: string) {
|
||||
if (!connId) return;
|
||||
loadingMeta.value = true;
|
||||
@@ -334,6 +342,7 @@ async function startExport() {
|
||||
exportFinishedAt.value = null;
|
||||
exportDone.value = false;
|
||||
exportError.value = null;
|
||||
exportWarning.value = null;
|
||||
exportCancelled.value = false;
|
||||
exportProgress.value = {
|
||||
exportId: exportId.value,
|
||||
@@ -380,11 +389,13 @@ async function startExport() {
|
||||
if (progress.status === "Done") {
|
||||
finishExportTiming();
|
||||
exportDone.value = true;
|
||||
exportWarning.value = progress.errorSummary ?? null;
|
||||
isExporting.value = false;
|
||||
toastDatabaseExportCompletion(progress.errorCount ?? 0, progress.errorSummary ?? null);
|
||||
} else if (progress.status === "Error") {
|
||||
finishExportTiming();
|
||||
exportError.value = progress.error;
|
||||
exportWarning.value = null;
|
||||
isExporting.value = false;
|
||||
} else if (progress.status === "Cancelled") {
|
||||
finishExportTiming();
|
||||
@@ -397,6 +408,7 @@ async function startExport() {
|
||||
);
|
||||
} catch (e: any) {
|
||||
exportError.value = e?.message || String(e);
|
||||
exportWarning.value = null;
|
||||
const lastProgress = exportProgress.value as api.ExportProgress | null;
|
||||
const fallbackProgress: api.ExportProgress = {
|
||||
exportId: exportId.value,
|
||||
@@ -440,6 +452,7 @@ async function startAllDatabasesExport() {
|
||||
exportFinishedAt.value = null;
|
||||
exportDone.value = false;
|
||||
exportError.value = null;
|
||||
exportWarning.value = null;
|
||||
exportCancelled.value = false;
|
||||
batchDatabaseIndex.value = 0;
|
||||
batchRowsExported.value = 0;
|
||||
@@ -532,6 +545,7 @@ async function startAllDatabasesExport() {
|
||||
if (progress.status === "Error") {
|
||||
finishExportTiming();
|
||||
exportError.value = progress.error;
|
||||
exportWarning.value = null;
|
||||
isExporting.value = false;
|
||||
} else if (progress.status === "Cancelled") {
|
||||
finishExportTiming();
|
||||
@@ -551,6 +565,7 @@ async function startAllDatabasesExport() {
|
||||
|
||||
if (!exportError.value && !exportCancelled.value) {
|
||||
exportDone.value = true;
|
||||
exportWarning.value = batchFirstErrorSummary;
|
||||
finishExportTiming();
|
||||
isExporting.value = false;
|
||||
const finalProgress: api.ExportProgress = {
|
||||
@@ -575,6 +590,7 @@ async function startAllDatabasesExport() {
|
||||
}
|
||||
} catch (e: any) {
|
||||
exportError.value = e?.message || String(e);
|
||||
exportWarning.value = null;
|
||||
updateDatabaseExportTask(batchId, {
|
||||
exportId: batchId,
|
||||
currentObject: t("databaseExport.allDatabasesTask", { count: dbs.length }),
|
||||
@@ -629,6 +645,7 @@ function resetState() {
|
||||
exportProgress.value = null;
|
||||
exportDone.value = false;
|
||||
exportError.value = null;
|
||||
exportWarning.value = null;
|
||||
exportCancelled.value = false;
|
||||
exportStartedAt.value = null;
|
||||
exportFinishedAt.value = null;
|
||||
@@ -940,6 +957,15 @@ watch(
|
||||
<div v-if="exportDone" class="text-xs text-green-600 font-medium">
|
||||
{{ t("databaseExport.exportSuccess") }}
|
||||
</div>
|
||||
<div v-if="exportDone && exportWarning" class="space-y-2">
|
||||
<div class="whitespace-pre-wrap break-words text-xs text-amber-600 dark:text-amber-400">
|
||||
{{ exportWarning }}
|
||||
</div>
|
||||
<Button v-if="canChangeQueryTimeout" variant="outline" size="sm" @click="emit('openConnectionSettings', connectionId)">
|
||||
<Wrench class="mr-1 h-3.5 w-3.5" />
|
||||
{{ t("editor.changeQueryTimeout") }}
|
||||
</Button>
|
||||
</div>
|
||||
<div v-else-if="exportError" class="text-xs text-destructive font-medium">
|
||||
{{ t("databaseExport.exportError", { error: exportError }) }}
|
||||
</div>
|
||||
|
||||
@@ -59,6 +59,7 @@ const emit = defineEmits<{
|
||||
connectFailed: [message: string];
|
||||
openDriverStore: [focus?: DriverStoreFocus];
|
||||
openTunnelProfileSettings: [];
|
||||
openConnectionSettings: [connectionId: string, initialTab: "advanced"];
|
||||
openLineageTarget: [
|
||||
target: {
|
||||
connectionId: string;
|
||||
@@ -327,6 +328,7 @@ watch(
|
||||
:prefill-table="dialogs.databaseExportPrefillTable.value"
|
||||
:prefill-tables="dialogs.databaseExportPrefillTables.value"
|
||||
:prefill-all-databases="dialogs.databaseExportAllDatabases.value"
|
||||
@open-connection-settings="emit('openConnectionSettings', $event, 'advanced')"
|
||||
/>
|
||||
<ConfigConnectionSelectDialog
|
||||
v-if="dialogs.showConfigConnectionSelectDialog.value"
|
||||
|
||||
Reference in new issue
Block a user