mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-24 22:16:00 +00:00
query error markers
This commit is contained in:
@@ -65,7 +65,7 @@
|
||||
let changeIndex = 0;
|
||||
let rowCountLoaded = null;
|
||||
|
||||
const throttleLoadNext = _.throttle(() => domGrid.resetLoadedAll(), 500);
|
||||
const throttleLoadNext = _.throttle(() => domGrid?.resetLoadedAll(), 500);
|
||||
|
||||
const handleJslDataStats = stats => {
|
||||
if (stats.changeIndex < changeIndex) return;
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
export let splitterOptions = null;
|
||||
export let onKeyDown = null;
|
||||
export let onExecuteFragment = null;
|
||||
export let errorMessages = null;
|
||||
|
||||
const tabVisible: any = getContext('tabVisible');
|
||||
|
||||
@@ -184,16 +185,28 @@
|
||||
return editor;
|
||||
}
|
||||
|
||||
export function getCurrentCommandText(): string {
|
||||
if (currentPart != null) return currentPart.text;
|
||||
if (!editor) return '';
|
||||
export function getCurrentCommandText(): { text: string; line?: number } {
|
||||
if (currentPart != null) {
|
||||
return {
|
||||
text: currentPart.text,
|
||||
line: currentPart.trimStart.line,
|
||||
};
|
||||
}
|
||||
if (!editor) return { text: '' };
|
||||
const selectedText = editor.getSelectedText();
|
||||
if (selectedText) return selectedText;
|
||||
if (selectedText)
|
||||
return {
|
||||
text: selectedText,
|
||||
line: editor.getSelectionRange().start.row,
|
||||
};
|
||||
if (editor.getHighlightActiveLine()) {
|
||||
const line = editor.getSelectionRange().start.row;
|
||||
return editor.session.getLine(line);
|
||||
return {
|
||||
text: editor.session.getLine(line),
|
||||
line,
|
||||
};
|
||||
}
|
||||
return '';
|
||||
return { text: '' };
|
||||
}
|
||||
|
||||
export function getCodeCompletionCommandText() {
|
||||
@@ -292,13 +305,25 @@
|
||||
}
|
||||
|
||||
function updateAnnotations() {
|
||||
editor.session.setAnnotations(
|
||||
(queryParts || []).map(part => ({
|
||||
row: part.trimStart.line,
|
||||
text: part.text,
|
||||
className: 'ace-gutter-sql-run',
|
||||
}))
|
||||
);
|
||||
editor?.session?.setAnnotations([
|
||||
...(queryParts || [])
|
||||
.filter(part => !(errorMessages || []).find(err => err.line == part.trimStart.line))
|
||||
.map(part => ({
|
||||
row: part.trimStart.line,
|
||||
text: part.text,
|
||||
className: 'ace-gutter-sql-run',
|
||||
})),
|
||||
...(errorMessages || []).map(error => ({
|
||||
row: error.line,
|
||||
text: error.message,
|
||||
type: 'error',
|
||||
})),
|
||||
]);
|
||||
}
|
||||
|
||||
$: {
|
||||
errorMessages;
|
||||
updateAnnotations();
|
||||
}
|
||||
|
||||
const handleContextMenu = e => {
|
||||
@@ -455,10 +480,10 @@
|
||||
|
||||
const part = (queryParts || []).find(part => part.trimStart.line == row);
|
||||
if (part && onExecuteFragment) {
|
||||
onExecuteFragment(part.text);
|
||||
onExecuteFragment(part.text, part.trimStart.line);
|
||||
e.stop();
|
||||
editor.moveCursorTo(part.trimStart.line, 0);
|
||||
editor.selection.clearSelection()
|
||||
editor.selection.clearSelection();
|
||||
}
|
||||
},
|
||||
true
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
export let items: any[];
|
||||
export let showProcedure = false;
|
||||
export let showLine = false;
|
||||
export let startLine = 0;
|
||||
|
||||
$: time0 = items[0] && new Date(items[0].time).getTime();
|
||||
|
||||
@@ -58,7 +59,7 @@
|
||||
<td>{row.procedure || ''}</td>
|
||||
{/if}
|
||||
{#if showLine}
|
||||
<td>{row.line || ''}</td>
|
||||
<td>{row.line == null ? '' : row.line + 1 + startLine}</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
@@ -13,8 +13,11 @@
|
||||
export let eventName;
|
||||
export let executeNumber;
|
||||
export let showNoMessagesAlert = false;
|
||||
export let startLine = 0;
|
||||
export let onChangeErrors = null;
|
||||
|
||||
const cachedMessagesRef = createRef([]);
|
||||
const lastErrorMessageCountRef = createRef(0);
|
||||
|
||||
let displayedMessages = [];
|
||||
|
||||
@@ -44,11 +47,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
if (onChangeErrors) {
|
||||
const errors = displayedMessages.filter(x => x.severity == 'error');
|
||||
if (lastErrorMessageCountRef.get() != errors.length) {
|
||||
onChangeErrors(
|
||||
errors.map(err => ({
|
||||
...err,
|
||||
line: err.line == null ? null : err.line + startLine,
|
||||
}))
|
||||
);
|
||||
lastErrorMessageCountRef.set(errors.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$: $effect;
|
||||
</script>
|
||||
|
||||
{#if showNoMessagesAlert && (!displayedMessages || displayedMessages.length == 0)}
|
||||
<ErrorInfo message="No messages" icon="img alert" />
|
||||
{:else}
|
||||
<MessageView items={displayedMessages} on:messageclick {showProcedure} {showLine} />
|
||||
<MessageView items={displayedMessages} on:messageclick {showProcedure} {showLine} {startLine} />
|
||||
{/if}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
return domEditor.getEditor();
|
||||
}
|
||||
|
||||
export function getCurrentCommandText(): string {
|
||||
export function getCurrentCommandText(): { text: string; line?: number } {
|
||||
return domEditor.getCurrentCommandText();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +86,11 @@
|
||||
|
||||
let busy = false;
|
||||
let executeNumber = 0;
|
||||
let executeStartLine = 0;
|
||||
let visibleResultTabs = false;
|
||||
let sessionId = null;
|
||||
let resultCount;
|
||||
|
||||
let errorMessages;
|
||||
let domEditor;
|
||||
|
||||
$: connection = useConnectionInfo({ conid });
|
||||
@@ -143,13 +144,14 @@
|
||||
return !!conid && (!$connection?.isReadOnly || driver?.readOnlySessions);
|
||||
}
|
||||
|
||||
async function executeCore(sql) {
|
||||
async function executeCore(sql, startLine = 0) {
|
||||
if (busy) return;
|
||||
if (!sql || !sql.trim()) {
|
||||
showSnackbarError('Skipped executing empty query');
|
||||
return;
|
||||
}
|
||||
|
||||
executeStartLine = startLine;
|
||||
executeNumber++;
|
||||
visibleResultTabs = true;
|
||||
|
||||
@@ -179,13 +181,14 @@
|
||||
}
|
||||
|
||||
export async function executeCurrent() {
|
||||
const sql = domEditor.getCurrentCommandText();
|
||||
await executeCore(sql);
|
||||
const cmd = domEditor.getCurrentCommandText();
|
||||
await executeCore(cmd.text, cmd.line);
|
||||
}
|
||||
|
||||
export async function execute() {
|
||||
const selectedText = domEditor.getEditor().getSelectedText();
|
||||
await executeCore(selectedText || $editorValue);
|
||||
const startLine = domEditor.getEditor().getSelectionRange().start.row;
|
||||
await executeCore(selectedText || $editorValue, selectedText ? startLine : 0);
|
||||
}
|
||||
|
||||
export async function kill() {
|
||||
@@ -257,6 +260,10 @@
|
||||
: null,
|
||||
});
|
||||
|
||||
function handleChangeErrors(errors) {
|
||||
errorMessages = errors;
|
||||
}
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
{ command: 'query.execute' },
|
||||
@@ -289,13 +296,17 @@
|
||||
splitterOptions={driver?.getQuerySplitterOptions('script')}
|
||||
value={$editorState.value || ''}
|
||||
menu={createMenu()}
|
||||
on:input={e => setEditorData(e.detail)}
|
||||
on:input={e => {
|
||||
setEditorData(e.detail);
|
||||
errorMessages = [];
|
||||
}}
|
||||
on:focus={() => {
|
||||
activator.activate();
|
||||
invalidateCommands();
|
||||
}}
|
||||
bind:this={domEditor}
|
||||
onExecuteFragment={sql => executeCore(sql)}
|
||||
onExecuteFragment={(sql, startLine) => executeCore(sql, startLine)}
|
||||
{errorMessages}
|
||||
/>
|
||||
{:else}
|
||||
<AceEditor
|
||||
@@ -319,8 +330,10 @@
|
||||
eventName={sessionId ? `session-info-${sessionId}` : null}
|
||||
on:messageClick={handleMesageClick}
|
||||
{executeNumber}
|
||||
startLine={executeStartLine}
|
||||
showProcedure
|
||||
showLine
|
||||
onChangeErrors={handleChangeErrors}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
</ResultTabs>
|
||||
|
||||
Reference in New Issue
Block a user