From 2b4cd311b356f153b02cbac8268c47ae4cfd8d5e Mon Sep 17 00:00:00 2001 From: skyler <77960507+t8y2@users.noreply.github.com> Date: Thu, 30 Apr 2026 17:23:50 +0800 Subject: [PATCH] feat(mongodb): support direct URL connection string (#32) * chore: bump version to 0.2.1 * fix(ci): wait for Release workflow before publishing packages Changed trigger from release:published to workflow_run on Release completion, so assets are already uploaded when download starts. * feat(mongodb): support direct URL connection string Allow pasting a full MongoDB URI (e.g. mongodb+srv://) to connect to Atlas clusters, replica sets, and other multi-instance setups. --- src-tauri/src/models/connection.rs | 13 ++++- .../connection/ConnectionDialog.vue | 47 ++++++++++++++++++- src/i18n/locales/zh-CN.ts | 2 + src/types/database.ts | 1 + 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src-tauri/src/models/connection.rs b/src-tauri/src/models/connection.rs index 0752af9dc..f45a613fd 100644 --- a/src-tauri/src/models/connection.rs +++ b/src-tauri/src/models/connection.rs @@ -33,6 +33,8 @@ pub struct ConnectionConfig { pub ssh_key_path: String, #[serde(default)] pub ssl: bool, + #[serde(default)] + pub connection_string: Option, } fn default_ssh_port() -> u16 { @@ -98,7 +100,12 @@ impl ConnectionConfig { "server=tcp:{host},{port};database={}", self.database.as_deref().unwrap_or("master") ), - DatabaseType::MongoDb => format!("mongodb://{host}:{port}{db_part}"), + DatabaseType::MongoDb => { + if let Some(cs) = self.connection_string.as_deref().filter(|s| !s.is_empty()) { + return cs.to_string(); + } + format!("mongodb://{host}:{port}{db_part}") + } DatabaseType::Oracle => format!("oracle://{host}:{port}{db_part}"), } } @@ -151,6 +158,9 @@ impl ConnectionConfig { self.database.as_deref().unwrap_or("master") ), DatabaseType::MongoDb => { + if let Some(cs) = self.connection_string.as_deref().filter(|s| !s.is_empty()) { + return cs.to_string(); + } if self.username.is_empty() { format!("mongodb://{host}:{port}{db_part}") } else { @@ -210,6 +220,7 @@ mod tests { ssh_password: String::new(), ssh_key_path: String::new(), ssl: false, + connection_string: None, } } diff --git a/src/components/connection/ConnectionDialog.vue b/src/components/connection/ConnectionDialog.vue index 5d18903fd..a74dd6cd6 100644 --- a/src/components/connection/ConnectionDialog.vue +++ b/src/components/connection/ConnectionDialog.vue @@ -54,11 +54,13 @@ const defaultForm = (): Omit => ({ ssh_password: "", ssh_key_path: "", ssl: false, + connection_string: undefined, }); const form = ref(defaultForm()); const selectedType = ref("mysql"); const customDriverName = ref(""); +const mongoUseUrl = ref(false); const colorOptions = [ { value: "", class: "bg-transparent border-dashed", labelKey: "connection.colorNone" }, @@ -146,8 +148,10 @@ watch(() => props.editConfig, (config) => { ssh_password: config.ssh_password || "", ssh_key_path: config.ssh_key_path || "", ssl: config.ssl || false, + connection_string: config.connection_string, }; selectedType.value = profile; + mongoUseUrl.value = !!config.connection_string; customDriverName.value = isCustomCompatibleProfile() ? (config.driver_label || "") : ""; } else { editingId.value = null; @@ -227,6 +231,7 @@ function resetForm() { editingId.value = null; form.value = defaultForm(); selectedType.value = "mysql"; + mongoUseUrl.value = false; testResult.value = null; } @@ -377,6 +382,46 @@ watch([() => editingId.value, () => open.value], () => { + +