diff --git a/src/lib/ch-engine/index.ts b/src/lib/ch-engine/index.ts deleted file mode 100644 index f04deda..0000000 --- a/src/lib/ch-engine/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { exec } from './query'; - -export async function init() { - await exec(` - CREATE DATABASE IF NOT EXISTS agx; - USE agx; - `); -} - -export { Sources } from './sources.svelte'; -export type * from './types'; -export { exec }; diff --git a/src/lib/ch-engine/query.ts b/src/lib/ch-engine/query.ts deleted file mode 100644 index b68a189..0000000 --- a/src/lib/ch-engine/query.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { invoke } from '@tauri-apps/api/core'; -import type { CHResponse } from './types'; - -export async function exec(query: string) { - try { - const r: string = await invoke('query', { query }); - if (!r) return; - - return JSON.parse(r) as CHResponse; - } catch (e) { - console.error(e); - } -} diff --git a/src/lib/ch-engine/sources.svelte.ts b/src/lib/ch-engine/sources.svelte.ts deleted file mode 100644 index b3cc681..0000000 --- a/src/lib/ch-engine/sources.svelte.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { exec } from './query'; -import type { Source } from './types'; - -const LIST_SOURCES_QUERY = `select - t.name as name, - t.engine as engine, - groupArray(map( - 'name', c.name, - 'type', c.type - )) as columns -from system.tables as t -inner join system.columns as c on t.name = c.table -where database = 'agx' -group by t.name, t.engine -`; - -export class Sources { - #tables = $state.raw([]); - - constructor() { - this.fetch(); - } - - public get tables() { - return this.#tables; - } - - async fetch() { - const response = await exec(LIST_SOURCES_QUERY); - if (response) this.#tables = response.data as Source[]; - } -} diff --git a/src/lib/ch-engine/types.d.ts b/src/lib/ch-engine/types.d.ts deleted file mode 100644 index d21a1c1..0000000 --- a/src/lib/ch-engine/types.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type CHResponse = { - meta: Array; - data: Array<{ [key: string]: any }>; -}; - -export interface ColumnDescriptor { - name: string; - type: string; -} - -export interface Source { - name: string; - engine: string; - columns: ColumnDescriptor[]; -} diff --git a/src/lib/components/Datasets/Datasets.svelte b/src/lib/components/Datasets/Datasets.svelte index a1aa87f..7510cac 100644 --- a/src/lib/components/Datasets/Datasets.svelte +++ b/src/lib/components/Datasets/Datasets.svelte @@ -1,8 +1,9 @@ @@ -23,9 +28,7 @@ @@ -36,7 +39,7 @@ {#if source.engine === 'MergeTree'} {:else} - + {/if}

{source.name}

diff --git a/src/lib/components/Datasets/utils.ts b/src/lib/components/Datasets/utils.ts index 0e788a1..58dfc86 100644 --- a/src/lib/components/Datasets/utils.ts +++ b/src/lib/components/Datasets/utils.ts @@ -1,6 +1,6 @@ -import { type Source } from '$lib/ch-engine'; +import { type Table } from '$lib/olap-engine'; -export function filter(sources: Source[], search: string) { +export function filter(sources: Table[], search: string) { if (!search) return sources; const search_ = search.toLowerCase(); diff --git a/src/lib/components/Editor/Editor.svelte b/src/lib/components/Editor/Editor.svelte index ae13e8f..1dcdda5 100644 --- a/src/lib/components/Editor/Editor.svelte +++ b/src/lib/components/Editor/Editor.svelte @@ -1,5 +1,5 @@
@@ -16,7 +23,7 @@ {#if tab === 'sources'} - + {/if}
diff --git a/src/lib/olap-engine/engine-chdb.ts b/src/lib/olap-engine/engine-chdb.ts new file mode 100644 index 0000000..556ee4b --- /dev/null +++ b/src/lib/olap-engine/engine-chdb.ts @@ -0,0 +1,29 @@ +import { invoke } from '@tauri-apps/api/core'; +import type { OLAPEngine, Table, OLAPResponse } from './index'; + +import CLICKHOUSE_GET_SCHEMA from './queries/clickhouse_get_schema.sql?raw'; +import CLICKHOUSE_INIT_DB from './queries/clickhouse_init_db.sql?raw'; + +export class CHDBEngine implements OLAPEngine { + async init() { + await this.exec(CLICKHOUSE_INIT_DB); + } + + async exec(query: string) { + try { + const r: string = await invoke('query', { query }); + if (!r) return; + + return JSON.parse(r) as OLAPResponse; + } catch (e) { + console.error(e); + return undefined; + } + } + + async getSchema() { + const response = await this.exec(CLICKHOUSE_GET_SCHEMA); + if (!response) return []; + return response.data as Table[]; + } +} diff --git a/src/lib/olap-engine/engine-remote.ts b/src/lib/olap-engine/engine-remote.ts new file mode 100644 index 0000000..27fbf5a --- /dev/null +++ b/src/lib/olap-engine/engine-remote.ts @@ -0,0 +1,32 @@ +import type { OLAPEngine, Table, OLAPResponse } from './index'; + +import CLICKHOUSE_GET_SCHEMA from './queries/clickhouse_get_schema.sql?raw'; + +export class RemoteEngine implements OLAPEngine { + async init() {} + + async exec(query: string) { + try { + const response = await fetch('https://proxy.agx.app/query', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: query + }); + const r = await response.text(); + if (!r) return; + + return JSON.parse(r) as OLAPResponse; + } catch (e) { + console.error(e); + return undefined; + } + } + + async getSchema() { + const response = await this.exec(CLICKHOUSE_GET_SCHEMA); + if (!response) return []; + return response.data as Table[]; + } +} diff --git a/src/lib/olap-engine/index.ts b/src/lib/olap-engine/index.ts new file mode 100644 index 0000000..d6fef43 --- /dev/null +++ b/src/lib/olap-engine/index.ts @@ -0,0 +1,26 @@ +import { CHDBEngine } from './engine-chdb'; +import { RemoteEngine } from './engine-remote'; + +export type OLAPResponse = { + meta: Array; + data: Array<{ [key: string]: any }>; +}; + +export interface ColumnDescriptor { + name: string; + type: string; +} + +export interface Table { + name: string; + engine: string; + columns: ColumnDescriptor[]; +} + +export interface OLAPEngine { + init(): Promise; + exec(query: string): Promise; + getSchema(): Promise; +} + +export const engine = new RemoteEngine() as OLAPEngine; diff --git a/src/lib/olap-engine/queries/clickhouse_get_schema.sql b/src/lib/olap-engine/queries/clickhouse_get_schema.sql new file mode 100644 index 0000000..60d4e6a --- /dev/null +++ b/src/lib/olap-engine/queries/clickhouse_get_schema.sql @@ -0,0 +1,11 @@ +SELECT + t.name AS name, + t.engine AS engine, + groupArray(map( + 'name', c.name, + 'type', c.type + )) AS columns +FROM system.tables AS t +INNER JOIN system.columns AS c ON t.name = c.table +WHERE database = currentDatabase() +GROUP BY t.name, t.engine diff --git a/src/lib/olap-engine/queries/clickhouse_init_db.sql b/src/lib/olap-engine/queries/clickhouse_init_db.sql new file mode 100644 index 0000000..40d8ca5 --- /dev/null +++ b/src/lib/olap-engine/queries/clickhouse_init_db.sql @@ -0,0 +1,2 @@ +CREATE DATABASE IF NOT EXISTS agx; +USE agx; diff --git a/src/lib/types.d.ts b/src/lib/types.d.ts index 241475a..f1ac9a5 100644 --- a/src/lib/types.d.ts +++ b/src/lib/types.d.ts @@ -1,7 +1,5 @@ -import type { Sources } from './ch-engine'; - type MaybePromise = T | Promise; export type AppContext = { - sources: Sources; + tables: Table[]; }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 023796d..378f877 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,14 +1,15 @@ @@ -35,16 +40,12 @@
{#snippet a()} - + {/snippet} {#snippet b()} {#snippet a()} - + {/snippet} {#snippet b()} diff --git a/src/routes/+page.ts b/src/routes/+page.ts index 87c29a8..cdaa54a 100644 --- a/src/routes/+page.ts +++ b/src/routes/+page.ts @@ -1,8 +1,8 @@ -import { init } from '$lib/ch-engine'; +import { engine } from '$lib/olap-engine'; import type { PageLoad } from './$types'; export const load = (async () => { - await init(); + await engine.init(); return {}; }) satisfies PageLoad;