use super::*;
impl DbPool {
#[cfg(any(feature = "cache", feature = "oxcache-integration"))]
pub fn set_cache_provider(
&mut self,
provider: Arc<dyn crate::domain::DbCacheProvider + Send + Sync>,
) {
self.inner.cache_provider.store(Some(Arc::new(provider)));
}
#[cfg(feature = "sql-parser")]
pub fn set_ddl_guard(&self, guard: std::sync::Arc<dyn DdlGuardPolicy>) {
*self
.inner
.ddl_guard
.write()
.expect("ddl_guard lock poisoned") = Some(guard);
}
#[cfg(feature = "prepare-cache")]
pub fn enable_prepare_cache(&self, capacity: usize) {
*self
.inner
.prepare_cache
.write()
.expect("prepare_cache lock poisoned") = Some(std::sync::Arc::new(
crate::database::pool::prepare_cache::PoolPrepareCache::new(capacity),
));
}
#[cfg(feature = "prepare-cache")]
pub fn prepare_cache_stats(&self) -> Option<crate::database::pool::PrepareCacheStats> {
self.inner
.prepare_cache
.read()
.expect("prepare_cache lock poisoned")
.as_ref()
.map(|cache| cache.stats())
}
#[cfg(any(feature = "cache", feature = "oxcache-integration"))]
pub fn cache_provider(
&self,
) -> Option<Arc<Arc<dyn crate::domain::DbCacheProvider + Send + Sync>>> {
self.inner.cache_provider.load().clone()
}
pub async fn get_session(&self, role: &str) -> DbResult<Session> {
#[cfg(feature = "permission")]
self.validate_role_name(role).await?;
let connection = self.acquire_connection().await?;
let session = Session::new(connection, self.inner.clone(), role.to_string());
Ok(session)
}
pub async fn query_rows(&self, sql: &str, role: &str) -> DbResult<Vec<serde_json::Value>> {
let session = self.get_session(role).await?;
session.query_rows(sql).await
}
#[cfg(feature = "data-protection")]
pub async fn set_data_protection(&self, dp: crate::access::data_protection::DataProtection) {
*self.inner.data_protection.write().await = dp;
}
#[cfg(feature = "permission")]
pub async fn set_permission_config(
&self,
config: crate::access::permission::PermissionConfig,
) -> DbResult<()> {
for (role_name, policy) in &config.roles {
let _ = self.inner.policy_cache.set(role_name, policy).await;
}
self.inner.permission_config.store(Some(Arc::new(config)));
Ok(())
}
#[cfg(feature = "permission")]
pub(super) async fn validate_role_name(&self, role: &str) -> DbResult<()> {
let permission_config = self.inner.permission_config.load();
if permission_config.is_none() {
let safe_roles = ["admin", "system"];
if !safe_roles.contains(&role) {
return Err(DbError::Permission(format!(
"Role '{}' is not allowed without explicit permission configuration. Allowed roles: {}",
role,
safe_roles.join(", ")
)));
}
return Ok(());
}
if permission_config
.as_ref()
.is_some_and(|c| c.get_role_policy(role).is_none())
{
return Err(DbError::Permission(format!(
"Role '{}' is not defined in permission configuration",
role
)));
}
Ok(())
}
}