use sea_orm::{ConnectionTrait, DatabaseConnection, DatabaseBackend};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tracing::debug;
#[derive(Error, Debug)]
pub enum PoolError {
#[error("连接池信息获取失败: {0}")]
InfoFailed(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PoolStats {
pub max_connections: u32,
pub min_connections: u32,
pub active_connections: Option<u32>,
pub idle_connections: Option<u32>,
pub waiting_requests: Option<u32>,
}
pub struct ConnectionPoolService;
impl ConnectionPoolService {
pub async fn get_pool_stats(
db: &DatabaseConnection,
max_connections: Option<u32>,
min_connections: Option<u32>,
) -> Result<PoolStats, PoolError> {
let backend = db.get_database_backend();
let (active, idle, waiting) = match backend {
DatabaseBackend::Postgres => {
match Self::get_postgres_pool_stats(db).await {
Ok(stats) => stats,
Err(e) => {
debug!("无法获取 PostgreSQL 连接池统计信息: {}", e);
(None, None, None)
}
}
}
_ => {
(None, None, None)
}
};
Ok(PoolStats {
max_connections: max_connections.unwrap_or(100),
min_connections: min_connections.unwrap_or(5),
active_connections: active,
idle_connections: idle,
waiting_requests: waiting,
})
}
async fn get_postgres_pool_stats(
_db: &DatabaseConnection,
) -> Result<(Option<u32>, Option<u32>, Option<u32>), PoolError> {
debug!("PostgreSQL 连接池统计信息需要通过 sqlx 连接池获取");
Ok((None, None, None))
}
pub async fn health_check(db: &DatabaseConnection) -> Result<bool, PoolError> {
db.execute_unprepared("SELECT 1")
.await
.map_err(|e| PoolError::InfoFailed(format!("连接池健康检查失败: {}", e)))?;
Ok(true)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_pool_stats_serialization() {
let stats = PoolStats {
max_connections: 100,
min_connections: 5,
active_connections: Some(10),
idle_connections: Some(5),
waiting_requests: Some(0),
};
let json = serde_json::to_string(&stats).unwrap();
assert!(json.contains("max_connections"));
}
}