From 0c430c9fb40871b248b152323d83e6cd96d30faf Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 7 May 2026 04:10:30 +0800 Subject: [PATCH] fix: filter system schemas for Oracle and DM (Dameng) --- crates/dbx-core/src/db/dm_driver.rs | 11 +++++-- crates/dbx-core/src/db/oracle_driver.rs | 42 ++++++++++++++++++++----- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/crates/dbx-core/src/db/dm_driver.rs b/crates/dbx-core/src/db/dm_driver.rs index a5dec78b1..2e48fff55 100644 --- a/crates/dbx-core/src/db/dm_driver.rs +++ b/crates/dbx-core/src/db/dm_driver.rs @@ -81,12 +81,19 @@ pub async fn connect(host: &str, port: u16, database: &str, user: &str, pass: &s } pub fn list_databases(client: &DmClient) -> Result, String> { - let rows = client.query_single_column("SELECT USERNAME FROM ALL_USERS ORDER BY USERNAME")?; + let rows = client.query_single_column( + "SELECT USERNAME FROM ALL_USERS \ + WHERE USERNAME NOT IN (\ + 'SYS','SYSDBA','SYSAUDITOR','SYSSSO','CTISYS',\ + 'SYS_DBA','_SYS_STATISTICS','SYS_PHM'\ + ) ORDER BY USERNAME", + )?; Ok(rows.into_iter().map(|name| DatabaseInfo { name }).collect()) } pub fn list_schemas(client: &DmClient) -> Result, String> { - client.query_single_column("SELECT USERNAME FROM ALL_USERS ORDER BY USERNAME") + let dbs = list_databases(client)?; + Ok(dbs.into_iter().map(|d| d.name).collect()) } pub fn list_tables(client: &DmClient, schema: &str) -> Result, String> { diff --git a/crates/dbx-core/src/db/oracle_driver.rs b/crates/dbx-core/src/db/oracle_driver.rs index a998bbb42..15350e358 100644 --- a/crates/dbx-core/src/db/oracle_driver.rs +++ b/crates/dbx-core/src/db/oracle_driver.rs @@ -39,17 +39,45 @@ fn value_to_json(val: &oracle_rs::Value) -> serde_json::Value { pub async fn list_databases(conn: &OracleClient) -> Result, String> { log::debug!("[oracle] list_databases: querying all_users"); - let result = conn.query("SELECT username FROM all_users ORDER BY username", &[]).await.map_err(|e| { - log::error!("[oracle] list_databases failed: {e}"); - e.to_string() - })?; + let result = conn + .query( + "SELECT username FROM all_users \ + WHERE oracle_maintained = 'N' \ + OR NOT EXISTS (SELECT 1 FROM all_users WHERE oracle_maintained IS NOT NULL) \ + ORDER BY username", + &[], + ) + .await; + + let result = match result { + Ok(r) => r, + Err(_) => conn + .query( + "SELECT username FROM all_users \ + WHERE username NOT IN (\ + 'SYS','SYSTEM','SYSMAN','DBSNMP','SYSBACKUP','SYSDG','SYSKM','OUTLN',\ + 'AUDSYS','LBACSYS','DVF','DVSYS','APPQOSSYS','CTXSYS','MDSYS','MDDATA',\ + 'ORDSYS','ORDDATA','ORDPLUGINS','XDB','ANONYMOUS','DIP','EXFSYS',\ + 'GSMADMIN_INTERNAL','GSMCATUSER','GSMUSER','OJVMSYS','OLAPSYS',\ + 'ORACLE_OCM','SI_INFORMTN_SCHEMA','WMSYS','XS$NULL','DBSFWUSER',\ + 'REMOTE_SCHEDULER_AGENT','PDBADMIN','DGPDB_INT','OPS$ORACLE',\ + 'GGSYS','FLOWS_FILES','APEX_PUBLIC_USER'\ + ) ORDER BY username", + &[], + ) + .await + .map_err(|e| { + log::error!("[oracle] list_databases failed: {e}"); + e.to_string() + })?, + }; + Ok(result.rows.iter().map(|row| DatabaseInfo { name: row.get_string(0).unwrap_or("").to_string() }).collect()) } pub async fn list_schemas(conn: &OracleClient) -> Result, String> { - let result = - conn.query("SELECT username FROM all_users ORDER BY username", &[]).await.map_err(|e| e.to_string())?; - Ok(result.rows.iter().map(|row| row.get_string(0).unwrap_or("").to_string()).collect()) + let dbs = list_databases(conn).await?; + Ok(dbs.into_iter().map(|d| d.name).collect()) } pub async fn list_tables(conn: &OracleClient, schema: &str) -> Result, String> {