feat(editor): add SQL compression
This commit is contained in:
1 parent
ff46b7cdbb
commit
9602cc3329
13 files changed
+487
-3
No files matched your search
@@ -17,7 +17,7 @@ import { executableStatementRangeAtCursor, executableStatementRangeCacheForDoc,
|
||||
import { currentStatementFrameRangeTo, visualSqlColumnsWithInlineHints } from "@/lib/sql/currentStatementFrame";
|
||||
import { expandToSqlStatementWindow, parseInsertValueHints } from "@/lib/sql/insertValueHints";
|
||||
import { insertValueHintColumnNames } from "@/lib/sql/insertValueHintColumns";
|
||||
import { formatSqlText, type SqlFormatDialect } from "@/lib/sql/sqlFormatter";
|
||||
import { formatSqlText, compressSqlText, type SqlFormatDialect } from "@/lib/sql/sqlFormatter";
|
||||
import { blankLineDeletionChanges, replaceSelectedEditorText } from "@/lib/editor/queryEditorTextEdits";
|
||||
import { buildSqlInConditionFromPasteSource, insertTextForSqlInCondition } from "@/lib/sql/sqlInListPaste";
|
||||
import { resolveSqlSingleQuoteKeyAction } from "@/lib/sql/sqlQuoteCaret";
|
||||
@@ -106,6 +106,7 @@ const props = defineProps<{
|
||||
syntaxDialect?: "mysql" | "postgres" | "sqlserver";
|
||||
formatDialect?: SqlFormatDialect;
|
||||
formatRequestId?: number;
|
||||
compressRequestId?: number;
|
||||
executionError?: string;
|
||||
executionErrorSql?: string;
|
||||
readOnly?: boolean;
|
||||
@@ -2112,6 +2113,30 @@ async function formatCurrentSql() {
|
||||
}
|
||||
}
|
||||
|
||||
function compressCurrentSql() {
|
||||
if (props.readOnly) return;
|
||||
const currentView = view.value;
|
||||
if (!currentView) return;
|
||||
|
||||
const originalState = currentView.state;
|
||||
const selection = originalState.selection.main;
|
||||
const compressesSelection = !selection.empty;
|
||||
const from = compressesSelection ? selection.from : 0;
|
||||
const to = compressesSelection ? selection.to : originalState.doc.length;
|
||||
const source = originalState.sliceDoc(from, to);
|
||||
if (!source.trim()) return;
|
||||
|
||||
const compressed = compressSqlText(source, props.formatDialect ?? props.dialect ?? "generic");
|
||||
if (currentView !== view.value || currentView.state !== originalState || currentView.state.sliceDoc(from, to) !== source) {
|
||||
return;
|
||||
}
|
||||
if (compressed === source) return;
|
||||
currentView.dispatch({
|
||||
changes: { from, to, insert: compressed },
|
||||
selection: compressesSelection ? { anchor: from, head: from + compressed.length } : { anchor: from + compressed.length },
|
||||
});
|
||||
}
|
||||
|
||||
function droppedTableReference(event: DragEvent) {
|
||||
return activeTableReferencePayloadValue() ?? parseTableReferencePayload(event.dataTransfer?.getData(DBX_TABLE_REFERENCE_MIME));
|
||||
}
|
||||
@@ -3911,6 +3936,13 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.compressRequestId,
|
||||
(val, oldVal) => {
|
||||
if (val && val !== oldVal) compressCurrentSql();
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.executionError,
|
||||
() => {
|
||||
|
||||
@@ -129,6 +129,7 @@ const props = defineProps<{
|
||||
executableSql: string;
|
||||
activeOutputView: "result" | "summary" | "explain" | "chart";
|
||||
formatSqlRequest: { id: number; tabId: string } | null;
|
||||
compressSqlRequest: { id: number; tabId: string } | null;
|
||||
selectedSql: string;
|
||||
cursorPos: number;
|
||||
blockDangerousRedisCommands: boolean;
|
||||
@@ -833,6 +834,7 @@ defineExpose({ focusSearch, refreshData, refreshQueryEditorCompletionCache, hand
|
||||
:syntax-dialect="editorSyntaxDialect"
|
||||
:format-dialect="activeSqlFormatDialect"
|
||||
:format-request-id="formatSqlRequest?.tabId === activeTab.id ? formatSqlRequest.id : undefined"
|
||||
:compress-request-id="compressSqlRequest?.tabId === activeTab.id ? compressSqlRequest.id : undefined"
|
||||
:execution-error="activeQueryError"
|
||||
:execution-error-sql="activeTab.lastExecutedSql"
|
||||
:statement-execution-markers="activeStatementExecutionMarkers"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch, watchEffect } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Play, Loader2, Square, Database, Check, Table2, AlignLeft, GitBranch, Save, FolderOpen, Layers, X, Shield, Download, RotateCcw, AlertTriangle, ClipboardPaste } from "@lucide/vue";
|
||||
import { Play, Loader2, Square, Database, Check, Table2, AlignLeft, GitBranch, Save, FolderOpen, Layers, X, Shield, Download, RotateCcw, AlertTriangle, ClipboardPaste, Minimize2 } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { SearchableSelect } from "@/components/ui/searchable-select";
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
|
||||
@@ -39,6 +39,7 @@ const emit = defineEmits<{
|
||||
explain: [];
|
||||
"update:explainMode": [mode: "explain" | "autotrace"];
|
||||
formatSql: [];
|
||||
compressSql: [];
|
||||
toggleSqlKeywordCase: [];
|
||||
saveSql: [];
|
||||
openSql: [];
|
||||
@@ -253,6 +254,14 @@ function databaseOptionIsProduction(database: string): boolean {
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ t("toolbar.formatSql") }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button variant="ghost" size="icon" class="h-6 w-6 text-amber-600 hover:bg-amber-500/10 hover:text-amber-700 dark:text-amber-300 dark:hover:text-amber-200" :disabled="activeTab.isExecuting || activeTab.isExplaining || !activeTab.sql.trim()" @click="emit('compressSql')">
|
||||
<Minimize2 class="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ t("toolbar.compressSql") }}</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<Button
|
||||
|
||||
Reference in new issue
Block a user