use crate::fdb::tenant_name::FoundationDbTenantName;
use foundationdb::{Database, tenant::TenantManagement};
use super::TenantHandle;
use super::metadata::{read_tenant_metadata, write_tenant_metadata};
use crate::fdb::error::{FdbError, FdbResult, TenantErrorReason};
pub async fn ensure_tenant(database: &Database, tenant: FoundationDbTenantName) -> FdbResult<()> {
let label = tenant.as_bytes();
let was_created = match TenantManagement::get_tenant(database, label).await {
Ok(Some(_info)) => false,
Ok(None) => {
TenantManagement::create_tenant(database, label)
.await
.map_err(|_| FdbError::Tenant {
reason: TenantErrorReason::AdministrationFailed { tenant },
})?;
true
}
Err(_) => {
return Err(FdbError::Tenant {
reason: TenantErrorReason::LookupFailed { tenant },
});
}
};
let inner = database.open_tenant(label).map_err(|_| FdbError::Tenant {
reason: TenantErrorReason::OpenFailed { tenant },
})?;
let tenant_handle = TenantHandle::new(tenant, inner);
if was_created {
return write_tenant_metadata(&tenant_handle, tenant).await;
}
read_tenant_metadata(&tenant_handle)
.await?
.ensure_compatible(tenant)
}
pub async fn delete_tenant(database: &Database, tenant: FoundationDbTenantName) -> FdbResult<()> {
TenantManagement::delete_tenant(database, tenant.as_bytes())
.await
.map_err(|_| FdbError::Tenant {
reason: TenantErrorReason::AdministrationFailed { tenant },
})
}
pub async fn tenant_exists(database: &Database, tenant: FoundationDbTenantName) -> FdbResult<bool> {
match TenantManagement::get_tenant(database, tenant.as_bytes()).await {
Ok(Some(_)) => Ok(true),
Ok(None) => Ok(false),
Err(_) => Err(FdbError::Tenant {
reason: TenantErrorReason::LookupFailed { tenant },
}),
}
}