diff --git a/src/App.vue b/src/App.vue index 33680acb2..a5599703f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -50,6 +50,7 @@ import { getVersion } from "@tauri-apps/api/app"; import * as api from "@/lib/tauri"; import { canCancelQueryExecution, queryExecutionLabelKey } from "@/lib/queryExecutionState"; import { resolveExecutableSql } from "@/lib/sqlExecutionTarget"; +import { buildTableSelectSql, quoteTableIdentifier } from "@/lib/tableSelectSql"; import type { SqlFormatDialect } from "@/lib/sqlFormatter"; import { isCloseTabShortcut, isExecuteSqlShortcut } from "@/lib/keyboardShortcuts"; @@ -305,6 +306,14 @@ function tabDisplayTitle(tab: typeof queryStore.tabs[number]): string { return tab.title; } +function tabModeLabel(tab: typeof queryStore.tabs[number]): string { + if (tab.mode === "data") return t("tabs.table"); + if (tab.mode === "query") return t("tabs.sql"); + if (tab.mode === "mongo") return t("tabs.mongo"); + if (tab.mode === "redis") return t("tabs.redis"); + return tab.mode; +} + function databaseDisplayNameForTab(connectionId: string, database: string): string { const connection = connectionStore.getConfig(connectionId); if (connection?.db_type === "redis" && database !== "") return `db${database}`; @@ -470,7 +479,8 @@ async function changeActiveConnection(connectionId: any) { async function onExecuteSql(sql: string) { const tab = activeTab.value; if (!tab) return; - await api.executeQuery(tab.connectionId, tab.database, sql); + queryStore.updateSql(tab.id, sql); + await queryStore.executeTabSql(tab.id, sql); } async function onReloadData() { @@ -486,61 +496,36 @@ type ActiveTab = NonNullable; function quoteIdent(tab: ActiveTab, name: string): string { const config = connectionStore.getConfig(tab.connectionId); - return config?.db_type === "mysql" - ? `\`${name.replace(/`/g, "``")}\`` - : `"${name.replace(/"/g, '""')}"`; -} - -function qualifiedTableName(tab: NonNullable): string { - const config = connectionStore.getConfig(tab.connectionId); - if (!tab.tableMeta) return ""; - if ((config?.db_type === "postgres" || config?.db_type === "oracle" || config?.db_type === "sqlserver") && tab.tableMeta.schema) { - return `${quoteIdent(tab, tab.tableMeta.schema)}.${quoteIdent(tab, tab.tableMeta.tableName)}`; - } - return quoteIdent(tab, tab.tableMeta.tableName); -} - -function defaultOrderBy(tab: NonNullable): string | undefined { - const primaryKeys = tab.tableMeta?.primaryKeys ?? []; - if (primaryKeys.length === 0) return undefined; - return primaryKeys.map((pk) => `${quoteIdent(tab, pk)} ASC`).join(", "); + return quoteTableIdentifier(config?.db_type, name); } function buildTableSql( tab: NonNullable, - options: { orderBy?: string; limit?: number; offset?: number } = {}, + options: { orderBy?: string; limit?: number; offset?: number; whereInput?: string } = {}, ): string { const config = connectionStore.getConfig(tab.connectionId); - const limit = options.limit ?? 100; - const orderBy = options.orderBy ?? defaultOrderBy(tab); - const order = orderBy ? ` ORDER BY ${orderBy}` : ""; - - if (config?.db_type === "oracle") { - const offset = options.offset ? ` OFFSET ${options.offset} ROWS` : ""; - return `SELECT * FROM ${qualifiedTableName(tab)}${order}${offset} FETCH FIRST ${limit} ROWS ONLY`; - } - - if (config?.db_type === "sqlserver") { - return `SELECT TOP ${limit} * FROM ${qualifiedTableName(tab)}${order}`; - } - - const offset = options.offset ? ` OFFSET ${options.offset}` : ""; - return `SELECT * FROM ${qualifiedTableName(tab)}${order} LIMIT ${limit}${offset};`; + return buildTableSelectSql({ + databaseType: config?.db_type, + schema: tab.tableMeta?.schema, + tableName: tab.tableMeta?.tableName ?? "", + primaryKeys: tab.tableMeta?.primaryKeys, + ...options, + }); } -async function onPaginate(offset: number, limit: number) { +async function onPaginate(offset: number, limit: number, whereInput?: string) { const tab = activeTab.value; if (!tab?.tableMeta) return; - const sql = buildTableSql(tab, { limit, offset }); + const sql = buildTableSql(tab, { limit, offset, whereInput }); queryStore.updateSql(tab.id, sql); await queryStore.executeCurrentTab(); } -async function onSort(column: string, direction: "asc" | "desc" | null) { +async function onSort(column: string, direction: "asc" | "desc" | null, whereInput?: string) { const tab = activeTab.value; if (!tab?.tableMeta) return; - const orderBy = direction ? `${quoteIdent(tab, column)} ${direction.toUpperCase()}` : defaultOrderBy(tab); - const sql = buildTableSql(tab, { orderBy }); + const orderBy = direction ? `${quoteIdent(tab, column)} ${direction.toUpperCase()}` : undefined; + const sql = buildTableSql(tab, { orderBy, whereInput }); queryStore.updateSql(tab.id, sql); await queryStore.executeCurrentTab(); } @@ -852,7 +837,18 @@ async function setupFileDrop() { @click="queryStore.activeTabId = tab.id" > + {{ tabDisplayTitle(tab) }} + + {{ tabModeLabel(tab) }} +