mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
query error markers
This commit is contained in:
parent
2f820d8dac
commit
1a7f06342f
@ -101,8 +101,9 @@ class TableWriter {
|
||||
}
|
||||
|
||||
class StreamHandler {
|
||||
constructor(resultIndexHolder, resolve) {
|
||||
constructor(resultIndexHolder, resolve, startLine) {
|
||||
this.recordset = this.recordset.bind(this);
|
||||
this.startLine = startLine;
|
||||
this.row = this.row.bind(this);
|
||||
// this.error = this.error.bind(this);
|
||||
this.done = this.done.bind(this);
|
||||
@ -155,14 +156,20 @@ class StreamHandler {
|
||||
this.resolve();
|
||||
}
|
||||
info(info) {
|
||||
if (info.line != null) {
|
||||
info = {
|
||||
...info,
|
||||
line: this.startLine + info.line,
|
||||
};
|
||||
}
|
||||
process.send({ msgtype: 'info', info });
|
||||
}
|
||||
}
|
||||
|
||||
function handleStream(driver, resultIndexHolder, sql) {
|
||||
function handleStream(driver, resultIndexHolder, sqlItem) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const handler = new StreamHandler(resultIndexHolder, resolve);
|
||||
driver.stream(systemConnection, sql, handler);
|
||||
const handler = new StreamHandler(resultIndexHolder, resolve, sqlItem.trimStart.line);
|
||||
driver.stream(systemConnection, sqlItem.text, handler);
|
||||
});
|
||||
}
|
||||
|
||||
@ -221,7 +228,10 @@ async function handleExecuteQuery({ sql }) {
|
||||
const resultIndexHolder = {
|
||||
value: 0,
|
||||
};
|
||||
for (const sqlItem of splitQuery(sql, driver.getQuerySplitterOptions('stream'))) {
|
||||
for (const sqlItem of splitQuery(sql, {
|
||||
...driver.getQuerySplitterOptions('stream'),
|
||||
returnRichInfo: true,
|
||||
})) {
|
||||
await handleStream(driver, resultIndexHolder, sqlItem);
|
||||
// const handler = new StreamHandler(resultIndex);
|
||||
// const stream = await driver.stream(systemConnection, sqlItem, handler);
|
||||
|
@ -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>
|
||||
|
@ -134,7 +134,7 @@ async function tediousStream(pool, sql, options) {
|
||||
const { message, lineNumber, procName } = info;
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
line: lineNumber != null && lineNumber > 0 ? lineNumber - 1 : lineNumber,
|
||||
procedure: procName,
|
||||
time: new Date(),
|
||||
severity: 'info',
|
||||
@ -144,7 +144,7 @@ async function tediousStream(pool, sql, options) {
|
||||
const { message, lineNumber, procName } = error;
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
line: lineNumber != null && lineNumber > 0 ? lineNumber - 1 : lineNumber,
|
||||
procedure: procName,
|
||||
time: new Date(),
|
||||
severity: 'error',
|
||||
|
@ -112,11 +112,10 @@ const drivers = driverBases.map(driverBase => ({
|
||||
|
||||
const handleError = error => {
|
||||
console.log('ERROR', error);
|
||||
const { message, lineNumber, procName } = error;
|
||||
const { message } = error;
|
||||
options.info({
|
||||
message,
|
||||
line: lineNumber,
|
||||
procedure: procName,
|
||||
line: 0,
|
||||
time: new Date(),
|
||||
severity: 'error',
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user