feat(editor): configure SQL variable syntax
This commit is contained in:
1 parent
54632f4c16
commit
1a309b6b63
18 files changed
+450
-24
No files matched your search
@@ -88,6 +88,7 @@ import { normalizeSqlFormatterSettings, type SqlFormatterSettings } from "@/lib/
|
||||
import { currentExecutableStatementRange, type SqlTextRange } from "@/lib/sql/sqlStatementRanges";
|
||||
import { executableStatementRangeCacheForDoc, executableStatementRangeStartingAt, type ExecutableStatementRangeCache } from "@/lib/sql/executableStatementRangeCache";
|
||||
import { EMPTY_TABLE_COLUMN_TEMPLATE_DATA_TYPE, parseTableColumnTemplateFields, TABLE_COLUMN_TEMPLATE_DATABASE_TYPES } from "@/lib/table/tableColumnTemplates";
|
||||
import { DEFAULT_SQL_VARIABLE_SYNTAX_TOGGLES, normalizeSqlVariableSyntaxOverrides, SQL_VARIABLE_SYNTAX_DATABASE_TYPES, SQL_VARIABLE_SYNTAX_KEYS, SQL_VARIABLE_SYNTAX_TOKENS, type SqlVariableSyntaxOverrides, type SqlVariableSyntaxToggles } from "@/lib/sql/sqlVariableSyntax";
|
||||
import { buildMcpCodexConfig, buildMcpJsonConfig, buildMcpOpenCodeConfig, buildMcpVsCodeConfig, type McpEnvEntry, type McpLaunchConfig } from "@/lib/mcp/mcpConfigTemplates";
|
||||
import { isWindows } from "@/lib/backend/platform";
|
||||
import { combineDataTypeForDatabase, dataTypeLengthInputValue, getDataTypeOptions, getDefaultLengthForType, isDataTypeLengthDisabled, splitDataType } from "@/lib/table/tableStructureEditorState";
|
||||
@@ -284,6 +285,33 @@ const editInfiniteScroll = ref(settingsStore.editorSettings.infiniteScroll);
|
||||
const editInfiniteScrollMaxRows = ref(settingsStore.editorSettings.infiniteScrollMaxRows);
|
||||
const editTableColumnTemplateRows = ref<TableColumnTemplateGridRow[]>(tableColumnTemplateRowsFromSettings(settingsStore.editorSettings.tableColumnTemplateFields));
|
||||
const editTableColumnTemplateDatabaseType = ref<DatabaseType>(TABLE_COLUMN_TEMPLATE_DATABASE_TYPES[0] ?? "mysql");
|
||||
const editSqlVariableSyntaxOverrides = ref<SqlVariableSyntaxOverrides>(normalizeSqlVariableSyntaxOverrides(settingsStore.editorSettings.sqlVariableSyntaxOverrides));
|
||||
const editSqlVariableSyntaxDatabaseType = ref<DatabaseType>(SQL_VARIABLE_SYNTAX_DATABASE_TYPES[0] ?? "mysql");
|
||||
|
||||
function sqlVariableSyntaxToggle(key: keyof SqlVariableSyntaxToggles): boolean {
|
||||
return editSqlVariableSyntaxOverrides.value[editSqlVariableSyntaxDatabaseType.value]?.[key] ?? true;
|
||||
}
|
||||
|
||||
function setSqlVariableSyntaxToggle(key: keyof SqlVariableSyntaxToggles, value: boolean) {
|
||||
const dbType = editSqlVariableSyntaxDatabaseType.value;
|
||||
const merged: SqlVariableSyntaxToggles = {
|
||||
...DEFAULT_SQL_VARIABLE_SYNTAX_TOGGLES,
|
||||
...editSqlVariableSyntaxOverrides.value[dbType],
|
||||
[key]: value,
|
||||
};
|
||||
const next: SqlVariableSyntaxOverrides = { ...editSqlVariableSyntaxOverrides.value };
|
||||
// Keep storage sparse: an all-enabled type has no entry; otherwise persist only the disabled syntaxes.
|
||||
if (SQL_VARIABLE_SYNTAX_KEYS.every((toggleKey) => merged[toggleKey])) {
|
||||
delete next[dbType];
|
||||
} else {
|
||||
const partial: Partial<SqlVariableSyntaxToggles> = {};
|
||||
for (const toggleKey of SQL_VARIABLE_SYNTAX_KEYS) {
|
||||
if (!merged[toggleKey]) partial[toggleKey] = false;
|
||||
}
|
||||
next[dbType] = partial;
|
||||
}
|
||||
editSqlVariableSyntaxOverrides.value = next;
|
||||
}
|
||||
const tableColumnTemplateSectionRef = ref<HTMLElement | null>(null);
|
||||
const draggedTableColumnTemplateRowId = ref<string | null>(null);
|
||||
let tableColumnTemplatePointerDragCleanup: (() => void) | null = null;
|
||||
@@ -393,6 +421,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
|
||||
updateDownloadSource: editUpdateDownloadSource.value,
|
||||
toolbarItems: { ...editToolbarItems.value },
|
||||
snippets: editSnippets.value,
|
||||
sqlVariableSyntaxOverrides: editSqlVariableSyntaxOverrides.value,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -664,6 +693,7 @@ function syncEditorSettingsDraftFromStore() {
|
||||
editUpdateDownloadSource.value = settingsStore.editorSettings.updateDownloadSource;
|
||||
editToolbarItems.value = { ...settingsStore.editorSettings.toolbarItems };
|
||||
editSnippets.value = settingsStore.editorSettings.snippets.map(editableSnippet);
|
||||
editSqlVariableSyntaxOverrides.value = normalizeSqlVariableSyntaxOverrides(settingsStore.editorSettings.sqlVariableSyntaxOverrides);
|
||||
editEditorSettingsBase.value = editorSettingsDraftFromSettings(settingsStore.editorSettings);
|
||||
}
|
||||
|
||||
@@ -818,6 +848,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
|
||||
editSqlSemanticDiagnosticsEnabled.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsEnabled;
|
||||
editConfirmDangerousSqlExecution.value = DEFAULT_EDITOR_SETTINGS.confirmDangerousSqlExecution;
|
||||
editConfirmUnsavedSqlClose.value = DEFAULT_EDITOR_SETTINGS.confirmUnsavedSqlClose;
|
||||
editSqlVariableSyntaxOverrides.value = normalizeSqlVariableSyntaxOverrides(DEFAULT_EDITOR_SETTINGS.sqlVariableSyntaxOverrides);
|
||||
} else if (tab === "formatter") {
|
||||
editSqlFormatter.value = normalizeSqlFormatterSettings(DEFAULT_EDITOR_SETTINGS.sqlFormatter);
|
||||
sqlFormatterConfigValid.value = true;
|
||||
@@ -890,6 +921,7 @@ function resetAllDefaults() {
|
||||
editSqlSemanticDiagnosticsEnabled.value = DEFAULT_EDITOR_SETTINGS.sqlSemanticDiagnosticsEnabled;
|
||||
editConfirmDangerousSqlExecution.value = DEFAULT_EDITOR_SETTINGS.confirmDangerousSqlExecution;
|
||||
editConfirmUnsavedSqlClose.value = DEFAULT_EDITOR_SETTINGS.confirmUnsavedSqlClose;
|
||||
editSqlVariableSyntaxOverrides.value = normalizeSqlVariableSyntaxOverrides(DEFAULT_EDITOR_SETTINGS.sqlVariableSyntaxOverrides);
|
||||
editAppLayout.value = DEFAULT_EDITOR_SETTINGS.appLayout;
|
||||
editShowTrayIcon.value = DEFAULT_DESKTOP_SETTINGS.show_tray_icon;
|
||||
editQuitOnClose.value = DEFAULT_DESKTOP_SETTINGS.quit_on_close;
|
||||
@@ -2747,6 +2779,39 @@ onUnmounted(cleanupPreviewEditor);
|
||||
|
||||
<Separator />
|
||||
|
||||
<div class="space-y-3">
|
||||
<div class="flex flex-wrap items-start justify-between gap-3">
|
||||
<div class="space-y-1">
|
||||
<div class="text-sm font-medium text-muted-foreground">{{ t("settings.sqlVariableSyntax") }}</div>
|
||||
<p class="text-xs text-muted-foreground">{{ t("settings.sqlVariableSyntaxDescription") }}</p>
|
||||
</div>
|
||||
<Select v-model="editSqlVariableSyntaxDatabaseType">
|
||||
<SelectTrigger class="h-8 w-44 px-2 text-xs">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent class="max-h-72">
|
||||
<SelectItem v-for="dbType in SQL_VARIABLE_SYNTAX_DATABASE_TYPES" :key="dbType" :value="dbType">
|
||||
{{ dbType }}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div class="grid gap-3 md:grid-cols-2">
|
||||
<div v-for="key in SQL_VARIABLE_SYNTAX_KEYS" :key="key" class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="min-w-0 space-y-1">
|
||||
<Label :for="`sql-var-syntax-${key}`" class="flex items-center gap-1.5">
|
||||
<span class="font-mono text-xs text-primary">{{ SQL_VARIABLE_SYNTAX_TOKENS[key] }}</span>
|
||||
<span>{{ t(`settings.sqlVariableSyntax_${key}`) }}</span>
|
||||
</Label>
|
||||
<p class="text-xs text-muted-foreground">{{ t(`settings.sqlVariableSyntax_${key}Description`) }}</p>
|
||||
</div>
|
||||
<Switch :id="`sql-var-syntax-${key}`" :model-value="sqlVariableSyntaxToggle(key)" class="mt-0.5 shrink-0" @update:model-value="(value) => setSqlVariableSyntaxToggle(key, value as boolean)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<!-- Live Preview -->
|
||||
<div class="space-y-2">
|
||||
<Label>{{ t("settings.preview") }}</Label>
|
||||
|
||||
@@ -25,6 +25,7 @@ const props = defineProps<{
|
||||
sql: string;
|
||||
parameters: SqlParameterDescriptor[];
|
||||
databaseType?: DatabaseType;
|
||||
enabledSyntaxes?: SqlParameterSyntax[];
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -46,7 +47,7 @@ const syntaxLabels: Record<SqlParameterSyntax, string> = {
|
||||
sqlserver: "@name",
|
||||
};
|
||||
|
||||
const resolvedSql = computed(() => substituteSqlParameters(props.sql, values.value, { databaseType: props.databaseType }));
|
||||
const resolvedSql = computed(() => substituteSqlParameters(props.sql, values.value, { databaseType: props.databaseType, enabledSyntaxes: props.enabledSyntaxes }));
|
||||
const highlightedSql = computed(() => highlight(resolvedSql.value));
|
||||
|
||||
watch(
|
||||
|
||||
@@ -20,7 +20,7 @@ const DataGenerateDialog = defineAsyncComponent(() => import("@/components/gener
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useDialogSources } from "@/composables/useDialogSources";
|
||||
import type { ConnectionDeepLinkDraft } from "@/lib/connection/connectionDeepLink";
|
||||
import type { SqlParameterDescriptor } from "@/lib/sql/sqlParameters";
|
||||
import type { SqlParameterDescriptor, SqlParameterSyntax } from "@/lib/sql/sqlParameters";
|
||||
import type { ConfigTab } from "@/components/connection/ConnectionDialog.vue";
|
||||
import type { DatabaseType } from "@/types/database";
|
||||
|
||||
@@ -35,6 +35,7 @@ const props = defineProps<{
|
||||
sqlParameterSourceSql: string;
|
||||
sqlParameterNames: SqlParameterDescriptor[];
|
||||
sqlParameterDatabaseType?: DatabaseType;
|
||||
sqlParameterEnabledSyntaxes?: SqlParameterSyntax[];
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -135,7 +136,16 @@ watch(
|
||||
@update:suppress-future-prompts="emit('update:suppressDangerConfirm', $event)"
|
||||
@confirm="emit('dangerConfirm')"
|
||||
/>
|
||||
<SqlParameterDialog v-if="showSqlParameterDialog" :open="showSqlParameterDialog" :sql="sqlParameterSourceSql" :parameters="sqlParameterNames" :database-type="sqlParameterDatabaseType" @update:open="emit('update:showSqlParameterDialog', $event)" @execute="emit('sqlParametersConfirm', $event)" />
|
||||
<SqlParameterDialog
|
||||
v-if="showSqlParameterDialog"
|
||||
:open="showSqlParameterDialog"
|
||||
:sql="sqlParameterSourceSql"
|
||||
:parameters="sqlParameterNames"
|
||||
:database-type="sqlParameterDatabaseType"
|
||||
:enabled-syntaxes="sqlParameterEnabledSyntaxes"
|
||||
@update:open="emit('update:showSqlParameterDialog', $event)"
|
||||
@execute="emit('sqlParametersConfirm', $event)"
|
||||
/>
|
||||
<DataTransferDialog v-model:open="dialogs.showTransferDialog.value" :prefill-connection-id="dialogs.transferPrefillConnectionId.value" :prefill-database="dialogs.transferPrefillDatabase.value" />
|
||||
<SchemaDiffDialog v-if="dialogs.showSchemaDiffDialog.value" v-model:open="dialogs.showSchemaDiffDialog.value" :prefill-connection-id="dialogs.schemaDiffPrefillConnectionId.value" :prefill-database="dialogs.schemaDiffPrefillDatabase.value" :prefill-schema="dialogs.schemaDiffPrefillSchema.value" />
|
||||
<DataCompareDialog
|
||||
|
||||
Reference in new issue
Block a user