99 lines
3.1 KiB
Rust
99 lines
3.1 KiB
Rust
use std::{error::Error, sync::Arc};
|
|
|
|
use async_trait::async_trait;
|
|
use testcontainers::{
|
|
GenericImage, ImageExt,
|
|
core::{IntoContainerPort, WaitFor},
|
|
runners::AsyncRunner,
|
|
};
|
|
|
|
use crate::{
|
|
ConfigInfoType,
|
|
containers::{
|
|
UnStartedContainer,
|
|
db::{
|
|
ContainerizedDBInfo, DBConfigInfoType, DBInfo,
|
|
config::{DatabaseContainerConfig, OptionalContainerConfig},
|
|
},
|
|
},
|
|
};
|
|
|
|
pub fn get_default_config() -> DatabaseContainerConfig {
|
|
DatabaseContainerConfig {
|
|
container_name: "yanpm-postgres".to_string(),
|
|
database_name: "postgres".to_string(),
|
|
user: "postgres".to_string(),
|
|
password: "postgres".to_string(),
|
|
image: "postgres".to_string(),
|
|
tag: "16-alpine".to_string(),
|
|
}
|
|
}
|
|
|
|
pub struct PostgreSQLContainer {
|
|
pub config: DatabaseContainerConfig,
|
|
}
|
|
|
|
#[async_trait]
|
|
impl DBInfo<OptionalContainerConfig> for PostgreSQLContainer {
|
|
async fn get_db_container_config_info(&self) -> DBConfigInfoType {
|
|
let pg_container = self
|
|
.get_unstarted_container()
|
|
.unwrap()
|
|
.await
|
|
.expect("Failed to start PostgreSQL container");
|
|
let pg_host = pg_container.get_host().await.expect("Failed to get host");
|
|
let pg_host_port = pg_container
|
|
.get_host_port_ipv4(5432.tcp())
|
|
.await
|
|
.expect("Failed to get host port");
|
|
let pg_url = format!(
|
|
"postgres://{}:{}@{}:{}/{}",
|
|
self.config.user,
|
|
self.config.password,
|
|
pg_host,
|
|
pg_host_port,
|
|
self.config.database_name
|
|
);
|
|
|
|
ConfigInfoType::Containerized(ContainerizedDBInfo {
|
|
db_type: crate::containers::db::DBType::PostgreSQL,
|
|
container: Arc::new(pg_container),
|
|
container_name: self.config.container_name.clone(),
|
|
database_name: self.config.database_name.clone(),
|
|
host: pg_host,
|
|
port: pg_host_port,
|
|
url: pg_url,
|
|
user: self.config.user.clone(),
|
|
password: self.config.password.clone(),
|
|
})
|
|
}
|
|
|
|
async fn new(user_default_config: Option<OptionalContainerConfig>) -> Self
|
|
where
|
|
Self: Sized,
|
|
{
|
|
let default_config = get_default_config();
|
|
let config = user_default_config
|
|
.unwrap_or_default()
|
|
.fill_with(&default_config);
|
|
|
|
PostgreSQLContainer {
|
|
config: config.clone(),
|
|
}
|
|
}
|
|
|
|
fn get_unstarted_container(&self) -> Result<UnStartedContainer, Box<dyn Error>> {
|
|
Ok(
|
|
GenericImage::new(self.config.image.clone(), self.config.tag.clone())
|
|
.with_exposed_port(5432.tcp())
|
|
.with_wait_for(WaitFor::message_on_stderr(
|
|
"database system is ready to accept connections",
|
|
))
|
|
.with_container_name(self.config.container_name.clone())
|
|
.with_env_var("POSTGRES_USER", self.config.user.clone())
|
|
.with_env_var("POSTGRES_PASSWORD", self.config.password.clone())
|
|
.start(),
|
|
)
|
|
}
|
|
}
|