diff --git a/crates/dbx-core/src/schema.rs b/crates/dbx-core/src/schema.rs index ce6657630..eae0bb2f8 100644 --- a/crates/dbx-core/src/schema.rs +++ b/crates/dbx-core/src/schema.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use crate::connection::{AppState, MysqlMode, PoolKind}; use crate::db; +use crate::models::connection::DatabaseType; pub fn duckdb_query_tables(con: &duckdb::Connection) -> Result, String> { let mut stmt = con.prepare( @@ -136,6 +137,13 @@ pub async fn list_databases_core(state: &AppState, connection_id: &str) -> Resul return db::sqlserver::list_databases(&mut client).await; } if let Some(client) = extract_agent(&connections, connection_id) { + let is_mongo = + state.configs.read().await.get(connection_id).is_some_and(|c| c.db_type == DatabaseType::MongoDb); + if is_mongo { + drop(connections); + let dbs = crate::mongo_ops::mongo_list_databases_core(state, connection_id).await?; + return Ok(dbs.into_iter().map(|name| db::DatabaseInfo { name }).collect()); + } drop(connections); let mut client = client.lock().await; return client.call("list_databases", serde_json::json!({})).await; diff --git a/src-tauri/src/commands/connection.rs b/src-tauri/src/commands/connection.rs index 8f8bfb005..66e77cf8c 100644 --- a/src-tauri/src/commands/connection.rs +++ b/src-tauri/src/commands/connection.rs @@ -81,12 +81,29 @@ pub async fn test_connection(state: State<'_, Arc>, config: Connection DatabaseType::DuckDb => duckdb::Connection::open(&expand_tilde(&config.host)) .map(|_| "Connection successful".to_string()) .map_err(|e| e.to_string()), - DatabaseType::MongoDb => match db::mongo_driver::connect(&url).await { - Ok(client) => { - db::mongo_driver::test_connection(&client).await.map(|_| "Connection successful".to_string()) + DatabaseType::MongoDb => { + let native_err = match db::mongo_driver::connect(&url).await { + Ok(client) => match db::mongo_driver::test_connection(&client).await { + Ok(()) => return Ok("Connection successful".to_string()), + Err(e) => e, + }, + Err(e) => e, + }; + if native_err.contains("wire version") { + let am = &state.agent_manager; + let mut client = am.spawn(&config.db_type, config.driver_profile.as_deref()).await?; + let params = serde_json::json!({ "connection": { + "host": host, "port": port, + "database": config.effective_database().unwrap_or(""), + "username": config.username, "password": config.password, + }}); + client.call::("connect", params).await?; + client.call::("disconnect", serde_json::json!({})).await.ok(); + Ok("Connection successful (via legacy driver)".to_string()) + } else { + Err(native_err) } - Err(e) => Err(e.to_string()), - }, + } DatabaseType::ClickHouse => { let username = if config.username.is_empty() { None } else { Some(config.username.clone()) }; let password = if config.password.is_empty() { None } else { Some(config.password.clone()) }; @@ -170,9 +187,31 @@ pub async fn connect_db(state: State<'_, Arc>, config: ConnectionConfi PoolKind::DuckDb(std::sync::Arc::new(std::sync::Mutex::new(con))) } DatabaseType::MongoDb => { - let client = db::mongo_driver::connect(&url).await?; - db::mongo_driver::test_connection(&client).await?; - PoolKind::MongoDb(client) + let native_err = match db::mongo_driver::connect(&url).await { + Ok(client) => match db::mongo_driver::test_connection(&client).await { + Ok(()) => { + state.configs.write().await.insert(id.clone(), config); + state.connections.write().await.insert(id.clone(), PoolKind::MongoDb(client)); + return Ok(id); + } + Err(e) => e, + }, + Err(e) => e, + }; + if native_err.contains("wire version") { + log::info!("Native MongoDB driver failed ({native_err}), falling back to agent driver"); + let mut client = + state.agent_manager.spawn(&db_config.db_type, db_config.driver_profile.as_deref()).await?; + let params = serde_json::json!({ "connection": { + "host": host, "port": port, + "database": db_config.effective_database().unwrap_or(""), + "username": db_config.username, "password": db_config.password, + }}); + client.call::("connect", params).await?; + PoolKind::Agent(std::sync::Arc::new(tokio::sync::Mutex::new(client))) + } else { + return Err(native_err); + } } DatabaseType::ClickHouse => { let username = if db_config.username.is_empty() { None } else { Some(db_config.username.clone()) }; diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index e863cac08..7889a505b 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -179,7 +179,7 @@ export default { dmCompatHint: "Requires DM8 ODBC driver installed on your system.", dmDownload: "Download from Dameng", mongoLegacyHint: - "For older MongoDB servers, enter authSource=admin&authMechanism=SCRAM-SHA-1 here; add directConnection=true only when needed for direct standalone connections.", + "MongoDB below 4.2 requires the MongoDB (Legacy) driver from Driver Manager; connections will switch automatically.", compatible: "Compatible", mainstream: "Popular", color: "Color", diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts index 935d8f626..df5ec2620 100644 --- a/src/i18n/locales/es.ts +++ b/src/i18n/locales/es.ts @@ -180,7 +180,7 @@ export default { dmCompatHint: "Requiere el driver ODBC DM8 instalado en el sistema.", dmDownload: "Descargar desde Dameng", mongoLegacyHint: - "Para servidores MongoDB más antiguos, ingresa authSource=admin&authMechanism=SCRAM-SHA-1 aquí; agrega directConnection=true solo cuando sea necesario para conexiones directas a instancias independientes.", + "MongoDB inferior a 4.2 requiere el controlador MongoDB (Legacy) del Gestor de controladores; la conexión cambiará automáticamente.", compatible: "Compatible", mainstream: "Popular", color: "Color", diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 9c56a0877..1370edadb 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -176,8 +176,7 @@ export default { jdbcPluginHint: "先安装 DBX JDBC 插件,再导入数据库厂商提供的 JDBC 驱动 JAR。", dmCompatHint: "需要在系统上安装达梦 DM8 ODBC 驱动程序。", dmDownload: "前往达梦官网下载", - mongoLegacyHint: - "连接旧版 MongoDB 时,可在此填写 authSource=admin&authMechanism=SCRAM-SHA-1;直连单节点时可按需追加 directConnection=true。", + mongoLegacyHint: "MongoDB 4.2 以下版本需在驱动管理中安装 MongoDB (Legacy) 驱动,连接时将自动切换。", compatible: "兼容", mainstream: "主流", color: "颜色",