use crate::adbc::Connection;
use crate::connection::params::ConnectionParams;
use crate::error::ConnectionError;
use std::str::FromStr;
#[derive(Debug, Clone)]
pub struct Database {
params: ConnectionParams,
connection_string: String,
}
impl Database {
pub fn new(params: ConnectionParams) -> Self {
let connection_string = format!(
"exasol://{}@{}:{}{}",
params.username,
params.host,
params.port,
params
.schema
.as_ref()
.map(|s| format!("/{}", s))
.unwrap_or_default()
);
Self {
params,
connection_string,
}
}
pub fn params(&self) -> &ConnectionParams {
&self.params
}
pub fn connection_string(&self) -> &str {
&self.connection_string
}
pub async fn connect(&self) -> Result<Connection, ConnectionError> {
Connection::from_params(self.params.clone()).await
}
pub async fn test_connection(&self) -> Result<(), ConnectionError> {
let connection = self.connect().await?;
connection.close().await?;
Ok(())
}
}
impl FromStr for Database {
type Err = ConnectionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let params = ConnectionParams::from_str(s)?;
Ok(Self::new(params))
}
}
impl std::fmt::Display for Database {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Database({})", self.connection_string)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::connection::ConnectionBuilder;
#[test]
fn test_database_creation() {
let params = ConnectionBuilder::new()
.host("localhost")
.port(8563)
.username("test")
.password("secret")
.build()
.unwrap();
let database = Database::new(params);
assert!(database.connection_string().contains("localhost"));
assert!(database.connection_string().contains("test"));
assert!(!database.connection_string().contains("secret"));
}
#[test]
fn test_database_from_str_basic() {
let database = Database::from_str("exasol://user@localhost").unwrap();
assert_eq!(database.params().host, "localhost");
assert_eq!(database.params().port, 8563);
assert_eq!(database.params().username, "user");
}
#[test]
fn test_database_from_str_with_port() {
let database = Database::from_str("exasol://user@localhost:9000").unwrap();
assert_eq!(database.params().port, 9000);
}
#[test]
fn test_database_from_str_with_password() {
let database = Database::from_str("exasol://user:pass@localhost").unwrap();
assert_eq!(database.params().username, "user");
assert!(database.connection_string().contains("user"));
assert!(!database.connection_string().contains("pass"));
}
#[test]
fn test_database_from_str_with_schema() {
let database = Database::from_str("exasol://user@localhost/MY_SCHEMA").unwrap();
assert_eq!(database.params().schema, Some("MY_SCHEMA".to_string()));
assert!(database.connection_string().contains("MY_SCHEMA"));
}
#[test]
fn test_database_from_str_full() {
let database =
Database::from_str("exasol://admin:secret@db.example.com:9000/PROD?timeout=30")
.unwrap();
assert_eq!(database.params().host, "db.example.com");
assert_eq!(database.params().port, 9000);
assert_eq!(database.params().username, "admin");
assert_eq!(database.params().schema, Some("PROD".to_string()));
}
#[test]
fn test_database_from_str_invalid() {
let result = Database::from_str("invalid://connection");
assert!(result.is_err());
let result = Database::from_str("");
assert!(result.is_err());
let result = Database::from_str("postgres://user@host");
assert!(result.is_err());
}
#[test]
fn test_database_display() {
let database = Database::from_str("exasol://user@localhost/SCHEMA").unwrap();
let display = format!("{}", database);
assert!(display.contains("Database"));
assert!(display.contains("localhost"));
assert!(display.contains("SCHEMA"));
}
#[test]
fn test_database_debug() {
let database = Database::from_str("exasol://user@localhost").unwrap();
let debug = format!("{:?}", database);
assert!(debug.contains("Database"));
assert!(debug.contains("params"));
}
}