feat(metadata): persist and lazy-load table structure metadata

This commit is contained in:
yanguibao1997 authored and GitHub committed 2026-07-31 16:27:37 +08:00
1 parent 584848f732
commit 7be11f54c9
15 files changed
+747 -89

No files matched your search

@@ -9,7 +9,7 @@ import { loadEditorTheme, editorFontTheme } from "@/lib/editor/editorThemes";
import { createDbxCodeMirrorSqlDialect } from "@/lib/editor/codemirrorSqlDialect";
import { copyToClipboard } from "@/lib/common/clipboard";
import { formatSqlForDisplay, type SqlFormatDialect } from "@/lib/sql/sqlFormatter";
import * as api from "@/lib/backend/api";
import { loadObjectDdl } from "@/lib/metadata/objectDdlCache";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import EditorSearchPanel from "@/components/editor/EditorSearchPanel.vue";
@@ -51,23 +51,38 @@ const ddlEditorContainer = ref<HTMLDivElement>();
const ddlSearchPanelRef = ref<InstanceType<typeof EditorSearchPanel>>();
const ddlEditorView = shallowRef<EditorView | null>(null);
/** Fetches the table DDL when the dialog opens. */
async function loadDdl(force = false) {
ddlError.value = "";
ddlLoading.value = true;
if (force) destroyDdlEditor();
try {
const schema = props.schema || props.database;
const { ddl } = await loadObjectDdl(
{
connectionId: props.connectionId,
database: props.database,
schema,
tableName: props.tableName,
objectType: props.objectType,
catalog: props.catalog,
},
{ force },
);
ddlContent.value = await formatSqlForDisplay(ddl, props.formatDialect ?? props.dialect, settingsStore.editorSettings.sqlFormatter);
} catch (e: any) {
ddlError.value = e?.message || String(e);
} finally {
ddlLoading.value = false;
}
}
/** Loads the persisted table DDL when the dialog opens. */
watch(
() => props.open,
async (open) => {
if (!open) return;
ddlContent.value = "";
ddlError.value = "";
ddlLoading.value = true;
try {
const schema = props.schema || props.database;
const ddl = await api.getTableDisplayDdl(props.connectionId, props.database, schema, props.tableName, props.objectType, props.catalog);
ddlContent.value = await formatSqlForDisplay(ddl, props.formatDialect ?? props.dialect, settingsStore.editorSettings.sqlFormatter);
} catch (e: any) {
ddlError.value = e?.message || String(e);
} finally {
ddlLoading.value = false;
}
await loadDdl();
},
{ immediate: true },
);
@@ -171,21 +186,8 @@ onUnmounted(() => {
});
function retry() {
ddlError.value = "";
ddlLoading.value = true;
ddlContent.value = "";
const schema = props.schema || props.database;
api
.getTableDisplayDdl(props.connectionId, props.database, schema, props.tableName, props.objectType)
.then(async (ddl) => {
ddlContent.value = await formatSqlForDisplay(ddl, props.formatDialect ?? props.dialect, settingsStore.editorSettings.sqlFormatter);
})
.catch((e: any) => {
ddlError.value = e?.message || String(e);
})
.finally(() => {
ddlLoading.value = false;
});
void loadDdl(true);
}
function onClose() {
@@ -218,6 +220,10 @@ function onClose() {
</div>
<DialogFooter>
<Button variant="outline" @click="onClose">{{ t("common.close") }}</Button>
<Button variant="outline" :disabled="ddlLoading" :title="t('structureEditor.refresh')" @click="loadDdl(true)">
<RefreshCw class="h-4 w-4" />
{{ t("structureEditor.refresh") }}
</Button>
<Button variant="outline" :disabled="!ddlContent" @click="copyDdlContent">
<Clipboard class="h-4 w-4" />
{{ t("grid.copyDdl") }}