From 7a2b9a7d26ea47dc63409787245ba0c7fd03e5fd Mon Sep 17 00:00:00 2001 From: kyoto7250 <50972773+kyoto7250@users.noreply.github.com> Date: Tue, 21 Jun 2022 11:38:23 +0900 Subject: [PATCH 1/3] add option for using unix_domain_socket --- src/config.rs | 80 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/src/config.rs b/src/config.rs index 3d41831..ef3863a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -58,6 +58,7 @@ impl Default for Config { path: None, password: None, database: None, + unix_domain_socket: None, }], key_config: KeyConfig::default(), log_level: LogLevel::default(), @@ -74,6 +75,7 @@ pub struct Connection { port: Option, path: Option, password: Option, + unix_domain_socket: Option, pub database: Option, } @@ -199,22 +201,27 @@ impl Connection { .password .as_ref() .map_or(String::new(), |p| p.to_string()); + let unix_domain_socket = self + .valid_unix_domain_socket() + .map_or(String::new(), |uds| format!("?socket={}", uds)); match self.database.as_ref() { Some(database) => Ok(format!( - "mysql://{user}:{password}@{host}:{port}/{database}", + "mysql://{user}:{password}@{host}:{port}/{database}{unix_domain_socket}", user = user, password = password, host = host, + database = database, port = port, - database = database + unix_domain_socket = unix_domain_socket, )), None => Ok(format!( - "mysql://{user}:{password}@{host}:{port}", + "mysql://{user}:{password}@{host}:{port}{unix_domain_socket}", user = user, password = password, host = host, port = port, + unix_domain_socket = unix_domain_socket, )), } } @@ -236,22 +243,40 @@ impl Connection { .as_ref() .map_or(String::new(), |p| p.to_string()); - match self.database.as_ref() { - Some(database) => Ok(format!( - "postgres://{user}:{password}@{host}:{port}/{database}", - user = user, - password = password, - host = host, - port = port, - database = database - )), - None => Ok(format!( - "postgres://{user}:{password}@{host}:{port}", - user = user, - password = password, - host = host, - port = port, - )), + if let Some(unix_domain_socket) = self.valid_unix_domain_socket() { + match self.database.as_ref() { + Some(database) => Ok(format!( + "postgres://?dbname={database}&host={unix_domain_socket}&user={user}&password={password}", + database = database, + unix_domain_socket = unix_domain_socket, + user = user, + password = password, + )), + None => Ok(format!( + "postgres://?host={unix_domain_socket}&user={user}&password={password}", + unix_domain_socket = unix_domain_socket, + user = user, + password = password, + )), + } + } else { + match self.database.as_ref() { + Some(database) => Ok(format!( + "postgres://{user}:{password}@{host}:{port}/{database}", + user = user, + password = password, + host = host, + port = port, + database = database, + )), + None => Ok(format!( + "postgres://{user}:{password}@{host}:{port}", + user = user, + password = password, + host = host, + port = port, + )), + } } } DatabaseType::Sqlite => { @@ -287,6 +312,23 @@ impl Connection { pub fn is_postgres(&self) -> bool { matches!(self.r#type, DatabaseType::Postgres) } + + fn valid_unix_domain_socket(&self) -> Option { + if cfg!(windows) { + // NOTE: + // windows also supports UDS, but `rust` does not support UDS in windows now. + // https://github.com/rust-lang/rust/issues/56533 + return None; + } + return self.unix_domain_socket.as_ref().and_then(|uds| { + let path = expand_path(uds)?; + let path_str = path.to_str()?; + if path_str.is_empty() { + return None; + } + Some(path_str.to_owned()) + }); + } } pub fn get_app_config_path() -> anyhow::Result { From 585b49cbefd4fb8a410abb2b3865988ee5993dfe Mon Sep 17 00:00:00 2001 From: kyoto7250 <50972773+kyoto7250@users.noreply.github.com> Date: Tue, 21 Jun 2022 12:08:51 +0900 Subject: [PATCH 2/3] add tests --- src/config.rs | 130 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index ef3863a..2a6c16b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -367,7 +367,7 @@ fn expand_path(path: &Path) -> Option { #[cfg(test)] mod test { - use super::{expand_path, KeyConfig, Path, PathBuf}; + use super::{expand_path, Connection, DatabaseType, KeyConfig, Path, PathBuf}; use serde_json::Value; use std::env; @@ -391,6 +391,134 @@ mod test { } } + #[test] + #[cfg(unix)] + fn test_dataset_url_in_unix() { + let mut mysql_conn = Connection { + r#type: DatabaseType::MySql, + name: None, + user: Some("root".to_owned()), + host: Some("localhost".to_owned()), + port: Some(3306), + path: None, + password: Some("password".to_owned()), + database: Some("city".to_owned()), + unix_domain_socket: None, + }; + + assert_eq!( + mysql_conn.database_url().unwrap(), + "mysql://root:password@localhost:3306/city".to_owned() + ); + + mysql_conn.unix_domain_socket = Some(Path::new("/tmp/mysql.sock").to_path_buf()); + assert_eq!( + mysql_conn.database_url().unwrap(), + "mysql://root:password@localhost:3306/city?socket=/tmp/mysql.sock".to_owned() + ); + + let mut postgres_conn = Connection { + r#type: DatabaseType::Postgres, + name: None, + user: Some("root".to_owned()), + host: Some("localhost".to_owned()), + port: Some(3306), + path: None, + password: Some("password".to_owned()), + database: Some("city".to_owned()), + unix_domain_socket: None, + }; + + assert_eq!( + postgres_conn.database_url().unwrap(), + "postgres://root:password@localhost:3306/city".to_owned() + ); + postgres_conn.unix_domain_socket = Some(Path::new("/tmp").to_path_buf()); + assert_eq!( + postgres_conn.database_url().unwrap(), + "postgres://?dbname=city&host=/tmp&user=root&password=password".to_owned() + ); + + let sqlite_conn = Connection { + r#type: DatabaseType::Sqlite, + name: None, + user: None, + host: None, + port: None, + path: Some(PathBuf::from("/home/user/sqlite3.db")), + password: None, + database: None, + unix_domain_socket: None, + }; + + let sqlite_result = sqlite_conn.database_url().unwrap(); + assert_eq!(sqlite_result, "sqlite:///home/user/sqlite3.db".to_owned()); + } + + #[test] + #[cfg(windows)] + fn test_database_url_in_windows() { + let mut mysql_conn = Connection { + r#type: DatabaseType::MySql, + name: None, + user: Some("root".to_owned()), + host: Some("localhost".to_owned()), + port: Some(3306), + path: None, + password: Some("password".to_owned()), + database: Some("city".to_owned()), + unix_domain_socket: None, + }; + + assert_eq!( + mysql_conn.database_url().unwrap(), + "mysql://root:password@localhost:3306/city".to_owned() + ); + + mysql_conn.unix_domain_socket = Some(Path::new("/tmp/mysql.sock").to_path_buf()); + assert_eq!( + mysql_conn.database_url().unwrap(), + "mysql://root:password@localhost:3306/city".to_owned() + ); + + let mut postgres_conn = Connection { + r#type: DatabaseType::Postgres, + name: None, + user: Some("root".to_owned()), + host: Some("localhost".to_owned()), + port: Some(3306), + path: None, + password: Some("password".to_owned()), + database: Some("city".to_owned()), + unix_domain_socket: None, + }; + + assert_eq!( + postgres_conn.database_url().unwrap(), + "postgres://root:password@localhost:3306/city".to_owned() + ); + postgres_conn.unix_domain_socket = Some(Path::new("/tmp").to_path_buf()); + assert_eq!( + postgres_conn.database_url().unwrap(), + "postgres://root:password@localhost:3306/city".to_owned() + ); + + let sqlite_conn = Connection { + r#type: DatabaseType::Sqlite, + name: None, + user: None, + host: None, + port: None, + path: Some(PathBuf::from("/home/user/sqlite3.db")), + password: None, + database: None, + unix_domain_socket: None, + }; + + let sqlite_result = sqlite_conn.database_url().unwrap(); + assert_eq!(sqlite_result, "sqlite:///home/user/sqlite3.db".to_owned()); + } + #[test] #[cfg(unix)] fn test_expand_path() { From 427210f391c60fcd21c81f8e8f1364452894f3d8 Mon Sep 17 00:00:00 2001 From: kyoto7250 <50972773+kyoto7250@users.noreply.github.com> Date: Thu, 23 Jun 2022 22:17:19 +0900 Subject: [PATCH 3/3] fix windows test --- src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 2a6c16b..c03efe3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -516,7 +516,7 @@ mod test { }; let sqlite_result = sqlite_conn.database_url().unwrap(); - assert_eq!(sqlite_result, "sqlite:///home/user/sqlite3.db".to_owned()); + assert_eq!(sqlite_result, "sqlite://\\home\\user\\sqlite3.db".to_owned()); } #[test]