use crate::{
database::{validators, ThingsDatabase},
error::{Result as ThingsResult, ThingsError},
models::ThingsId,
};
use chrono::Utc;
use tracing::{info, instrument};
impl ThingsDatabase {
#[instrument(skip(self))]
pub async fn create_area(
&self,
request: crate::models::CreateAreaRequest,
) -> ThingsResult<ThingsId> {
let id = ThingsId::new_things_native();
let now = Utc::now().timestamp() as f64;
let max_index: Option<i64> = sqlx::query_scalar("SELECT MAX(`index`) FROM TMArea")
.fetch_one(&self.pool)
.await
.map_err(|e| ThingsError::unknown(format!("Failed to get max area index: {e}")))?;
let next_index = max_index.unwrap_or(-1) + 1;
sqlx::query(
r"
INSERT INTO TMArea (
uuid, title, visible, `index`,
creationDate, userModificationDate
) VALUES (?, ?, 1, ?, ?, ?)
",
)
.bind(id.as_str())
.bind(&request.title)
.bind(next_index)
.bind(now)
.bind(now)
.execute(&self.pool)
.await
.map_err(|e| ThingsError::unknown(format!("Failed to create area: {e}")))?;
info!("Created area with UUID: {}", id);
Ok(id)
}
#[instrument(skip(self))]
pub async fn update_area(&self, request: crate::models::UpdateAreaRequest) -> ThingsResult<()> {
validators::validate_area_exists(&self.pool, &request.uuid).await?;
let now = Utc::now().timestamp() as f64;
sqlx::query("UPDATE TMArea SET title = ?, userModificationDate = ? WHERE uuid = ?")
.bind(&request.title)
.bind(now)
.bind(request.uuid.as_str())
.execute(&self.pool)
.await
.map_err(|e| ThingsError::unknown(format!("Failed to update area: {e}")))?;
info!("Updated area with UUID: {}", request.uuid);
Ok(())
}
#[instrument(skip(self))]
pub async fn delete_area(&self, id: &ThingsId) -> ThingsResult<()> {
validators::validate_area_exists(&self.pool, id).await?;
let now = Utc::now().timestamp() as f64;
sqlx::query(
"UPDATE TMTask SET area = NULL, userModificationDate = ? WHERE area = ? AND type = 1 AND trashed = 0",
)
.bind(now)
.bind(id.as_str())
.execute(&self.pool)
.await
.map_err(|e| ThingsError::unknown(format!("Failed to orphan projects in area: {e}")))?;
sqlx::query("DELETE FROM TMArea WHERE uuid = ?")
.bind(id.as_str())
.execute(&self.pool)
.await
.map_err(|e| ThingsError::unknown(format!("Failed to delete area: {e}")))?;
info!("Deleted area with UUID: {}", id);
Ok(())
}
}