From fb9582fd2cafe3cbb8cb5ada1503a2680a1c4709 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Mon, 18 May 2026 14:33:18 +0800 Subject: [PATCH] feat(drivers): add YashanDB built-in support --- apps/desktop/public/icons/database/yashandb.png | Bin 0 -> 15267 bytes .../components/connection/ConnectionDialog.vue | 5 +++++ .../src/components/icons/DatabaseIcon.vue | 1 + apps/desktop/src/lib/connectionPresentation.ts | 1 + apps/desktop/src/lib/connectionUrl.ts | 1 + apps/desktop/src/lib/databaseCapabilitySets.ts | 6 ++++++ apps/desktop/src/stores/connectionStore.ts | 1 + apps/desktop/src/types/database.ts | 1 + crates/dbx-core/src/connection.rs | 1 + crates/dbx-core/src/database_capabilities.rs | 2 ++ crates/dbx-core/src/models/connection.rs | 14 ++++++++++++++ crates/dbx-core/tests/database_capabilities.rs | 4 ++++ src-tauri/src/commands/agents.rs | 2 ++ 13 files changed, 39 insertions(+) create mode 100644 apps/desktop/public/icons/database/yashandb.png diff --git a/apps/desktop/public/icons/database/yashandb.png b/apps/desktop/public/icons/database/yashandb.png new file mode 100644 index 0000000000000000000000000000000000000000..ef3ab69466038f719082a7f543fb9d8408c36be5 GIT binary patch literal 15267 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 literal 0 HcmV?d00001 diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue index 2c30a2aa3..03b2d07f6 100644 --- a/apps/desktop/src/components/connection/ConnectionDialog.vue +++ b/apps/desktop/src/components/connection/ConnectionDialog.vue @@ -163,6 +163,7 @@ const driverProfiles: Record< gaussdb: { type: "gaussdb", port: 5432, user: "gaussdb", label: "GaussDB", icon: "gaussdb" }, kingbase: { type: "kingbase", port: 54321, user: "system", label: "KingBase", icon: "kingbase" }, highgo: { type: "highgo", port: 5866, user: "highgo", label: "瀚高 HighGo", icon: "highgo" }, + yashandb: { type: "yashandb", port: 1688, user: "sys", label: "崖山 YashanDB", icon: "yashandb" }, vastbase: { type: "vastbase", port: 5432, user: "vastbase", label: "Vastbase", icon: "vastbase" }, doris: { type: "mysql", port: 9030, user: "root", label: "Doris", icon: "doris", urlParams: "" }, selectdb: { @@ -342,6 +343,7 @@ function defaultDatabaseForProfile() { if (form.value.db_type === "gaussdb") return "postgres"; if (selectedType.value === "cockroachdb") return "defaultdb"; if (form.value.db_type === "highgo") return "highgo"; + if (form.value.db_type === "yashandb") return "yasdb"; if (form.value.db_type === "postgres" || form.value.db_type === "kingbase" || form.value.db_type === "vastbase") return "postgres"; if (form.value.db_type === "sqlserver") return "master"; @@ -376,6 +378,7 @@ const iconTypeMap: Record = { gaussdb: "gaussdb", kingbase: "kingbase", highgo: "highgo", + yashandb: "yashandb", vastbase: "vastbase", doris: "doris", selectdb: "selectdb", @@ -425,6 +428,7 @@ const dbOptions = [ { value: "opengauss", label: "openGauss" }, { value: "kingbase", label: "KingBase" }, { value: "highgo", label: "瀚高 HighGo" }, + { value: "yashandb", label: "崖山 YashanDB" }, { value: "vastbase", label: "Vastbase" }, { value: "redshift", label: "Redshift" }, { value: "cockroachdb", label: "CockroachDB" }, @@ -1229,6 +1233,7 @@ function openExternalUrl(url: string) { form.db_type === 'informix' || form.db_type === 'kingbase' || form.db_type === 'highgo' || + form.db_type === 'yashandb' || form.db_type === 'vastbase' || form.db_type === 'goldendb' " diff --git a/apps/desktop/src/components/icons/DatabaseIcon.vue b/apps/desktop/src/components/icons/DatabaseIcon.vue index d56e59b28..3b6619dc5 100644 --- a/apps/desktop/src/components/icons/DatabaseIcon.vue +++ b/apps/desktop/src/components/icons/DatabaseIcon.vue @@ -29,6 +29,7 @@ const assetIcons: Record = { kingbase: "kingbase", goldendb: "goldendb.png", vastbase: "vastbase.png", + yashandb: "yashandb.png", snowflake: "snowflake", h2: "h2", dm: "dm", diff --git a/apps/desktop/src/lib/connectionPresentation.ts b/apps/desktop/src/lib/connectionPresentation.ts index 094a2246d..5c8d9f967 100644 --- a/apps/desktop/src/lib/connectionPresentation.ts +++ b/apps/desktop/src/lib/connectionPresentation.ts @@ -33,6 +33,7 @@ export function connectionUrlPlaceholder(dbType: DatabaseType): string { case "postgres": case "gaussdb": + case "yashandb": case "redshift": return "postgresql://user:password@host:port/database"; diff --git a/apps/desktop/src/lib/connectionUrl.ts b/apps/desktop/src/lib/connectionUrl.ts index a53150568..19752f276 100644 --- a/apps/desktop/src/lib/connectionUrl.ts +++ b/apps/desktop/src/lib/connectionUrl.ts @@ -40,6 +40,7 @@ const SCHEME_PROFILES: Record = { dm: { type: "dameng", profile: "dm", label: "DM (Dameng)", defaultPort: 5236 }, dameng: { type: "dameng", profile: "dm", label: "DM (Dameng)", defaultPort: 5236 }, gaussdb: { type: "gaussdb", profile: "gaussdb", label: "GaussDB", defaultPort: 5432 }, + yashandb: { type: "yashandb", profile: "yashandb", label: "崖山 YashanDB", defaultPort: 1688 }, opengauss: { type: "gaussdb", profile: "opengauss", label: "openGauss", defaultPort: 5432 }, tdengine: { type: "tdengine", profile: "tdengine", label: "TDengine", defaultPort: 6041 }, "taos-ws": { type: "tdengine", profile: "tdengine", label: "TDengine", defaultPort: 6041 }, diff --git a/apps/desktop/src/lib/databaseCapabilitySets.ts b/apps/desktop/src/lib/databaseCapabilitySets.ts index 36e82d2d7..1711bfa50 100644 --- a/apps/desktop/src/lib/databaseCapabilitySets.ts +++ b/apps/desktop/src/lib/databaseCapabilitySets.ts @@ -10,6 +10,7 @@ export const SCHEMA_AWARE_TYPES = new Set([ "kingbase", "highgo", "vastbase", + "yashandb", "jdbc", "h2", "snowflake", @@ -33,6 +34,7 @@ export const DIAGRAM_SUPPORTED_TYPES = new Set([ "highgo", "vastbase", "goldendb", + "yashandb", "access", "h2", "db2", @@ -53,6 +55,7 @@ export const DATABASE_SEARCH_SUPPORTED_TYPES = new Set([ "highgo", "vastbase", "goldendb", + "yashandb", "access", "h2", "snowflake", @@ -85,6 +88,7 @@ export const TABLE_IMPORT_SUPPORTED_TYPES = new Set([ "highgo", "vastbase", "goldendb", + "yashandb", "access", ]); @@ -132,6 +136,7 @@ export const TREE_SCHEMA_TYPES = new Set([ "kingbase", "highgo", "vastbase", + "yashandb", "jdbc", "trino", "h2", @@ -145,6 +150,7 @@ export const AGENT_DRIVER_TYPES = new Set([ "kingbase", "highgo", "vastbase", + "yashandb", "goldendb", "access", "oracle", diff --git a/apps/desktop/src/stores/connectionStore.ts b/apps/desktop/src/stores/connectionStore.ts index 3505442eb..635dbe6a4 100644 --- a/apps/desktop/src/stores/connectionStore.ts +++ b/apps/desktop/src/stores/connectionStore.ts @@ -194,6 +194,7 @@ export const useConnectionStore = defineStore("connection", () => { gaussdb: "GaussDB", kingbase: "KingBase", highgo: "瀚高 HighGo", + yashandb: "崖山 YashanDB", vastbase: "Vastbase", goldendb: "GoldenDB", access: "Microsoft Access", diff --git a/apps/desktop/src/types/database.ts b/apps/desktop/src/types/database.ts index 249370896..20660ec34 100644 --- a/apps/desktop/src/types/database.ts +++ b/apps/desktop/src/types/database.ts @@ -18,6 +18,7 @@ export type DatabaseType = | "highgo" | "vastbase" | "goldendb" + | "yashandb" | "access" | "h2" | "snowflake" diff --git a/crates/dbx-core/src/connection.rs b/crates/dbx-core/src/connection.rs index 74b099365..39364a188 100644 --- a/crates/dbx-core/src/connection.rs +++ b/crates/dbx-core/src/connection.rs @@ -232,6 +232,7 @@ impl AppState { | DatabaseType::Highgo | DatabaseType::Vastbase | DatabaseType::Goldendb + | DatabaseType::Yashandb | DatabaseType::Oracle | DatabaseType::H2 | DatabaseType::Snowflake diff --git a/crates/dbx-core/src/database_capabilities.rs b/crates/dbx-core/src/database_capabilities.rs index bdca40517..f0a2eef3a 100644 --- a/crates/dbx-core/src/database_capabilities.rs +++ b/crates/dbx-core/src/database_capabilities.rs @@ -7,6 +7,7 @@ pub fn agent_key(db_type: &DatabaseType, driver_profile: Option<&str>) -> Option DatabaseType::Highgo => Some("highgo"), DatabaseType::Vastbase => Some("vastbase"), DatabaseType::Goldendb => Some("goldendb"), + DatabaseType::Yashandb => Some("yashandb"), DatabaseType::Oracle => match driver_profile { Some("oracle-10g") => Some("oracle-10g"), _ => Some("oracle"), @@ -45,6 +46,7 @@ pub fn is_single_connection_pool(db_type: &DatabaseType) -> bool { | DatabaseType::Highgo | DatabaseType::Vastbase | DatabaseType::Goldendb + | DatabaseType::Yashandb | DatabaseType::Access | DatabaseType::Jdbc ) diff --git a/crates/dbx-core/src/models/connection.rs b/crates/dbx-core/src/models/connection.rs index 4db3524de..86ed00bd2 100644 --- a/crates/dbx-core/src/models/connection.rs +++ b/crates/dbx-core/src/models/connection.rs @@ -128,6 +128,7 @@ pub enum DatabaseType { Vastbase, Goldendb, Gaussdb, + Yashandb, Access, #[serde(rename = "h2")] H2, @@ -175,6 +176,7 @@ impl ConnectionConfig { DatabaseType::Gaussdb => Some("postgres"), DatabaseType::Kingbase | DatabaseType::Vastbase => Some("postgres"), DatabaseType::Highgo => Some("highgo"), + DatabaseType::Yashandb => Some("yasdb"), _ => None, } } @@ -267,6 +269,7 @@ impl ConnectionConfig { DatabaseType::Vastbase => format!("vastbase://{host}:{port}{db_part}"), DatabaseType::Goldendb => format!("goldendb://{host}:{port}{db_part}"), DatabaseType::Gaussdb => format!("gaussdb://{host}:{port}{db_part}"), + DatabaseType::Yashandb => format!("yashandb://{host}:{port}{db_part}"), DatabaseType::H2 => format!("h2://{host}:{port}{db_part}"), DatabaseType::Snowflake => format!("snowflake://{host}/{db_part}"), DatabaseType::Trino => format!("trino://{host}:{port}{db_part}"), @@ -366,6 +369,9 @@ impl ConnectionConfig { DatabaseType::Gaussdb => { format!("gaussdb://{}:{}@{host}:{port}{db_part}", username, password) } + DatabaseType::Yashandb => { + format!("yashandb://{}:{}@{host}:{port}{db_part}", username, password) + } DatabaseType::H2 => { format!("h2://{}:{}@{host}:{port}{db_part}", username, password) } @@ -816,6 +822,14 @@ mod tests { assert_eq!(config.connection_url(), "gaussdb://gaussdb:secret@10.1.2.3:2883/postgres"); } + #[test] + fn yashandb_url_defaults_to_yasdb_database() { + let mut config = mysql_config("sys", "secret", None); + config.db_type = DatabaseType::Yashandb; + + assert_eq!(config.connection_url(), "yashandb://sys:secret@10.1.2.3:2883/yasdb"); + } + #[test] fn mongodb_form_url_without_params_does_not_force_topology_or_auth() { let config = mongodb_config("root", "secret", Some("admin")); diff --git a/crates/dbx-core/tests/database_capabilities.rs b/crates/dbx-core/tests/database_capabilities.rs index 4337f3b12..1668ce956 100644 --- a/crates/dbx-core/tests/database_capabilities.rs +++ b/crates/dbx-core/tests/database_capabilities.rs @@ -9,6 +9,7 @@ fn maps_agent_database_types_to_driver_keys() { assert_eq!(agent_key(&DatabaseType::Hive, None), Some("hive")); assert_eq!(agent_key(&DatabaseType::Gaussdb, None), Some("gaussdb")); assert_eq!(agent_key(&DatabaseType::Tdengine, None), Some("tdengine")); + assert_eq!(agent_key(&DatabaseType::Yashandb, None), Some("yashandb")); assert_eq!(agent_key(&DatabaseType::Access, None), Some("access")); assert_eq!(agent_key(&DatabaseType::Oracle, None), Some("oracle")); assert_eq!(agent_key(&DatabaseType::Oracle, Some("oracle-10g")), Some("oracle-10g")); @@ -21,6 +22,7 @@ fn classifies_agent_database_types() { assert!(is_agent_type(&DatabaseType::Trino)); assert!(is_agent_type(&DatabaseType::Hive)); assert!(is_agent_type(&DatabaseType::Tdengine)); + assert!(is_agent_type(&DatabaseType::Yashandb)); assert!(is_agent_type(&DatabaseType::Access)); assert!(!is_agent_type(&DatabaseType::Mysql)); assert!(!is_agent_type(&DatabaseType::Jdbc)); @@ -33,6 +35,7 @@ fn identifies_single_connection_pool_types() { assert!(is_single_connection_pool(&DatabaseType::Oracle)); assert!(is_single_connection_pool(&DatabaseType::Dameng)); assert!(is_single_connection_pool(&DatabaseType::Access)); + assert!(is_single_connection_pool(&DatabaseType::Yashandb)); assert!(is_single_connection_pool(&DatabaseType::Jdbc)); assert!(!is_single_connection_pool(&DatabaseType::Trino)); assert!(!is_single_connection_pool(&DatabaseType::Postgres)); @@ -56,6 +59,7 @@ fn skips_tcp_probe_for_local_file_plugin_and_agent_types() { assert!(skips_tcp_probe(&DatabaseType::Trino)); assert!(skips_tcp_probe(&DatabaseType::Oracle)); assert!(skips_tcp_probe(&DatabaseType::Tdengine)); + assert!(skips_tcp_probe(&DatabaseType::Yashandb)); assert!(!skips_tcp_probe(&DatabaseType::Postgres)); assert!(!skips_tcp_probe(&DatabaseType::Mysql)); } diff --git a/src-tauri/src/commands/agents.rs b/src-tauri/src/commands/agents.rs index 00cc5cd33..464013c0d 100644 --- a/src-tauri/src/commands/agents.rs +++ b/src-tauri/src/commands/agents.rs @@ -36,6 +36,7 @@ const AGENT_TYPES: &[(&str, &str)] = &[ ("kylin", "Apache Kylin"), ("sundb", "SunDB"), ("gaussdb", "GaussDB"), + ("yashandb", "崖山 YashanDB"), ("tdengine", "TDengine"), ("mongodb", "MongoDB (Legacy)"), ]; @@ -112,6 +113,7 @@ mod tests { let agents = build_agent_list(&manager, None); assert!(agents.iter().any(|agent| agent.db_type == "tdengine" && agent.label == "TDengine")); + assert!(agents.iter().any(|agent| agent.db_type == "yashandb" && agent.label == "崖山 YashanDB")); assert!(agents.iter().any(|agent| agent.db_type == "access" && agent.label == "Microsoft Access")); let _ = std::fs::remove_dir_all(dir); }