fix(sql-format): format source and DDL with proper dialects

This commit is contained in:
kkk000111999 authored and GitHub committed 2026-06-27 12:36:13 +08:00
1 parent ed35164828
commit ff810f3058
7 files changed
+136 -56

No files matched your search

@@ -8,6 +8,7 @@ import { useSettingsStore } from "@/stores/settingsStore";
import { loadEditorTheme, editorFontTheme } from "@/lib/editorThemes";
import { createDbxCodeMirrorSqlDialect } from "@/lib/codemirrorSqlDialect";
import { copyToClipboard } from "@/lib/clipboard";
import { formatSqlForDisplay, type SqlFormatDialect } from "@/lib/sqlFormatter";
import * as api from "@/lib/api";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
@@ -23,6 +24,8 @@ const props = withDefaults(
tableName: string;
/** SQL dialect for syntax highlighting. Non-PG/non-MSSQL databases fall back to MySQL (same as QueryEditor's source viewer). */
dialect: "mysql" | "postgres" | "sqlserver";
/** SQL formatter dialect. Kept separate from the syntax-highlighting dialect because several PG-compatible DBs highlight as MySQL. */
formatDialect?: SqlFormatDialect;
}>(),
{},
);
@@ -54,7 +57,7 @@ watch(
try {
const schema = props.schema || props.database;
const ddl = await api.getTableDdl(props.connectionId, props.database, schema, props.tableName);
ddlContent.value = ddl;
ddlContent.value = await formatSqlForDisplay(ddl, props.formatDialect ?? props.dialect, settingsStore.editorSettings.sqlFormatter);
} catch (e: any) {
ddlError.value = e?.message || String(e);
} finally {
@@ -160,8 +163,8 @@ function retry() {
const schema = props.schema || props.database;
api
.getTableDdl(props.connectionId, props.database, schema, props.tableName)
.then((ddl) => {
ddlContent.value = ddl;
.then(async (ddl) => {
ddlContent.value = await formatSqlForDisplay(ddl, props.formatDialect ?? props.dialect, settingsStore.editorSettings.sqlFormatter);
})
.catch((e: any) => {
ddlError.value = e?.message || String(e);
@@ -67,7 +67,7 @@ import { useSettingsStore } from "@/stores/settingsStore";
import { useQueryStore } from "@/stores/queryStore";
import QueryEditor from "@/components/editor/QueryEditor.vue";
import DdlViewDialog from "./DdlViewDialog.vue";
import type { SqlFormatDialect } from "@/lib/sqlFormatter";
import { formatSqlForDisplay, sqlFormatDialectForDbType, type SqlFormatDialect } from "@/lib/sqlFormatter";
import { isCancelSearchShortcut } from "@/lib/keyboardShortcuts";
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import {
@@ -122,6 +122,7 @@ const sourceRow = ref<ObjectBrowserRow | null>(null);
const sourceEditing = ref(false);
const effectiveDatabaseType = computed(() => effectiveDatabaseTypeForConnection(props.connection) ?? props.connection.db_type);
const tableStructureDatabaseType = computed(() => tableStructureDatabaseTypeForConnection(props.connection) ?? props.connection.db_type);
const sourceEditableText = ref("");
const sourceDraft = ref("");
const sourceSaving = ref(false);
const sourceSaveError = ref("");
@@ -178,25 +179,7 @@ const canOpenDiagram = computed(() => !!props.database && supportsSchemaDiagram(
const canOpenTableImport = computed(() => !!props.database && supportsTableImport(effectiveDatabaseType.value));
const supportsTruncateTable = computed(() => supportsTableTruncate(effectiveDatabaseType.value));
const sourceDialect = computed(() => codeMirrorSqlDialect(effectiveDatabaseType.value));
const sourceFormatDialect = computed<SqlFormatDialect>(() => {
switch (effectiveDatabaseType.value) {
case "mysql":
case "postgres":
case "sqlite":
case "sqlserver":
return effectiveDatabaseType.value;
case "rqlite":
case "turso":
return "sqlite";
case "gaussdb":
case "kwdb":
case "opengauss":
case "questdb":
return "postgres";
default:
return "generic";
}
});
const sourceFormatDialect = computed<SqlFormatDialect>(() => sqlFormatDialectForDbType(effectiveDatabaseType.value));
const objectFilters = computed<ObjectFilter[]>(() =>
(
[
@@ -425,6 +408,7 @@ async function openSource(row: ObjectBrowserRow) {
sourceContent.value = "";
sourceError.value = "";
sourceEditing.value = false;
sourceEditableText.value = "";
sourceDraft.value = "";
sourceSaveError.value = "";
sourceLoading.value = true;
@@ -437,7 +421,8 @@ async function openSource(row: ObjectBrowserRow) {
name: row.name,
source: result.source,
});
sourceContent.value = editable;
sourceEditableText.value = editable;
sourceContent.value = await formatSqlForDisplay(editable, sourceFormatDialect.value, settingsStore.editorSettings.sqlFormatter);
sourceDraft.value = editable;
sourceEditing.value = row.type !== "SEQUENCE";
} catch (e: any) {
@@ -457,8 +442,9 @@ async function openViewDdl(row: ObjectBrowserRow) {
name: row.name,
source: result.source,
});
const formatted = await formatSqlForDisplay(ddl, sourceFormatDialect.value, settingsStore.editorSettings.sqlFormatter);
const tabId = queryStore.createTab(props.connection.id, props.database, `DDL - ${row.name}`);
queryStore.updateSql(tabId, ddl);
queryStore.updateSql(tabId, formatted);
} catch (e: any) {
toast(e?.message || String(e), 5000);
}
@@ -630,6 +616,7 @@ function closeSource() {
sourceContent.value = "";
sourceError.value = "";
sourceEditing.value = false;
sourceEditableText.value = "";
sourceDraft.value = "";
sourceSaveError.value = "";
}
@@ -1040,8 +1027,8 @@ async function copySource() {
}
function editSource() {
if (!sourceRow.value || !sourceContent.value) return;
sourceDraft.value = sourceContent.value;
if (!sourceRow.value || !sourceEditableText.value) return;
sourceDraft.value = sourceEditableText.value;
sourceSaveError.value = "";
sourceEditing.value = true;
}
@@ -1684,7 +1671,7 @@ function getObjectBrowserMenuItems(item: ObjectBrowserRow): ContextMenuItem[] {
</DialogContent>
</Dialog>
<DdlViewDialog v-if="ddlDialogTarget" :connection-id="props.connection.id" :database="props.database" :schema="ddlDialogTarget.schema || selectedSchema" :table-name="ddlDialogTarget.name" :dialect="sourceDialect" v-model:open="showDdlDialog" />
<DdlViewDialog v-if="ddlDialogTarget" :connection-id="props.connection.id" :database="props.database" :schema="ddlDialogTarget.schema || selectedSchema" :table-name="ddlDialogTarget.name" :dialect="sourceDialect" :format-dialect="sourceFormatDialect" v-model:open="showDdlDialog" />
</template>
<style scoped>