use std::sync::Arc;
use async_trait::async_trait;
use nisshi_schema::redact_url;
use nisshi_storage::{
ArcDynStorage, Error, Result, StartupFailure, Storage as _, StorageFactory,
StorageFactoryConfiguration,
};
use regex::Regex;
use super::Postgres;
#[derive(Clone, Copy, Debug)]
pub struct PostgresFactory;
#[async_trait]
impl StorageFactory for PostgresFactory {
fn scheme(&self) -> Result<Regex> {
Regex::new(r"postgres|postgresql").map_err(Into::into)
}
async fn build(&self, configuration: StorageFactoryConfiguration) -> Result<ArcDynStorage> {
let storage = Postgres::builder(configuration.storage.to_string().as_str())
.map(|builder| builder.cluster(&configuration.cluster))
.map(|builder| builder.node(configuration.node_id))
.map(|builder| builder.advertised_listener(configuration.advertised_listener.clone()))
.map(|builder| builder.schemas(configuration.schema_registry.clone()))
.map(|builder| builder.lake(configuration.lake_house.clone()))
.map(|builder| builder.build())?;
storage
.ping()
.await
.map_err(|source| Error::StartupFailed {
storage: Arc::new(redact_url(&configuration.storage)),
failure: StartupFailure::StorageUnreachable,
source: Arc::new(source),
})?;
storage
.ensure_schema()
.await
.map_err(|source| Error::StartupFailed {
storage: Arc::new(redact_url(&configuration.storage)),
failure: StartupFailure::SchemaSetup,
source: Arc::new(source),
})?;
Ok(Arc::new(Box::new(storage)) as ArcDynStorage)
}
}