Skip to content

Commit 1c0f25c

Browse files
committed
refactor(WIP): Querybuilder public interface
1 parent e6f463c commit 1c0f25c

21 files changed

Lines changed: 775 additions & 552 deletions

File tree

canyon_core/src/connection/clients/mssql.rs

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ use crate::connection::clients::mssql::sqlserver_query_launcher::execute_query;
22
use crate::connection::contracts::DbConnection;
33
use crate::connection::database_type::DatabaseType;
44
use crate::connection::datasources::DatasourceConfig;
5-
use crate::connection::{MsManager, SqlServerConnectionPool};
65
use crate::mapper::RowMapper;
76
use crate::query::parameters::QueryParameter;
87
use crate::rows::{CanyonRows, FromSqlOwnedValue};
98
use bb8::PooledConnection;
109
use std::error::Error;
10+
use std::sync::Arc;
1111
use tiberius::Query;
12+
use bb8_tiberius::ConnectionManager as TiberiusConnectionManager;
1213

13-
/// A connection with a `SqlServer` database
14+
type SqlServerConnectionPool = Arc<bb8::Pool<TiberiusConnectionManager>>;
15+
16+
/// A connector for a `SqlServer` database
1417
pub struct SqlServerConnector(SqlServerConnectionPool);
1518

1619
impl SqlServerConnector {
@@ -19,7 +22,7 @@ impl SqlServerConnector {
1922
}
2023
pub async fn get_pooled(
2124
&self,
22-
) -> Result<PooledConnection<'_, MsManager>, Box<dyn Error + Send + Sync>> {
25+
) -> Result<PooledConnection<'_, TiberiusConnectionManager>, Box<dyn Error + Send + Sync>> {
2326
Ok(self.0.get().await?)
2427
}
2528
}
@@ -190,18 +193,16 @@ pub(crate) mod __impl {
190193

191194
pub(crate) async fn create_sqlserver_connector(
192195
datasource: &DatasourceConfig,
193-
) -> Result<Arc<Pool<MsManager>>, Box<dyn Error + Send + Sync>> {
196+
) -> Result<Arc<Pool<TiberiusConnectionManager>>, Box<dyn Error + Send + Sync>> {
194197
let sqlserver_config = sqlserver_config_from_datasource(datasource)?;
195-
// let tcp = TcpStream::connect(tiberius_config.get_addr()).await?;
196-
// tcp.set_nodelay(true)?;
197198

198-
let manager = MsManager::new(sqlserver_config);
199+
let manager = TiberiusConnectionManager::new(sqlserver_config);
199200
let pool = bb8::Pool::builder().max_size(10u32).build(manager).await?;
200201

201202
Ok(SqlServerConnectionPool::from(pool))
202203
}
203204

204-
fn sqlserver_config_from_datasource(
205+
pub(crate) fn sqlserver_config_from_datasource(
205206
datasource: &DatasourceConfig,
206207
) -> Result<Config, Box<dyn Error + Send + Sync>> {
207208
let mut tiberius_config = tiberius::Config::new();
@@ -220,7 +221,7 @@ pub(crate) mod __impl {
220221
Ok(tiberius_config)
221222
}
222223

223-
pub fn extract_mssql_auth(
224+
pub(crate) fn extract_mssql_auth(
224225
auth: &Auth,
225226
) -> Result<tiberius::AuthMethod, Box<dyn std::error::Error + Send + Sync>> {
226227
match auth {
@@ -235,3 +236,52 @@ pub(crate) mod __impl {
235236
}
236237
}
237238
}
239+
#[cfg(test)]
240+
mod tests {
241+
use super::__impl;
242+
use crate::connection::datasources::{Auth, DatasourceConfig, DatasourceProperties, SqlServerAuth};
243+
use tiberius::AuthMethod;
244+
245+
#[test]
246+
fn test_extract_mssql_auth_basic() {
247+
let auth = Auth::SqlServer(SqlServerAuth::Basic {
248+
username: "sa".to_string(),
249+
password: "password123".to_string(),
250+
});
251+
252+
let result = __impl::extract_mssql_auth(&auth).unwrap();
253+
254+
match result {
255+
// We can only check the variant, not its internals (private fields)
256+
AuthMethod::SqlServer(_) => {} // success
257+
_ => panic!("Expected AuthMethod::SqlServer variant"),
258+
}
259+
}
260+
261+
#[test]
262+
fn test_extract_mssql_auth_integrated() {
263+
let auth = Auth::SqlServer(SqlServerAuth::Integrated);
264+
let result = __impl::extract_mssql_auth(&auth).unwrap();
265+
assert!(matches!(result, AuthMethod::Integrated));
266+
}
267+
268+
#[test]
269+
fn test_sqlserver_config_from_datasource_basic() {
270+
let datasource = DatasourceConfig {
271+
name: "test_source".into(),
272+
properties: DatasourceProperties {
273+
host: "localhost".into(),
274+
db_name: "test_db".into(),
275+
port: None, // default
276+
migrations: None,
277+
},
278+
auth: Auth::SqlServer(SqlServerAuth::Basic {
279+
username: "sa".into(),
280+
password: "pass123".into(),
281+
}),
282+
};
283+
284+
let config = __impl::sqlserver_config_from_datasource(&datasource).unwrap();
285+
assert_eq!(config.get_addr(), "localhost:1433");
286+
}
287+
}

canyon_core/src/connection/clients/postgresql.rs

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use crate::connection::contracts::DbConnection;
22
use crate::connection::database_type::DatabaseType;
33
use crate::connection::datasources::{Auth, DatasourceConfig, PostgresAuth};
4-
use crate::connection::{PgManager, PostgresConnectionPool};
54
use crate::mapper::RowMapper;
65
use crate::rows::FromSqlOwnedValue;
76
use crate::{query::parameters::QueryParameter, rows::CanyonRows};
87
use bb8::{Pool, PooledConnection};
98
use std::error::Error;
109
use std::sync::Arc;
10+
use bb8_postgres::PostgresConnectionManager;
1111
use tokio_postgres::types::ToSql;
1212
use tokio_postgres::{Config, NoTls};
1313

14+
type PgManager = PostgresConnectionManager<NoTls>;
15+
type PostgresConnectionPool = Arc<bb8::Pool<PgManager>>;
16+
1417
/// A connector with a `PostgreSQL` database
15-
#[cfg(feature = "postgres")]
1618
pub struct PostgresConnector(PostgresConnectionPool);
17-
18-
#[cfg(feature = "postgres")]
1919
impl PostgresConnector {
2020
pub async fn new(datasource: &DatasourceConfig) -> Result<Self, Box<dyn Error + Send + Sync>> {
2121
Ok(Self(create_postgres_connector(datasource).await?))
@@ -168,11 +168,84 @@ mod __impl {
168168
_ => Err("Invalid auth configuration for a Postgres datasource.".into()),
169169
}
170170
}
171+
171172
pub(crate) async fn create_postgres_connection_pool(
172173
config: Config,
173174
) -> Result<Pool<PgManager>, Box<dyn Error + Send + Sync>> {
174175
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?;
176179
Ok(pool)
177180
}
178181
}
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+
}

canyon_core/src/connection/mod.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,12 @@ use crate::canyon::Canyon;
3232
use crate::connection::contracts::DbConnection;
3333
use crate::connection::database_type::DatabaseType;
3434

35-
use bb8_postgres::PostgresConnectionManager;
36-
use bb8_tiberius::ConnectionManager as TiberiusConnectionManager;
37-
3835
use std::error::Error;
3936
use std::sync::{Arc, OnceLock};
4037

4138
use tokio::runtime::Runtime;
4239
use tokio::sync::Mutex;
43-
use tokio_postgres::NoTls;
44-
45-
type PgManager = PostgresConnectionManager<NoTls>;
46-
type PostgresConnectionPool = Arc<bb8::Pool<PgManager>>;
4740

48-
type MsManager = TiberiusConnectionManager;
49-
type SqlServerConnectionPool = Arc<bb8::Pool<MsManager>>;
50-
51-
//
5241
// // TODO's: DatabaseConnector and DataSource can implement default, so there's no need to use str and &str
5342
// // as defaults anymore, since the can load as the default the first one defined in the config file, or have more
5443
// // complex workflows that are deferred to initialization time

canyon_core/src/connection/provisional_tests.rs

Lines changed: 0 additions & 143 deletions
This file was deleted.

0 commit comments

Comments
 (0)