diff --git a/packages/web/package.json b/packages/web/package.json index e391b5b3f..18ce6719b 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -24,6 +24,7 @@ "cross-env": "^7.0.3", "dbgate-datalib": "^4.1.1", "dbgate-sqltree": "^4.1.1", + "dbgate-query-splitter": "^4.1.1", "dbgate-tools": "^4.1.1", "dbgate-types": "^4.1.1", "file-selector": "^0.2.4", @@ -48,9 +49,7 @@ "svelte-select": "^3.17.0", "tslib": "^2.3.1", "typescript": "^4.4.3", - "uuid": "^3.4.0" - }, - "dependencies": { + "uuid": "^3.4.0", "chartjs-adapter-moment": "^1.0.0", "diff": "^5.0.0", "diff2html": "^3.4.13", diff --git a/packages/web/src/query/AceEditor.svelte b/packages/web/src/query/AceEditor.svelte index 3eaada494..66ca544f2 100644 --- a/packages/web/src/query/AceEditor.svelte +++ b/packages/web/src/query/AceEditor.svelte @@ -25,6 +25,7 @@ import _ from 'lodash'; import { handleCommandKeyDown } from '../commands/CommandListener.svelte'; import resizeObserver from '../utility/resizeObserver'; + import { splitQuery } from 'dbgate-query-splitter'; const EDITOR_ID = `svelte-ace-editor-div:${Math.floor(Math.random() * 10000000000)}`; const dispatch = createEventDispatcher<{ @@ -50,8 +51,9 @@ export let mode: string = 'text'; // String // export let theme: string = 'github'; // String export let options: any = {}; // Object - export let menu; - export let readOnly; + export let menu = null; + export let readOnly = false; + export let splitterOptions = null; let editor: ace.Editor; let contentBackup: string = ''; @@ -59,6 +61,10 @@ let clientWidth; let clientHeight; + let queryParts = []; + let currentPart = null; + let currentPartMarker = null; + const stdOptions = { showPrintMargin: false, }; @@ -104,6 +110,11 @@ } } + $: { + splitterOptions; + changedQueryParts(); + } + const resizeOnNextTick = () => tick().then(() => { if (editor) { @@ -126,6 +137,53 @@ if (event) handleCommandKeyDown(event); }; + function changedQueryParts() { + const editor = getEditor(); + if (splitterOptions && editor) { + const sql = editor.getValue(); + queryParts = splitQuery(sql, { + ...splitterOptions, + returnRichInfo: true, + }); + editor.setHighlightActiveLine(queryParts.length <= 1); + if (queryParts.length <= 1) { + removeCurrentPartMarker(); + } + } + changedCurrentQueryPart(); + } + + function changedCurrentQueryPart() { + if (queryParts.length <= 1) return; + const cursor = editor.getSelectionRange().start; + const part = queryParts.find( + x => + ((cursor.row == x.startLine && cursor.column >= x.startColumn) || cursor.row > x.startLine) && + ((cursor.row == x.endLine && cursor.column <= x.endColumn) || cursor.row < x.endLine) + ); + if (part?.text != currentPart?.text) { + removeCurrentPartMarker(); + + currentPart = part; + if (currentPart) { + currentPartMarker = editor + .getSession() + .addMarker( + new ace.Range(currentPart.startLine, currentPart.startColumn, currentPart.endLine, currentPart.endColumn), + 'ace_active-line', + 'text' + ); + } + } + } + + function removeCurrentPartMarker() { + if (currentPartMarker != null) { + editor.getSession().removeMarker(currentPartMarker); + currentPartMarker = null; + } + } + onMount(() => { editor = ace.edit(EDITOR_ID); @@ -146,6 +204,7 @@ editor.container.addEventListener('contextmenu', handleContextMenu); editor.keyBinding.addKeyboardHandler(handleKeyDown); + changedQueryParts(); }); onDestroy(() => { @@ -180,6 +239,11 @@ value = content; dispatch('input', content); contentBackup = content; + changedQueryParts(); + }); + + editor.on('changeSelection', () => { + changedCurrentQueryPart(); }); } diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte index 937df89c2..e7e0e1830 100644 --- a/packages/web/src/tabs/QueryTab.svelte +++ b/packages/web/src/tabs/QueryTab.svelte @@ -253,6 +253,7 @@ setEditorData(e.detail)} on:focus={() => { @@ -266,6 +267,7 @@ engine={$connection && $connection.engine} {conid} {database} + splitterOptions={driver?.getQuerySplitterOptions('stream')} value={$editorState.value || ''} menu={createMenu()} on:input={e => setEditorData(e.detail)}