feat(postgres): add table vacuum action
This commit is contained in:
1 parent
0e0edcd206
commit
11407b537f
23 files changed
+554
-36
No files matched your search
@@ -3,6 +3,7 @@ import { computed, createApp, nextTick, onActivated, onBeforeUnmount, ref, watch
|
||||
import { RecycleScroller } from "vue-virtual-scroller";
|
||||
import { useSqlHighlighter } from "@/composables/useSqlHighlighter";
|
||||
import {
|
||||
Activity,
|
||||
ArrowDown,
|
||||
ArrowRightLeft,
|
||||
ArrowUp,
|
||||
@@ -61,7 +62,7 @@ import XlsxHeaderDialog from "@/components/export/XlsxHeaderDialog.vue";
|
||||
import * as api from "@/lib/backend/api";
|
||||
import type { ColumnInfo, ConnectionConfig, ForeignKeyInfo, IndexInfo, ObjectBrowserViewMode, ObjectBrowserViewport, ObjectInfo, ObjectSourceKind, ObjectStatistics, TableInfoTab, TreeNode, TriggerInfo } from "@/types/database";
|
||||
import { sortTablesByFkDependency, type TableWithFk } from "@/lib/table/tableDependencySort";
|
||||
import { isSchemaAware, supportsTransfer } from "@/lib/database/databaseCapabilities";
|
||||
import { isSchemaAware, supportsTableVacuum, supportsTransfer } from "@/lib/database/databaseCapabilities";
|
||||
import { supportsSchemaDiagram, supportsTableImport, supportsTableStructureEditing, supportsTableTruncate } from "@/lib/database/databaseFeatureSupport";
|
||||
import { codeMirrorSqlDialect, connectionObjectTreeNodeSchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, tableStructureDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
|
||||
import { getTableMetadataCapabilities, type TableMetadataCapabilities } from "@/lib/table/tableMetadataCapabilities";
|
||||
@@ -73,6 +74,7 @@ import {
|
||||
buildCopyTableDataSql,
|
||||
buildEmptyTableSql,
|
||||
buildTruncateTableSql,
|
||||
buildVacuumTableSql,
|
||||
supportsDropTableCascade,
|
||||
supportsTruncateTableCascade,
|
||||
type TableAdminSqlOptions,
|
||||
@@ -246,6 +248,12 @@ const showTruncateConfirm = ref(false);
|
||||
const truncateTarget = ref<ObjectBrowserRow | null>(null);
|
||||
const truncatePreviewSql = ref("");
|
||||
const truncateTableCascade = ref(false);
|
||||
const showVacuumConfirm = ref(false);
|
||||
const vacuumTarget = ref<ObjectBrowserRow | null>(null);
|
||||
const vacuumPreviewSql = ref("");
|
||||
const vacuumTableFull = ref(false);
|
||||
const vacuumTableAnalyze = ref(false);
|
||||
const vacuumExecuting = ref(false);
|
||||
const showEmptyConfirm = ref(false);
|
||||
const emptyTarget = ref<ObjectBrowserRow | null>(null);
|
||||
const emptyPreviewSql = ref("");
|
||||
@@ -299,6 +307,8 @@ const canOpenStructureEditor = computed(() => supportsTableStructureEditing(tabl
|
||||
const canOpenDiagram = computed(() => !!props.database && supportsSchemaDiagram(effectiveDatabaseType.value));
|
||||
const canOpenTableImport = computed(() => !!props.database && supportsTableImport(effectiveDatabaseType.value));
|
||||
const supportsTruncateTable = computed(() => supportsTableTruncate(effectiveDatabaseType.value));
|
||||
const supportsVacuumTable = computed(() => !props.connection.read_only && supportsTableVacuum(effectiveDatabaseType.value));
|
||||
const vacuumRiskMessage = computed(() => (vacuumExecuting.value ? t("contextMenu.vacuumTableRunningHint") : vacuumTableFull.value ? t("contextMenu.vacuumTableFullRisk") : vacuumTableAnalyze.value ? t("contextMenu.vacuumTableAnalyzeRisk") : t("contextMenu.vacuumTableDefaultRisk")));
|
||||
const sourceDialect = computed(() => codeMirrorSqlDialect(effectiveDatabaseType.value));
|
||||
const sourceFormatDialect = computed<SqlFormatDialect>(() => sqlFormatDialectForDbType(effectiveDatabaseType.value));
|
||||
const objectFilters = computed<ObjectFilter[]>(() =>
|
||||
@@ -2356,6 +2366,55 @@ async function confirmTruncateTable() {
|
||||
truncateTarget.value = null;
|
||||
}
|
||||
|
||||
async function refreshVacuumPreviewSql() {
|
||||
const row = vacuumTarget.value;
|
||||
vacuumPreviewSql.value = "";
|
||||
if (!row) return;
|
||||
vacuumPreviewSql.value = await buildVacuumTableSql({
|
||||
databaseType: effectiveDatabaseType.value,
|
||||
schema: row.schema || selectedSchema.value,
|
||||
tableName: row.name,
|
||||
full: vacuumTableFull.value,
|
||||
analyze: vacuumTableAnalyze.value,
|
||||
}).catch(() => "");
|
||||
}
|
||||
|
||||
function requestVacuumTable(row: ObjectBrowserRow) {
|
||||
if (!supportsVacuumTable.value) return;
|
||||
vacuumTarget.value = row;
|
||||
vacuumTableFull.value = false;
|
||||
vacuumTableAnalyze.value = false;
|
||||
vacuumPreviewSql.value = "";
|
||||
void refreshVacuumPreviewSql();
|
||||
showVacuumConfirm.value = true;
|
||||
}
|
||||
|
||||
async function confirmVacuumTable() {
|
||||
const row = vacuumTarget.value;
|
||||
if (!row || vacuumExecuting.value) return;
|
||||
vacuumExecuting.value = true;
|
||||
try {
|
||||
const sql =
|
||||
vacuumPreviewSql.value ||
|
||||
(await buildVacuumTableSql({
|
||||
databaseType: effectiveDatabaseType.value,
|
||||
schema: row.schema || selectedSchema.value,
|
||||
tableName: row.name,
|
||||
full: vacuumTableFull.value,
|
||||
analyze: vacuumTableAnalyze.value,
|
||||
}));
|
||||
const executed = await executeObjectBrowserSqlWithProductionGuard(sql, () => api.executeQuery(props.connection.id, props.database, sql, row.schema || selectedSchema.value));
|
||||
if (!executed) return;
|
||||
toast(t("contextMenu.vacuumTableSuccess", { name: row.name }));
|
||||
showVacuumConfirm.value = false;
|
||||
vacuumTarget.value = null;
|
||||
} catch (e: any) {
|
||||
toast(t("contextMenu.tableOperationFailed", { message: e?.message || String(e) }), 5000);
|
||||
} finally {
|
||||
vacuumExecuting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshEmptyPreviewSql(row: ObjectBrowserRow) {
|
||||
emptyPreviewSql.value = "";
|
||||
emptyPreviewSql.value = await buildEmptyTableSql(tableAdminSqlOptions(row)).catch(() => "");
|
||||
@@ -2759,6 +2818,32 @@ function getTableMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
|
||||
];
|
||||
}
|
||||
const useBatchActions = isSelectedBatchTableContext(item);
|
||||
const moreActions: ContextMenuItem[] = [];
|
||||
if (supportsVacuumTable.value) {
|
||||
moreActions.push({ label: t("contextMenu.vacuumTable"), action: () => requestVacuumTable(item), icon: Activity, variant: "destructive" as const });
|
||||
}
|
||||
if (supportsTruncateTable.value) {
|
||||
moreActions.push({
|
||||
label: useBatchActions ? selectedBatchTableCountLabel("batchTruncate") : t("contextMenu.truncateTable"),
|
||||
action: useBatchActions ? requestBatchTruncateTables : () => requestTruncateTable(item),
|
||||
icon: Scissors,
|
||||
variant: "destructive" as const,
|
||||
});
|
||||
}
|
||||
moreActions.push(
|
||||
{
|
||||
label: useBatchActions ? selectedBatchTableCountLabel("batchEmpty") : t("contextMenu.emptyTable"),
|
||||
action: useBatchActions ? requestBatchEmptyTables : () => requestEmptyTable(item),
|
||||
icon: Eraser,
|
||||
variant: "destructive" as const,
|
||||
},
|
||||
{
|
||||
label: useBatchActions ? selectedBatchTableCountLabel("batchDrop") : t("contextMenu.dropTable"),
|
||||
action: useBatchActions ? requestBatchDropTables : () => requestDrop(item),
|
||||
icon: Trash2,
|
||||
variant: "destructive" as const,
|
||||
},
|
||||
);
|
||||
return [
|
||||
{ label: t("contextMenu.viewData"), action: () => openViewData(item), icon: Table2 },
|
||||
{
|
||||
@@ -2780,28 +2865,7 @@ function getTableMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
|
||||
{ label: t("contextMenu.duplicateStructure"), action: () => requestDuplicateStructure(item), icon: CopyPlus },
|
||||
...tableClipboardMenuItems(item),
|
||||
{ label: "", separator: true },
|
||||
...(supportsTruncateTable.value
|
||||
? [
|
||||
{
|
||||
label: useBatchActions ? selectedBatchTableCountLabel("batchTruncate") : t("contextMenu.truncateTable"),
|
||||
action: useBatchActions ? requestBatchTruncateTables : () => requestTruncateTable(item),
|
||||
icon: Scissors,
|
||||
variant: "destructive" as const,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
label: useBatchActions ? selectedBatchTableCountLabel("batchEmpty") : t("contextMenu.emptyTable"),
|
||||
action: useBatchActions ? requestBatchEmptyTables : () => requestEmptyTable(item),
|
||||
icon: Eraser,
|
||||
variant: "destructive" as const,
|
||||
},
|
||||
{
|
||||
label: useBatchActions ? selectedBatchTableCountLabel("batchDrop") : t("contextMenu.dropTable"),
|
||||
action: useBatchActions ? requestBatchDropTables : () => requestDrop(item),
|
||||
icon: Trash2,
|
||||
variant: "destructive" as const,
|
||||
},
|
||||
{ label: t("common.more"), icon: ListTree, children: moreActions },
|
||||
{ label: "", separator: true },
|
||||
{ label: t("contextMenu.copyName"), action: () => copyName(item), icon: Copy },
|
||||
];
|
||||
@@ -3541,6 +3605,31 @@ function getObjectBrowserMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<DangerConfirmDialog
|
||||
v-model:open="showVacuumConfirm"
|
||||
:title="t('contextMenu.vacuumTableTitle')"
|
||||
:message="t('contextMenu.vacuumTableMessage', { name: vacuumTarget?.name ?? '' })"
|
||||
:details-text="vacuumRiskMessage"
|
||||
:sql="vacuumPreviewSql"
|
||||
:confirm-label="vacuumExecuting ? t('contextMenu.vacuumTableRunning') : vacuumTableFull ? t('contextMenu.vacuumTableFullConfirm') : t('contextMenu.vacuumTable')"
|
||||
:loading="vacuumExecuting"
|
||||
:close-on-confirm="false"
|
||||
@confirm="confirmVacuumTable"
|
||||
>
|
||||
<template #options>
|
||||
<div class="mb-3 flex gap-3 rounded-md border bg-muted/20 px-3 py-2 text-sm">
|
||||
<label class="flex items-center gap-2" :title="t('contextMenu.vacuumTableAnalyzeHint')">
|
||||
<input v-model="vacuumTableAnalyze" :disabled="vacuumExecuting" type="checkbox" class="h-3.5 w-3.5 shrink-0 accent-primary" @change="refreshVacuumPreviewSql" />
|
||||
<span class="font-medium text-foreground">ANALYZE</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2" :title="t('contextMenu.vacuumTableFullHint')">
|
||||
<input v-model="vacuumTableFull" :disabled="vacuumExecuting" type="checkbox" class="h-3.5 w-3.5 shrink-0 accent-destructive" @change="refreshVacuumPreviewSql" />
|
||||
<span class="font-medium" :class="vacuumTableFull ? 'text-destructive' : 'text-foreground'">FULL</span>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
</DangerConfirmDialog>
|
||||
|
||||
<DangerConfirmDialog
|
||||
v-model:open="showTruncateConfirm"
|
||||
:title="t('contextMenu.confirmTruncateTableTitle')"
|
||||
|
||||
@@ -61,7 +61,7 @@ import { codeMirrorSqlDialect } from "@/lib/database/jdbcDialect";
|
||||
import { sqlFormatDialectForDbType } from "@/lib/sql/sqlFormatter";
|
||||
import { createSidebarActionTarget, findSidebarActionTarget, matchesSidebarActionTarget, type SidebarActionTarget } from "@/lib/sidebar/sidebarActionTarget";
|
||||
import { syncSidebarTreeNodeExpansion } from "@/lib/sidebar/sidebarTreeExpansion";
|
||||
import type { SidebarDangerDialogRequest } from "@/lib/sidebar/sidebarDangerDialog";
|
||||
import type { SidebarDangerDialogOption, SidebarDangerDialogRequest } from "@/lib/sidebar/sidebarDangerDialog";
|
||||
import { resetSidebarTreeDialogState, sidebarDangerRunningExecutionId } from "./sidebarTreeDialogState";
|
||||
import { SidebarDangerConfirmDialog, SidebarDdlViewDialog, SidebarObjectSourceDialog, SidebarProcedureExecutionDialog, SidebarVisibleDatabasesDialog, SidebarVisibleNacosNamespacesDialog, SidebarVisibleSchemasDialog } from "./sidebarAsyncDialogs";
|
||||
import { sortConnectionListForDisplay } from "@/lib/sidebar/connectionListSort";
|
||||
@@ -1609,8 +1609,9 @@ async function confirmSidebarDangerDialog() {
|
||||
if (!request || sidebarDangerDialogConfirming.value) return;
|
||||
if (request.closeOnConfirm !== false) sidebarDangerDialogOpen.value = false;
|
||||
sidebarDangerDialogConfirming.value = true;
|
||||
let completed: void | boolean = undefined;
|
||||
try {
|
||||
await request.confirm();
|
||||
completed = await request.confirm();
|
||||
} finally {
|
||||
// A danger operation that hit a client-observed timeout is kept alive
|
||||
// (still cancellable) rather than settled outright — sidebarDangerRunningExecutionId
|
||||
@@ -1620,7 +1621,7 @@ async function confirmSidebarDangerDialog() {
|
||||
// execution actually settles.
|
||||
if (!sidebarDangerRunningExecutionId.value) {
|
||||
sidebarDangerDialogConfirming.value = false;
|
||||
sidebarDangerDialogOpen.value = false;
|
||||
if (completed !== false) sidebarDangerDialogOpen.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1651,8 +1652,8 @@ async function cancelSidebarDangerDialogRunning() {
|
||||
}
|
||||
}
|
||||
|
||||
function updateSidebarDangerDialogOption(event: Event) {
|
||||
const option = sidebarDangerDialogRequest.value?.option;
|
||||
function updateSidebarDangerDialogOption(event: Event, optionOverride?: SidebarDangerDialogOption) {
|
||||
const option = optionOverride ?? sidebarDangerDialogRequest.value?.option;
|
||||
if (!option) return;
|
||||
option.checked = (event.target as HTMLInputElement).checked;
|
||||
void option.onChange?.(option.checked);
|
||||
@@ -2490,6 +2491,17 @@ defineExpose({ focusSearch, createNewGroup, collapseAllTreeNodes });
|
||||
<div class="h-full bg-primary transition-[width] duration-200" :style="{ width: `${Math.round((sidebarDangerDialogRequest.progress.completed / sidebarDangerDialogRequest.progress.total) * 100)}%` }" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="sidebarDangerDialogRequest.options?.length" class="mb-3 flex flex-wrap gap-2">
|
||||
<template v-for="(option, optionIndex) in sidebarDangerDialogRequest.options ?? []" :key="`danger-option-${optionIndex}`">
|
||||
<label class="flex items-start gap-2 rounded-md border px-3 py-2 text-sm" :class="[option.compact ? 'min-w-32 flex-1' : 'w-full', option.danger && option.checked ? 'border-destructive/50 bg-destructive/10' : 'bg-muted/20']" :title="option.compact ? option.hint : undefined">
|
||||
<input :checked="option.checked" :disabled="sidebarDangerDialogConfirming" type="checkbox" class="mt-0.5 h-3.5 w-3.5 shrink-0" :class="option.danger ? 'accent-destructive' : 'accent-primary'" @change="updateSidebarDangerDialogOption($event, option)" />
|
||||
<span class="grid gap-0.5">
|
||||
<span class="font-medium" :class="option.danger && option.checked ? 'text-destructive' : 'text-foreground'">{{ option.label }}</span>
|
||||
<span v-if="!option.compact" class="text-xs leading-5 text-muted-foreground">{{ option.hint }}</span>
|
||||
</span>
|
||||
</label>
|
||||
</template>
|
||||
</div>
|
||||
<label v-if="sidebarDangerDialogRequest.option" class="mb-3 flex items-start gap-2 rounded-md border bg-muted/20 px-3 py-2 text-sm">
|
||||
<input :checked="sidebarDangerDialogRequest.option.checked" type="checkbox" class="mt-0.5 h-3.5 w-3.5 shrink-0 accent-primary" @change="updateSidebarDangerDialogOption" />
|
||||
<span class="grid gap-0.5">
|
||||
|
||||
@@ -197,6 +197,7 @@ import {
|
||||
isLoadingStructurePreview,
|
||||
showEmptyTableConfirm,
|
||||
showTruncateTableConfirm,
|
||||
showVacuumTableConfirm,
|
||||
showMysqlAutoIncrementConfirm,
|
||||
showRenameObjectDialog,
|
||||
renameObjectName,
|
||||
@@ -208,6 +209,10 @@ import {
|
||||
emptyTablePreviewSql,
|
||||
truncateTablePreviewSql,
|
||||
truncateTableCascade,
|
||||
vacuumTableFull,
|
||||
vacuumTableAnalyze,
|
||||
vacuumTablePreviewSql,
|
||||
vacuumTableExecuting,
|
||||
mysqlAutoIncrementValue,
|
||||
mysqlAutoIncrementPreviewSql,
|
||||
dropObjectPreviewSql,
|
||||
@@ -510,6 +515,7 @@ const {
|
||||
const {
|
||||
isTableNotView,
|
||||
supportsTruncate,
|
||||
supportsVacuum,
|
||||
supportsMysqlAutoIncrement,
|
||||
canDropTableCascade,
|
||||
canTruncateTableCascade,
|
||||
@@ -522,6 +528,9 @@ const {
|
||||
confirmEmptyTable,
|
||||
truncateTable,
|
||||
confirmTruncateTable,
|
||||
vacuumTable,
|
||||
refreshVacuumPreviewForOptions,
|
||||
confirmVacuumTable,
|
||||
mysqlAutoIncrement,
|
||||
refreshMysqlAutoIncrementPreviewSql,
|
||||
confirmMysqlAutoIncrement,
|
||||
@@ -3945,7 +3954,7 @@ function dangerRequest(request: Omit<SidebarDangerDialogRequest, "target">): Sid
|
||||
const confirm = request.confirm;
|
||||
routedRequest.confirm = async () => {
|
||||
activateActionTarget(target);
|
||||
await confirm();
|
||||
return confirm();
|
||||
};
|
||||
if (request.option?.onChange) {
|
||||
const onChange = request.option.onChange;
|
||||
@@ -3954,6 +3963,14 @@ function dangerRequest(request: Omit<SidebarDangerDialogRequest, "target">): Sid
|
||||
await onChange(checked);
|
||||
};
|
||||
}
|
||||
for (const option of request.options ?? []) {
|
||||
if (!option.onChange) continue;
|
||||
const onChange = option.onChange;
|
||||
option.onChange = async (checked) => {
|
||||
activateActionTarget(target);
|
||||
await onChange(checked);
|
||||
};
|
||||
}
|
||||
if (request.textInput?.onInput) {
|
||||
const onInput = request.textInput.onInput;
|
||||
request.textInput.onInput = async (value) => {
|
||||
@@ -4062,6 +4079,49 @@ routeDangerDialog(showTruncateTableConfirm, () =>
|
||||
}),
|
||||
);
|
||||
|
||||
routeDangerDialog(showVacuumTableConfirm, () =>
|
||||
dangerRequest({
|
||||
title: t("contextMenu.vacuumTableTitle"),
|
||||
message: t("contextMenu.vacuumTableMessage", { name: activeNode.value.label }),
|
||||
get detailsText() {
|
||||
if (vacuumTableExecuting.value) return t("contextMenu.vacuumTableRunningHint");
|
||||
return vacuumTableFull.value ? t("contextMenu.vacuumTableFullRisk") : vacuumTableAnalyze.value ? t("contextMenu.vacuumTableAnalyzeRisk") : t("contextMenu.vacuumTableDefaultRisk");
|
||||
},
|
||||
get sql() {
|
||||
return vacuumTablePreviewSql.value;
|
||||
},
|
||||
get confirmLabel() {
|
||||
return vacuumTableExecuting.value ? t("contextMenu.vacuumTableRunning") : vacuumTableFull.value ? t("contextMenu.vacuumTableFullConfirm") : t("contextMenu.vacuumTable");
|
||||
},
|
||||
loading: false,
|
||||
closeOnConfirm: false,
|
||||
options: [
|
||||
{
|
||||
checked: vacuumTableAnalyze.value,
|
||||
label: t("contextMenu.vacuumTableAnalyze"),
|
||||
hint: t("contextMenu.vacuumTableAnalyzeHint"),
|
||||
compact: true,
|
||||
async onChange(checked) {
|
||||
vacuumTableAnalyze.value = checked;
|
||||
await refreshVacuumPreviewForOptions();
|
||||
},
|
||||
},
|
||||
{
|
||||
checked: vacuumTableFull.value,
|
||||
label: t("contextMenu.vacuumTableFull"),
|
||||
hint: t("contextMenu.vacuumTableFullHint"),
|
||||
compact: true,
|
||||
danger: true,
|
||||
async onChange(checked) {
|
||||
vacuumTableFull.value = checked;
|
||||
await refreshVacuumPreviewForOptions();
|
||||
},
|
||||
},
|
||||
],
|
||||
confirm: confirmVacuumTable,
|
||||
}),
|
||||
);
|
||||
|
||||
routeDangerDialog(showMysqlAutoIncrementConfirm, () =>
|
||||
dangerRequest({
|
||||
title: t("contextMenu.mysqlAutoIncrementTitle"),
|
||||
@@ -5178,6 +5238,9 @@ function buildObjectSidebarMenu(context: SidebarMenuFactoryContext): boolean {
|
||||
items.push({ label: t("contextMenu.duplicateStructure"), action: duplicateStructure, icon: CopyPlus });
|
||||
// Keep menu copy aligned with keyboard copy so frozen multi-selection and single-row fallback stay compatible.
|
||||
items.push(...treeTableClipboardMenuItems(node));
|
||||
if (supportsVacuum.value) {
|
||||
destructiveActions.push({ label: t("contextMenu.vacuumTable"), action: vacuumTable, icon: Activity, variant: "destructive" as const });
|
||||
}
|
||||
if (supportsMysqlAutoIncrement.value) {
|
||||
items.push({ label: t("contextMenu.mysqlAutoIncrement"), action: mysqlAutoIncrement, icon: Gauge });
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ export const structureDocCopyTitle = ref("");
|
||||
export const isLoadingStructurePreview = ref(false);
|
||||
export const showEmptyTableConfirm = ref(false);
|
||||
export const showTruncateTableConfirm = ref(false);
|
||||
export const showVacuumTableConfirm = ref(false);
|
||||
export const showMysqlAutoIncrementConfirm = ref(false);
|
||||
export const showRenameObjectDialog = ref(false);
|
||||
export const renameObjectName = ref("");
|
||||
@@ -48,6 +49,11 @@ export const batchDropCascade = ref(false);
|
||||
export const emptyTablePreviewSql = ref("");
|
||||
export const truncateTablePreviewSql = ref("");
|
||||
export const truncateTableCascade = ref(false);
|
||||
export const vacuumTableFull = ref(false);
|
||||
export const vacuumTableAnalyze = ref(false);
|
||||
export const vacuumTablePreviewSql = ref("");
|
||||
export const vacuumTablePreviewKey = ref("");
|
||||
export const vacuumTableExecuting = ref(false);
|
||||
export const mysqlAutoIncrementValue = ref("1");
|
||||
export const mysqlAutoIncrementPreviewSql = ref("");
|
||||
export const mysqlAutoIncrementPreviewKey = ref("");
|
||||
@@ -187,6 +193,7 @@ const openFlags = [
|
||||
showStructureDocCopyDialog,
|
||||
showEmptyTableConfirm,
|
||||
showTruncateTableConfirm,
|
||||
showVacuumTableConfirm,
|
||||
showMysqlAutoIncrementConfirm,
|
||||
showDropObjectConfirm,
|
||||
showRenameObjectDialog,
|
||||
@@ -230,6 +237,7 @@ export function resetSidebarTreeDialogState() {
|
||||
cloneMongoCollectionLoading.value = false;
|
||||
resetMongoCreateIndexForm();
|
||||
resetMongoIndexManager();
|
||||
vacuumTableExecuting.value = false;
|
||||
sidebarTreeDialogOwner.value = null;
|
||||
sidebarDangerTarget.value = null;
|
||||
sidebarFormTarget.value = null;
|
||||
|
||||
Reference in new issue
Block a user