|
1 | 1 | use crate::connection::contracts::DbConnection; |
2 | 2 | use crate::connection::database_type::DatabaseType; |
3 | 3 | use crate::connection::datasources::{Auth, DatasourceConfig, PostgresAuth}; |
4 | | -use crate::connection::{PgManager, PostgresConnectionPool}; |
5 | 4 | use crate::mapper::RowMapper; |
6 | 5 | use crate::rows::FromSqlOwnedValue; |
7 | 6 | use crate::{query::parameters::QueryParameter, rows::CanyonRows}; |
8 | 7 | use bb8::{Pool, PooledConnection}; |
9 | 8 | use std::error::Error; |
10 | 9 | use std::sync::Arc; |
| 10 | +use bb8_postgres::PostgresConnectionManager; |
11 | 11 | use tokio_postgres::types::ToSql; |
12 | 12 | use tokio_postgres::{Config, NoTls}; |
13 | 13 |
|
| 14 | +type PgManager = PostgresConnectionManager<NoTls>; |
| 15 | +type PostgresConnectionPool = Arc<bb8::Pool<PgManager>>; |
| 16 | + |
14 | 17 | /// A connector with a `PostgreSQL` database |
15 | | -#[cfg(feature = "postgres")] |
16 | 18 | pub struct PostgresConnector(PostgresConnectionPool); |
17 | | - |
18 | | -#[cfg(feature = "postgres")] |
19 | 19 | impl PostgresConnector { |
20 | 20 | pub async fn new(datasource: &DatasourceConfig) -> Result<Self, Box<dyn Error + Send + Sync>> { |
21 | 21 | Ok(Self(create_postgres_connector(datasource).await?)) |
@@ -168,11 +168,84 @@ mod __impl { |
168 | 168 | _ => Err("Invalid auth configuration for a Postgres datasource.".into()), |
169 | 169 | } |
170 | 170 | } |
| 171 | + |
171 | 172 | pub(crate) async fn create_postgres_connection_pool( |
172 | 173 | config: Config, |
173 | 174 | ) -> Result<Pool<PgManager>, Box<dyn Error + Send + Sync>> { |
174 | 175 | let manager = PgManager::new(config, NoTls); |
175 | | - let pool = bb8::Pool::builder().max_size(10u32).build(manager).await?; |
| 176 | + let pool = bb8::Pool::builder() |
| 177 | + .max_size(10u32) |
| 178 | + .build(manager).await?; |
176 | 179 | Ok(pool) |
177 | 180 | } |
178 | 181 | } |
| 182 | + |
| 183 | +#[cfg(test)] |
| 184 | +mod tests { |
| 185 | + use super::__impl; |
| 186 | + use crate::connection::datasources::{Auth, DatasourceConfig, DatasourceProperties, PostgresAuth}; |
| 187 | + |
| 188 | + #[test] |
| 189 | + fn test_extract_postgres_auth_basic() { |
| 190 | + let auth = Auth::Postgres(PostgresAuth::Basic { |
| 191 | + username: "pguser".into(), |
| 192 | + password: "pgpass".into(), |
| 193 | + }); |
| 194 | + |
| 195 | + let (user, pass) = __impl::extract_postgres_auth(&auth).unwrap(); |
| 196 | + assert_eq!(user, "pguser"); |
| 197 | + assert_eq!(pass, "pgpass"); |
| 198 | + } |
| 199 | + |
| 200 | + #[test] |
| 201 | + fn test_set_tokio_postgres_configs_basic() { |
| 202 | + let datasource = DatasourceConfig { |
| 203 | + name: "pg_test".into(), |
| 204 | + properties: DatasourceProperties { |
| 205 | + host: "localhost".into(), |
| 206 | + db_name: "pg_db".into(), |
| 207 | + port: Some(5433), |
| 208 | + migrations: None, |
| 209 | + }, |
| 210 | + auth: Auth::Postgres(PostgresAuth::Basic { |
| 211 | + username: "pguser".into(), |
| 212 | + password: "pgpass".into(), |
| 213 | + }), |
| 214 | + }; |
| 215 | + |
| 216 | + let config = __impl::set_tokio_postgres_configs(&datasource, "pguser", "pgpass"); |
| 217 | + |
| 218 | + assert_eq!(config.get_hosts(), vec![tokio_postgres::config::Host::Tcp("localhost".into())]); |
| 219 | + assert_eq!(config.get_dbname(), Some("pg_db")); |
| 220 | + assert_eq!(config.get_user(), Some("pguser")); |
| 221 | + assert_eq!(*config.get_ports().first().unwrap(), 5433); |
| 222 | + |
| 223 | + // sanity check for configured timeouts and keepalives |
| 224 | + assert_eq!(config.get_connect_timeout(), Some(std::time::Duration::from_secs(5)).as_ref()); |
| 225 | + assert_eq!(config.get_keepalives_idle(), std::time::Duration::from_secs(30)); |
| 226 | + assert_eq!(config.get_keepalives_interval(), Some(std::time::Duration::from_secs(10))); |
| 227 | + assert_eq!(config.get_keepalives_retries(), Some(3)); |
| 228 | + } |
| 229 | + |
| 230 | + #[test] |
| 231 | + fn test_set_tokio_postgres_configs_default_port() { |
| 232 | + let datasource = DatasourceConfig { |
| 233 | + name: "pg_test_default".into(), |
| 234 | + properties: DatasourceProperties { |
| 235 | + host: "127.0.0.1".into(), |
| 236 | + db_name: "default_db".into(), |
| 237 | + port: None, |
| 238 | + migrations: None, |
| 239 | + }, |
| 240 | + auth: Auth::Postgres(PostgresAuth::Basic { |
| 241 | + username: "user".into(), |
| 242 | + password: "pass".into(), |
| 243 | + }), |
| 244 | + }; |
| 245 | + |
| 246 | + let config = __impl::set_tokio_postgres_configs(&datasource, "user", "pass"); |
| 247 | + assert_eq!(*config.get_ports().first().unwrap(), 5432); // default Postgres port |
| 248 | + assert_eq!(config.get_dbname(), Some("default_db")); |
| 249 | + assert_eq!(config.get_user(), Some("user")); |
| 250 | + } |
| 251 | +} |
0 commit comments