use super::connection::TestClusterConnection;
use super::lifecycle::DatabaseName;
use super::temporary_database::TemporaryDatabase;
use crate::error::BootstrapResult;
use crate::{TestBootstrapEnvironment, TestBootstrapSettings};
use postgresql_embedded::Settings;
#[derive(Debug, Clone)]
pub struct ClusterHandle {
bootstrap: TestBootstrapSettings,
}
const _: () = {
const fn assert_send<T: Send>() {}
const fn assert_sync<T: Sync>() {}
assert_send::<ClusterHandle>();
assert_sync::<ClusterHandle>();
};
impl From<TestBootstrapSettings> for ClusterHandle {
fn from(bootstrap: TestBootstrapSettings) -> Self {
Self { bootstrap }
}
}
impl ClusterHandle {
pub(super) const fn new(bootstrap: TestBootstrapSettings) -> Self {
Self { bootstrap }
}
#[must_use]
pub const fn settings(&self) -> &Settings {
&self.bootstrap.settings
}
#[must_use]
pub const fn environment(&self) -> &TestBootstrapEnvironment {
&self.bootstrap.environment
}
#[must_use]
pub const fn bootstrap(&self) -> &TestBootstrapSettings {
&self.bootstrap
}
#[must_use]
pub fn connection(&self) -> TestClusterConnection {
TestClusterConnection::new(&self.bootstrap)
}
}
impl ClusterHandle {
pub fn create_database(&self, name: impl Into<DatabaseName>) -> BootstrapResult<()> {
self.connection().create_database(name)
}
pub fn create_database_from_template(
&self,
name: impl Into<DatabaseName>,
template: impl Into<DatabaseName>,
) -> BootstrapResult<()> {
self.connection()
.create_database_from_template(name, template)
}
pub fn drop_database(&self, name: impl Into<DatabaseName>) -> BootstrapResult<()> {
self.connection().drop_database(name)
}
pub fn database_exists(&self, name: impl Into<DatabaseName>) -> BootstrapResult<bool> {
self.connection().database_exists(name)
}
pub fn ensure_template_exists<F>(
&self,
name: impl Into<DatabaseName>,
setup_fn: F,
) -> BootstrapResult<()>
where
F: FnOnce(&str) -> BootstrapResult<()>,
{
self.connection().ensure_template_exists(name, setup_fn)
}
pub fn temporary_database(
&self,
name: impl Into<DatabaseName>,
) -> BootstrapResult<TemporaryDatabase> {
self.connection().temporary_database(name)
}
pub fn temporary_database_from_template(
&self,
name: impl Into<DatabaseName>,
template: impl Into<DatabaseName>,
) -> BootstrapResult<TemporaryDatabase> {
self.connection()
.temporary_database_from_template(name, template)
}
}
impl ClusterHandle {
pub fn register_shutdown_on_exit(&self) -> BootstrapResult<()> {
self.register_shutdown_on_exit_impl()
}
#[cfg(unix)]
fn register_shutdown_on_exit_impl(&self) -> BootstrapResult<()> {
super::shutdown_hook::register_shutdown_hook(
self.bootstrap.settings.clone(),
self.bootstrap.shutdown_timeout,
self.bootstrap.cleanup_mode,
)
}
#[cfg(not(unix))]
fn register_shutdown_on_exit_impl(&self) -> BootstrapResult<()> {
Ok(())
}
}