diff --git a/src/components/sidebar/TreeItem.vue b/src/components/sidebar/TreeItem.vue index 974433deb2..e66a656bf3 100644 --- a/src/components/sidebar/TreeItem.vue +++ b/src/components/sidebar/TreeItem.vue @@ -152,34 +152,42 @@ function onClick() { async function openData() { const node = props.node; if (!(node.type === "table" || node.type === "view") || !node.connectionId || !node.database) return; - await connectionStore.ensureConnected(node.connectionId); const config = connectionStore.getConfig(node.connectionId); - const qualifiedName = (config?.db_type === "postgres" || config?.db_type === "oracle" || config?.db_type === "sqlserver") && node.schema - ? `${quoteIdent(node.schema)}.${quoteIdent(node.label)}` - : quoteIdent(node.label); const tabId = queryStore.createTab(node.connectionId, node.database, node.label, "data"); + queryStore.setExecuting(tabId, true); - const querySchema = node.schema || node.database; - const columns = await api.getColumns(node.connectionId, node.database, querySchema, node.label); - const pks = columns.filter((c) => c.is_primary_key).map((c) => c.name); - const order = pks.length ? ` ORDER BY ${pks.map((pk) => `${quoteIdent(pk)} ASC`).join(", ")}` : ""; - let sql: string; - if (config?.db_type === "oracle") { - sql = `SELECT * FROM ${qualifiedName}${order} FETCH FIRST 100 ROWS ONLY`; - } else if (config?.db_type === "sqlserver") { - sql = `SELECT TOP 100 * FROM ${qualifiedName}${order}`; - } else { - sql = `SELECT * FROM ${qualifiedName}${order} LIMIT 100;`; + try { + await connectionStore.ensureConnected(node.connectionId); + if (!config) throw new Error("Connection config not found"); + + const qualifiedName = (config.db_type === "postgres" || config.db_type === "oracle" || config.db_type === "sqlserver") && node.schema + ? `${quoteIdent(node.schema)}.${quoteIdent(node.label)}` + : quoteIdent(node.label); + + const querySchema = node.schema || node.database; + const columns = await api.getColumns(node.connectionId, node.database, querySchema, node.label); + const pks = columns.filter((c) => c.is_primary_key).map((c) => c.name); + const order = pks.length ? ` ORDER BY ${pks.map((pk) => `${quoteIdent(pk)} ASC`).join(", ")}` : ""; + let sql: string; + if (config.db_type === "oracle") { + sql = `SELECT * FROM ${qualifiedName}${order} FETCH FIRST 100 ROWS ONLY`; + } else if (config.db_type === "sqlserver") { + sql = `SELECT TOP 100 * FROM ${qualifiedName}${order}`; + } else { + sql = `SELECT * FROM ${qualifiedName}${order} LIMIT 100;`; + } + queryStore.updateSql(tabId, sql); + queryStore.setTableMeta(tabId, { + schema: node.schema, + tableName: node.label, + columns, + primaryKeys: pks, + }); + + await queryStore.executeTabSql(tabId, sql); + } catch (e: any) { + queryStore.setErrorResult(tabId, e); } - queryStore.updateSql(tabId, sql); - queryStore.setTableMeta(tabId, { - schema: node.schema, - tableName: node.label, - columns, - primaryKeys: pks, - }); - - queryStore.executeCurrentTab(); } async function newQuery() { diff --git a/src/stores/queryStore.ts b/src/stores/queryStore.ts index 5109506fd0..c0e42f68c5 100644 --- a/src/stores/queryStore.ts +++ b/src/stores/queryStore.ts @@ -95,6 +95,27 @@ export const useQueryStore = defineStore("query", () => { if (tab) tab.tableMeta = meta; } + function setExecuting(id: string, isExecuting: boolean) { + const tab = tabs.value.find((t) => t.id === id); + if (tab) tab.isExecuting = isExecuting; + } + + function toErrorResult(e: any): NonNullable { + return { + columns: ["Error"], + rows: [[String(e)]], + affected_rows: 0, + execution_time_ms: 0, + }; + } + + function setErrorResult(id: string, e: any) { + const tab = tabs.value.find((t) => t.id === id); + if (!tab) return; + tab.result = toErrorResult(e); + tab.isExecuting = false; + } + async function executeCurrentTab() { const tab = tabs.value.find((t) => t.id === activeTabId.value); if (!tab || !tab.sql.trim()) return; @@ -103,7 +124,12 @@ export const useQueryStore = defineStore("query", () => { } async function executeCurrentSql(sql: string) { - const tab = tabs.value.find((t) => t.id === activeTabId.value); + if (!activeTabId.value) return; + await executeTabSql(activeTabId.value, sql); + } + + async function executeTabSql(id: string, sql: string) { + const tab = tabs.value.find((t) => t.id === id); if (!tab || !sql.trim()) return; tab.isExecuting = true; @@ -111,12 +137,7 @@ export const useQueryStore = defineStore("query", () => { try { tab.result = await api.executeQuery(tab.connectionId, tab.database, sql); } catch (e: any) { - tab.result = { - columns: ["Error"], - rows: [[String(e)]], - affected_rows: 0, - execution_time_ms: 0, - }; + tab.result = toErrorResult(e); } finally { tab.isExecuting = false; } @@ -143,7 +164,10 @@ export const useQueryStore = defineStore("query", () => { updateDatabase, updateConnection, setTableMeta, + setExecuting, + setErrorResult, executeCurrentTab, executeCurrentSql, + executeTabSql, }; });