From 8cc7a35c1a3539d49807d1289cd11777e12ce4c8 Mon Sep 17 00:00:00 2001 From: luoianun Date: Tue, 23 Jun 2026 00:22:47 +0800 Subject: [PATCH] feat: add PrestoSQL connector --- apps/desktop/public/icons/database/trino.svg | 1 + .../components/config/DriverStoreDialog.vue | 49 ++++- .../connection/ConnectionDialog.vue | 96 +++++++- .../src/components/editor/QueryEditor.vue | 146 +++++++----- .../src/components/icons/DatabaseIcon.vue | 3 +- .../completionMetadataPolicy.spec.ts | 23 ++ .../lib/__tests__/completionTreeIndex.spec.ts | 59 +++++ .../__tests__/prestoSqlBuiltinDriver.spec.ts | 49 +++++ apps/desktop/src/lib/api.ts | 1 + .../src/lib/completionMetadataPolicy.ts | 11 + apps/desktop/src/lib/completionTreeIndex.ts | 52 +++++ .../src/lib/connectionAttemptTimeout.ts | 1 + .../desktop/src/lib/databaseCapabilitySets.ts | 2 + .../src/lib/databaseObjectCapabilities.ts | 1 + .../src/lib/databaseTableDataCapabilities.ts | 9 + apps/desktop/src/lib/http.ts | 4 + .../desktop/src/lib/prestoSqlBuiltinDriver.ts | 26 +++ apps/desktop/src/lib/tauri.ts | 4 + apps/desktop/src/stores/connectionStore.ts | 37 +++- apps/desktop/src/types/database.ts | 1 + .../assets/database-drivers.manifest.json | 31 ++- crates/dbx-core/src/agent_catalog.rs | 2 +- crates/dbx-core/src/agent_connection.rs | 41 +++- crates/dbx-core/src/agent_runtime.rs | 15 ++ crates/dbx-core/src/agent_service.rs | 11 +- crates/dbx-core/src/connection.rs | 135 ++++++++---- crates/dbx-core/src/jdbc.rs | 207 ++++++++++++++++++ crates/dbx-core/src/models/connection.rs | 6 + crates/dbx-core/src/plugins.rs | 2 +- crates/dbx-core/src/schema.rs | 167 +++++++++++++- .../dbx-core/src/sql_dialect/capabilities.rs | 1 + crates/dbx-web/src/main.rs | 1 + crates/dbx-web/src/routes/jdbc.rs | 14 +- packages/mcp-server/src/index.ts | 2 +- packages/node-core/src/diagnostics.ts | 1 + .../main/java/app/dbx/jdbc/DbxJdbcPlugin.java | 72 ++++++ .../java/app/dbx/jdbc/DbxJdbcPluginTest.java | 142 ++++++++++++ src-tauri/src/commands/connection.rs | 12 +- src-tauri/src/commands/plugins.rs | 8 +- src-tauri/src/lib.rs | 1 + 40 files changed, 1323 insertions(+), 123 deletions(-) create mode 100644 apps/desktop/public/icons/database/trino.svg create mode 100644 apps/desktop/src/lib/__tests__/completionMetadataPolicy.spec.ts create mode 100644 apps/desktop/src/lib/__tests__/completionTreeIndex.spec.ts create mode 100644 apps/desktop/src/lib/__tests__/prestoSqlBuiltinDriver.spec.ts create mode 100644 apps/desktop/src/lib/completionMetadataPolicy.ts create mode 100644 apps/desktop/src/lib/completionTreeIndex.ts create mode 100644 apps/desktop/src/lib/prestoSqlBuiltinDriver.ts diff --git a/apps/desktop/public/icons/database/trino.svg b/apps/desktop/public/icons/database/trino.svg new file mode 100644 index 0000000000..725aaacec7 --- /dev/null +++ b/apps/desktop/public/icons/database/trino.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/desktop/src/components/config/DriverStoreDialog.vue b/apps/desktop/src/components/config/DriverStoreDialog.vue index c35f79e350..5d77a37dd1 100644 --- a/apps/desktop/src/components/config/DriverStoreDialog.vue +++ b/apps/desktop/src/components/config/DriverStoreDialog.vue @@ -19,6 +19,7 @@ import * as api from "@/lib/api"; import type { AgentDriverInfo, DriverRuntimeInfo, DriverRuntimeSummary, DriverStoreUsage, JavaRuntimeConfig } from "@/lib/api"; import { formatRuntimeBytes, formatRuntimeCpu, formatRuntimeUptime, runtimeHealthClass, runtimeStatusClass, runtimeStatusDotClass } from "@/lib/driverRuntimePresentation"; import { addDriverInstallQueue, driverInstallProgressPercent, isDriverInstallProgressTarget, removeDriverInstallQueue, takeNextDriverInstallQueue, type DriverInstallProgress } from "@/lib/driverInstallProgressUi"; +import { PRESTOSQL_DRIVER_DB_TYPE, prestoSqlBuiltinDriverRow, prestoSqlMavenBundle } from "@/lib/prestoSqlBuiltinDriver"; const { t } = useI18n(); const { toast } = useToast(); @@ -261,12 +262,22 @@ function progressTitle(fallback: string): string { return progressText.value || fallback; } +function isPrestoSqlBuiltinDriver(dbType: string): boolean { + return dbType === PRESTOSQL_DRIVER_DB_TYPE; +} + +const builtinDriverRows = computed(() => [...drivers.value, prestoSqlBuiltinDriverRow(jdbcMavenBundles.value)]); + +function driverLabel(dbType: string): string { + return builtinDriverRows.value.find((d) => d.db_type === dbType)?.label ?? dbType; +} + function isDriverQueued(dbType: string): boolean { return queuedDriverInstalls.value.includes(dbType); } function canInstallOrUpdateDriver(dbType: string): boolean { - const driver = drivers.value.find((d) => d.db_type === dbType); + const driver = builtinDriverRows.value.find((d) => d.db_type === dbType); return Boolean(driver && (!driver.installed || driver.update_available)); } @@ -353,10 +364,21 @@ async function installDriver(dbType: string) { } async function runDriverInstall(dbType: string) { - const label = drivers.value.find((d) => d.db_type === dbType)?.label ?? dbType; + const label = driverLabel(dbType); installing.value = dbType; resetInstallProgress(); try { + if (isPrestoSqlBuiltinDriver(dbType)) { + if (!jdbcPluginStatus.value?.installed || !jdbcPluginStatus.value.compatible) { + jdbcPluginStatus.value = await api.installJdbcPlugin(); + emitDriverUpdateCount(); + } + jdbcDrivers.value = await api.installPrestoSqlJdbcDriver(); + jdbcMavenBundles.value = await api.listJdbcMavenBundles(); + void loadDriverStoreUsage(); + toast(t("driverStore.driverInstallSuccess", { label })); + return; + } const blockers = await api.checkAgentUpdateBlockers([dbType]); if (blockers.length > 0) { toast(t("driverStore.driverUpdateBlocked", { labels: blockers.map((blocker) => blocker.label).join(", ") })); @@ -415,8 +437,17 @@ async function upgradeAll() { } async function uninstallDriver(dbType: string) { - const label = drivers.value.find((d) => d.db_type === dbType)?.label ?? dbType; + const label = driverLabel(dbType); try { + if (isPrestoSqlBuiltinDriver(dbType)) { + const bundle = prestoSqlMavenBundle(jdbcMavenBundles.value); + if (!bundle) return; + jdbcDrivers.value = await api.deleteJdbcMavenBundle(bundle.id); + jdbcMavenBundles.value = await api.listJdbcMavenBundles(); + void loadDriverStoreUsage(); + toast(t("driverStore.driverUninstallSuccess", { label })); + return; + } await api.uninstallAgent(dbType); await refreshAgents(); toast(t("driverStore.driverUninstallSuccess", { label })); @@ -495,7 +526,11 @@ async function importOfflineZip() { } async function importDriverJar(dbType: string) { - const label = drivers.value.find((d) => d.db_type === dbType)?.label ?? dbType; + if (isPrestoSqlBuiltinDriver(dbType)) { + await importJdbcDrivers(); + return; + } + const label = driverLabel(dbType); if (isWeb) { const file = await chooseWebFile(".jar"); if (!file) return; @@ -600,8 +635,8 @@ type JdbcDriverListItem = const filteredAgentDrivers = computed(() => { const query = agentDriverSearch.value.trim().toLowerCase(); - if (!query) return drivers.value; - return drivers.value.filter((driver) => [driver.label, driver.db_type, driver.version, driver.installed_version, driver.jre].filter(Boolean).join(" ").toLowerCase().includes(query)); + if (!query) return builtinDriverRows.value; + return builtinDriverRows.value.filter((driver) => [driver.label, driver.db_type, driver.version, driver.installed_version, driver.jre].filter(Boolean).join(" ").toLowerCase().includes(query)); }); const jdbcDriverListItems = computed(() => { @@ -1102,7 +1137,7 @@ watch(driverStoreTab, (tab) => { {{ t("driverStore.install") }}