diff --git a/crates/dbx-core/src/connection.rs b/crates/dbx-core/src/connection.rs index 5400b8b101..daceb00d53 100644 --- a/crates/dbx-core/src/connection.rs +++ b/crates/dbx-core/src/connection.rs @@ -171,20 +171,27 @@ impl AppState { let con = db::duckdb_driver::connect_path(&expand_tilde(&db_config.host))?; PoolKind::DuckDb(con) } - DatabaseType::MongoDb => match db::mongo_driver::connect(&url).await { - Ok(client) => { - db::mongo_driver::test_connection(&client).await?; - PoolKind::MongoDb(client) - } - Err(e) if e.contains("wire version") => { - log::info!("Native MongoDB driver failed ({e}), falling back to agent driver"); + DatabaseType::MongoDb => { + let native_err = match db::mongo_driver::connect(&url).await { + Ok(client) => match db::mongo_driver::test_connection(&client).await { + Ok(()) => { + self.connections.write().await.insert(pool_key.clone(), PoolKind::MongoDb(client)); + return Ok(pool_key); + } + 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 connect_params = serde_json::json!({ "connection": agent_connect_params(&db_config, &host, port, db_config.effective_database().unwrap_or("")) }); let mut client = self.agent_manager.spawn(&DatabaseType::MongoDb, None).await?; client.call::("connect", connect_params).await?; PoolKind::Agent(Arc::new(tokio::sync::Mutex::new(client))) + } else { + return Err(native_err); } - Err(e) => return Err(e), - }, + } DatabaseType::ClickHouse => { let username = if db_config.username.is_empty() { None } else { Some(db_config.username.clone()) }; let password = if db_config.password.is_empty() { None } else { Some(db_config.password.clone()) }; diff --git a/crates/dbx-core/src/db/postgres.rs b/crates/dbx-core/src/db/postgres.rs index 0a68a21016..8cbc643c29 100644 --- a/crates/dbx-core/src/db/postgres.rs +++ b/crates/dbx-core/src/db/postgres.rs @@ -201,11 +201,15 @@ pub async fn list_databases(pool: &PgPool) -> Result, String> pub async fn list_tables(pool: &PgPool, schema: &str) -> Result, String> { let rows: Vec = sqlx::query( - "SELECT t.table_name, t.table_type, obj_description(c.oid) AS table_comment \ - FROM information_schema.tables t \ - LEFT JOIN pg_catalog.pg_class c ON c.relname = t.table_name \ - LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND n.nspname = t.table_schema \ - WHERE t.table_schema = $1 ORDER BY t.table_name", + "SELECT c.relname AS table_name, \ + CASE c.relkind WHEN 'r' THEN 'BASE TABLE' WHEN 'v' THEN 'VIEW' \ + WHEN 'm' THEN 'MATERIALIZED VIEW' WHEN 'f' THEN 'FOREIGN TABLE' \ + WHEN 'p' THEN 'BASE TABLE' END AS table_type, \ + obj_description(c.oid) AS table_comment \ + FROM pg_catalog.pg_class c \ + JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \ + WHERE n.nspname = $1 AND c.relkind IN ('r','v','m','f','p') \ + ORDER BY c.relname", ) .bind(schema) .fetch_all(pool) @@ -224,11 +228,11 @@ pub async fn list_tables(pool: &PgPool, schema: &str) -> Result, pub async fn list_schemas(pool: &PgPool) -> Result, String> { let rows: Vec = sqlx::query( - "SELECT schema_name FROM information_schema.schemata \ - WHERE schema_name NOT IN ('information_schema', 'pg_catalog', 'pg_toast') \ - AND schema_name NOT LIKE 'pg_toast_temp_%' \ - AND schema_name NOT LIKE 'pg_temp_%' \ - ORDER BY schema_name", + "SELECT n.nspname AS schema_name FROM pg_catalog.pg_namespace n \ + WHERE n.nspname NOT IN ('information_schema', 'pg_catalog', 'pg_toast') \ + AND n.nspname NOT LIKE 'pg_toast_temp_%' \ + AND n.nspname NOT LIKE 'pg_temp_%' \ + ORDER BY n.nspname", ) .fetch_all(pool) .await