use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, prelude::*}; use uuid::Uuid; use crate::service::proxy::types::{LimitZoneConfig, ProxyServiceError, ProxyServiceResult}; pub struct CreateLimitZoneParams { pub name: String, pub key: String, pub rate: String, pub override_of_id: Option, } pub struct UpdateLimitZoneParams { pub name: Option, pub key: Option, pub rate: Option, pub override_of_id: Option>, } #[cfg_attr(test, mockall::automock)] #[async_trait::async_trait] pub trait LimitZoneService: Send + Sync + 'static { async fn get(&self, id: Uuid) -> ProxyServiceResult; async fn list(&self) -> ProxyServiceResult>; async fn create(&self, params: CreateLimitZoneParams) -> ProxyServiceResult; async fn update( &self, id: Uuid, params: UpdateLimitZoneParams, ) -> ProxyServiceResult; async fn delete(&self, id: Uuid) -> ProxyServiceResult; } pub(crate) struct LimitZoneServiceImpl { db: DatabaseConnection, } impl LimitZoneServiceImpl { pub fn new(db: DatabaseConnection) -> Self { Self { db } } } #[async_trait::async_trait] impl LimitZoneService for LimitZoneServiceImpl { async fn get(&self, id: Uuid) -> ProxyServiceResult { use crate::db::entities::limit_zone; let model = limit_zone::Entity::find_by_id(id) .one(&self.db) .await? .ok_or(ProxyServiceError::ConfigNotFound)?; Ok(model.into()) } async fn list(&self) -> ProxyServiceResult> { use crate::db::entities::limit_zone; let models = limit_zone::Entity::find().all(&self.db).await?; Ok(models.into_iter().map(Into::into).collect()) } async fn create(&self, params: CreateLimitZoneParams) -> ProxyServiceResult { use crate::db::entities::limit_zone::ActiveModel; let model = ActiveModel { id: Set(Uuid::new_v4()), name: Set(params.name), key: Set(params.key), rate: Set(params.rate), override_of_id: Set(params.override_of_id), }; let result = model.insert(&self.db).await?; Ok(result.into()) } async fn update( &self, id: Uuid, params: UpdateLimitZoneParams, ) -> ProxyServiceResult { use crate::db::entities::limit_zone::{ActiveModel, Entity as LimitZoneEntity}; let existing = LimitZoneEntity::find_by_id(id) .one(&self.db) .await? .ok_or(ProxyServiceError::ConfigNotFound)?; let mut model: ActiveModel = existing.into(); if let Some(name) = params.name { model.name = Set(name); } if let Some(key) = params.key { model.key = Set(key); } if let Some(rate) = params.rate { model.rate = Set(rate); } if let Some(override_of_id) = params.override_of_id { model.override_of_id = Set(override_of_id); } let result = model.update(&self.db).await?; Ok(result.into()) } async fn delete(&self, id: Uuid) -> ProxyServiceResult { let result = crate::db::entities::limit_zone::Entity::delete_by_id(id) .exec(&self.db) .await?; Ok(result.rows_affected > 0) } }