feat: update datasource when request contains CREATE keyword

This commit is contained in:
Yann Amsellem
2025-02-18 11:00:13 +01:00
parent b2c4088ec6
commit fab807b54f
4 changed files with 38 additions and 29 deletions

View File

@@ -3,7 +3,7 @@ type Callback = (...param: any[]) => void;
type OptionalRecord<K extends keyof any, T> = { [P in K]?: T };
export interface IEventEmitter<Events extends string> {
on(event: Events, fn: Callback): () => void;
on(event: Events, fn: Callback): () => any;
emit(event: Events, param: any): void;
}

View File

@@ -11,30 +11,31 @@ export class CHDBEngine extends EventEmitter<Events> implements OLAPEngine {
await this.exec(CLICKHOUSE_INIT_DB);
}
async exec(query: string) {
async exec(query: string, _emit = true) {
try {
const r: string = await invoke('query', { query });
if (!r) return;
const data = JSON.parse(r) as OLAPResponse;
this.emit('success', query, data);
let data: OLAPResponse | undefined;
if (r) data = JSON.parse(r) as OLAPResponse;
if (_emit) this.emit('success', query, data);
return data;
} catch (e) {
if (typeof e === 'string') e = new Error(e);
console.error(e);
this.emit('error', e);
if (_emit) this.emit('error', e);
}
}
async getSchema() {
const response = await this.exec(CLICKHOUSE_GET_SCHEMA);
const response = await this.exec(CLICKHOUSE_GET_SCHEMA, false);
if (!response) return [];
return response.data as Table[];
}
async getUDFs() {
const response = await this.exec(CLICKHOUSE_GET_UDFS);
const response = await this.exec(CLICKHOUSE_GET_UDFS, false);
if (!response) return [];
return response.data.map((row) => row.name as string);

View File

@@ -7,7 +7,7 @@ import CLICKHOUSE_GET_UDFS from './queries/clickhouse_get_udfs.sql?raw';
export class RemoteEngine extends EventEmitter<Events> implements OLAPEngine {
async init() {}
async exec(query: string) {
async exec(query: string, _emit = true) {
try {
const proxy =
new URLSearchParams(window.location.search).get('proxy') ?? 'https://proxy.agx.app/query';
@@ -22,23 +22,23 @@ export class RemoteEngine extends EventEmitter<Events> implements OLAPEngine {
if ('exception' in data) throw new Error(data.exception);
this.emit('success', query, data);
if (_emit) this.emit('success', query, data);
return data;
} catch (e) {
console.error(e);
this.emit('error', e);
if (_emit) this.emit('error', e);
}
}
async getSchema() {
const response = await this.exec(CLICKHOUSE_GET_SCHEMA);
const response = await this.exec(CLICKHOUSE_GET_SCHEMA, false);
if (!response) return [];
return response.data as Table[];
}
async getUDFs() {
const response = await this.exec(CLICKHOUSE_GET_UDFS);
const response = await this.exec(CLICKHOUSE_GET_UDFS, false);
if (!response) return [];
return response.data.map((row) => row.name as string);

View File

@@ -3,6 +3,9 @@
import { ContextMenuState } from '$lib/components/ContextMenu';
import ContextMenu from '$lib/components/ContextMenu/ContextMenu.svelte';
import Drawer from '$lib/components/Drawer.svelte';
import { functions, keywords, operators, types } from '$lib/components/Editor/clickhouse';
import Editor from '$lib/components/Editor/Editor.svelte';
import { setupLanguage } from '$lib/components/Editor/language';
import { SaveQueryModal } from '$lib/components/Queries';
import Result from '$lib/components/Result.svelte';
import SideBar from '$lib/components/SideBar.svelte';
@@ -23,13 +26,10 @@
import { historyRepository, type HistoryEntry } from '$lib/repositories/history';
import { queryRepository, type Query } from '$lib/repositories/queries';
import { tabRepository, type Tab } from '$lib/repositories/tabs';
import Editor from '$lib/components/Editor/Editor.svelte';
import { SplitPane } from '@rich_harris/svelte-split-pane';
import debounce from 'p-debounce';
import { format } from 'sql-formatter';
import { tick, type ComponentProps } from 'svelte';
import { setupLanguage } from '$lib/components/Editor/language';
import { keywords, functions, operators, types } from '$lib/components/Editor/clickhouse';
let response = $state.raw<OLAPResponse>();
let loading = $state(false);
@@ -37,24 +37,15 @@
async function handleExec() {
const query = currentTab.content;
if (loading || !query) {
return;
}
if (loading || !query) return;
loading = true;
counter?.start();
response = await engine.exec(query).finally(() => {
try {
response = await engine.exec(query);
} finally {
loading = false;
counter?.stop();
});
const last = await historyRepository.getLast();
if (response && last?.content !== query) await addHistoryEntry(query);
if (response) {
bottomPanel.open = true;
if (bottomPanelTab === 'logs') bottomPanelTab = 'data';
}
}
@@ -82,6 +73,23 @@
$effect(() => void historyRepository.getAll().then((entries) => (history = entries)));
$effect(() => void queryRepository.getAll().then((q) => (queries = q)));
engine.on('success', async (query: string) => {
if (typeof query !== 'string') return;
if (/(CREATE|DROP)/gi.test(query)) tables = await engine.getSchema();
});
engine.on('success', async (query: string, response?: OLAPResponse) => {
const last = await historyRepository.getLast();
if (response && last?.content !== query) await addHistoryEntry(query);
});
engine.on('success', (query: string, response?: OLAPResponse) => {
if (response) {
bottomPanel.open = true;
if (bottomPanelTab === 'logs') bottomPanelTab = 'data';
}
});
async function addHistoryEntry(query: string) {
try {
const entry = await historyRepository.add(query);