fix(mongo): complete agent fallback for all connection paths
- Fix connect_db and test_connection to also fallback to agent when native driver fails with wire version error - Route MongoDB agent through mongo_ops in schema.rs list_databases - Update MongoDB legacy hint text to mention Driver Manager
This commit is contained in:
parent
1e8ce6673f
commit
7faa9ec818
|
|
@ -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<Vec<db::TableInfo>, 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;
|
||||
|
|
|
|||
|
|
@ -81,12 +81,29 @@ pub async fn test_connection(state: State<'_, Arc<AppState>>, 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::<serde_json::Value>("connect", params).await?;
|
||||
client.call::<serde_json::Value>("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<AppState>>, 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::<serde_json::Value>("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()) };
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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: "颜色",
|
||||
|
|
|
|||
Loading…
Reference in New Issue