diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue index c1d8e660e..6042e1050 100644 --- a/apps/desktop/src/components/connection/ConnectionDialog.vue +++ b/apps/desktop/src/components/connection/ConnectionDialog.vue @@ -135,6 +135,7 @@ const defaultForm = (): ConnectionForm => ({ redis_key_separator: ":", etcd_endpoints: "", gbase_server: "", + informix_server: "", external_config: undefined, read_only: false, visible_databases: undefined, @@ -736,6 +737,7 @@ watch( redis_cluster_nodes: config.redis_cluster_nodes || "", redis_key_separator: config.redis_key_separator ?? ":", etcd_endpoints: config.etcd_endpoints || "", + informix_server: config.informix_server || "", read_only: config.read_only || false, visible_databases: config.visible_databases, }; @@ -1255,6 +1257,13 @@ function connectionConfigForSubmit(id: string): ConnectionConfig { if (config.db_type === "manticoresearch") { config.url_params = ""; } + if (config.db_type === "informix" && config.informix_server) { + // Strip INFORMIXSERVER from url_params to avoid duplicate when dedicated field is used + config.url_params = (config.url_params || "") + .replace(/(?:^|[;])\s*INFORMIXSERVER\s*=[^;]*/gi, "") + .replace(/^[;]|[;]$/g, "") + .trim(); + } if (!config.one_time) config.one_time = undefined; if (!config.read_only) config.read_only = undefined; if (config.db_type === "mq") { @@ -2973,6 +2982,11 @@ function openExternalUrl(url: string) { +
+ + +
+
@@ -3043,7 +3057,7 @@ function openExternalUrl(url: string) { : form.db_type === 'bigquery' ? 'OAuthType=0;OAuthServiceAcctEmail=svc@project.iam.gserviceaccount.com;OAuthPvtKeyPath=/path/key.json' : form.db_type === 'informix' - ? 'INFORMIXSERVER=informix;CLIENT_LOCALE=en_US.utf8;DB_LOCALE=en_US.utf8' + ? 'CLIENT_LOCALE=en_US.utf8;DB_LOCALE=en_US.utf8' : 'sslmode=disable' " /> diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index 5c95a0fe2..65867818d 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -172,6 +172,7 @@ export default { driverNamePlaceholder: "Vendor or environment name", urlParams: "URL Params", gbaseServer: "GBASEDBTSERVER", + informixServer: "INFORMIXSERVER", sslEnable: "Enable encrypted connection", caCertPath: "CA Certificate", caCertPathPlaceholder: "Optional, e.g. ~/.yandex/RootCA.crt", diff --git a/apps/desktop/src/i18n/locales/ja.ts b/apps/desktop/src/i18n/locales/ja.ts index 4a16cd6a5..9afbe8868 100644 --- a/apps/desktop/src/i18n/locales/ja.ts +++ b/apps/desktop/src/i18n/locales/ja.ts @@ -171,6 +171,7 @@ export default { driverNamePlaceholder: "ベンダー名または環境名", urlParams: "URLパラメータ", gbaseServer: "GBASEDBTSERVER", + informixServer: "INFORMIXSERVER", sslEnable: "暗号化接続を有効にする", caCertPath: "CA証明書", caCertPathPlaceholder: "任意、例: ~/.yandex/RootCA.crt", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index a2ba6a994..84f023cf9 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -173,6 +173,7 @@ export default { driverNamePlaceholder: "厂商或环境名称", urlParams: "URL 参数", gbaseServer: "GBASEDBTSERVER", + informixServer: "INFORMIXSERVER", sslEnable: "启用加密连接", caCertPath: "CA 证书", caCertPathPlaceholder: "可选,例如 ~/.yandex/RootCA.crt", diff --git a/apps/desktop/src/types/database.ts b/apps/desktop/src/types/database.ts index fcf7f6c6b..42e51d656 100644 --- a/apps/desktop/src/types/database.ts +++ b/apps/desktop/src/types/database.ts @@ -101,6 +101,7 @@ export interface ConnectionConfig { redis_key_separator?: string; etcd_endpoints?: string; gbase_server?: string; + informix_server?: string; external_config?: unknown; one_time?: boolean; read_only?: boolean; diff --git a/crates/dbx-core/src/agent_connection.rs b/crates/dbx-core/src/agent_connection.rs index 57fd56000..5207f8966 100644 --- a/crates/dbx-core/src/agent_connection.rs +++ b/crates/dbx-core/src/agent_connection.rs @@ -49,6 +49,7 @@ pub fn agent_connect_params(config: &ConnectionConfig, host: &str, port: u16, da "client_key_path": config.client_key_path, "etcd_endpoints": etcd_endpoints, "gbase_server": config.gbase_server, + "informix_server": config.informix_server, "jdbc_driver_class": config.jdbc_driver_class.as_deref().unwrap_or(""), "jdbc_driver_paths": &config.jdbc_driver_paths, }) @@ -564,6 +565,7 @@ mod tests { redis_key_separator: default_redis_key_separator(), etcd_endpoints: String::new(), gbase_server: String::new(), + informix_server: String::new(), external_config: None, jdbc_driver_class: None, jdbc_driver_paths: Vec::new(), diff --git a/crates/dbx-core/src/db/agent_driver.rs b/crates/dbx-core/src/db/agent_driver.rs index 42603a864..bd6437dfc 100644 --- a/crates/dbx-core/src/db/agent_driver.rs +++ b/crates/dbx-core/src/db/agent_driver.rs @@ -808,7 +808,7 @@ fn agent_java_args(jar_path: &str) -> Vec { .map(str::to_string) .collect::>(); - if agent_jar_path_matches_key(jar_path, "kingbase") { + if agent_jar_path_matches_key(jar_path, "kingbase") || agent_jar_path_matches_key(jar_path, "informix") { args.push("-Djava.net.preferIPv4Stack=true".to_string()); } @@ -981,6 +981,13 @@ mod tests { assert!(args.iter().any(|arg| arg == "-Djava.net.preferIPv4Stack=true")); } + #[test] + fn agent_java_args_prefer_ipv4_for_informix() { + let args = agent_java_args("/tmp/dbx/drivers/informix/agent.jar"); + + assert!(args.iter().any(|arg| arg == "-Djava.net.preferIPv4Stack=true")); + } + #[test] fn agent_java_args_do_not_prefer_ipv4_for_other_agents() { let args = agent_java_args("/tmp/dbx/drivers/highgo/agent.jar"); diff --git a/crates/dbx-core/src/models/connection.rs b/crates/dbx-core/src/models/connection.rs index d7bcfd0d8..04d0133a6 100644 --- a/crates/dbx-core/src/models/connection.rs +++ b/crates/dbx-core/src/models/connection.rs @@ -68,6 +68,10 @@ pub struct ConnectionConfig { pub etcd_endpoints: String, #[serde(default, skip_serializing_if = "String::is_empty")] pub gbase_server: String, + /// Informix server name (INFORMIXSERVER). When empty, the agent + /// derives it from the hostname. + #[serde(default, skip_serializing_if = "String::is_empty")] + pub informix_server: String, /// Typed configuration for external tabular sources. #[serde(default)] pub external_config: Option, @@ -374,6 +378,8 @@ struct ConnectionConfigData { #[serde(default)] pub gbase_server: String, #[serde(default)] + pub informix_server: String, + #[serde(default)] pub external_config: Option, #[serde(default)] pub jdbc_driver_class: Option, @@ -424,6 +430,7 @@ impl From for ConnectionConfig { redis_key_separator: data.redis_key_separator, etcd_endpoints: data.etcd_endpoints, gbase_server: data.gbase_server, + informix_server: data.informix_server, external_config: data.external_config, jdbc_driver_class: data.jdbc_driver_class, jdbc_driver_paths: data.jdbc_driver_paths, @@ -1463,6 +1470,7 @@ mod tests { redis_key_separator: default_redis_key_separator(), etcd_endpoints: String::new(), gbase_server: String::new(), + informix_server: String::new(), external_config: None, jdbc_driver_class: None, jdbc_driver_paths: Vec::new(),