diff --git a/src/handler/point.rs b/src/handler/point.rs index 5de31ad..5ba5385 100644 --- a/src/handler/point.rs +++ b/src/handler/point.rs @@ -5,6 +5,7 @@ use axum::{ Json, }; use serde::{Deserialize, Serialize}; +use serde_with::rust::double_option; use sqlx::{QueryBuilder, Row}; use std::collections::{HashMap, HashSet}; use uuid::Uuid; @@ -145,11 +146,16 @@ pub async fn get_point_history( #[derive(Deserialize, Validate)] pub struct UpdatePointReq { pub name: Option, - pub description: Option, - pub unit: Option, - pub tag_id: Option, - pub equipment_id: Option, - pub signal_role: Option, + #[serde(default, with = "double_option")] + pub description: Option>, + #[serde(default, with = "double_option")] + pub unit: Option>, + #[serde(default, with = "double_option")] + pub tag_id: Option>, + #[serde(default, with = "double_option")] + pub equipment_id: Option>, + #[serde(default, with = "double_option")] + pub signal_role: Option>, } /// Request payload for batch setting point tags. @@ -187,7 +193,7 @@ pub async fn update_point( } // If tag_id is provided, ensure tag exists. - if let Some(tag_id) = payload.tag_id { + if let Some(Some(tag_id)) = payload.tag_id { let tag_exists = sqlx::query(r#"SELECT 1 FROM tag WHERE id = $1"#) .bind(tag_id) .fetch_optional(pool) @@ -199,7 +205,7 @@ pub async fn update_point( } } - if let Some(equipment_id) = payload.equipment_id { + if let Some(Some(equipment_id)) = payload.equipment_id { let equipment_exists = sqlx::query(r#"SELECT 1 FROM equipment WHERE id = $1"#) .bind(equipment_id) .fetch_optional(pool) @@ -220,29 +226,56 @@ pub async fn update_point( return Err(ApiErr::NotFound("Point not found".to_string(), None)); } - let mut qb = QueryBuilder::new("UPDATE point SET "); - let mut sep = qb.separated(", "); + let mut qb: QueryBuilder = QueryBuilder::new("UPDATE point SET "); + let mut wrote_field = false; if let Some(name) = &payload.name { - sep.push("name = ").push_bind(name); + if wrote_field { + qb.push(", "); + } + qb.push("name = ").push_bind(name); + wrote_field = true; } if let Some(description) = &payload.description { - sep.push("description = ").push_bind(description); + if wrote_field { + qb.push(", "); + } + qb.push("description = ").push_bind(description.as_deref()); + wrote_field = true; } if let Some(unit) = &payload.unit { - sep.push("unit = ").push_bind(unit); + if wrote_field { + qb.push(", "); + } + qb.push("unit = ").push_bind(unit.as_deref()); + wrote_field = true; } if let Some(tag_id) = &payload.tag_id { - sep.push("tag_id = ").push_bind(tag_id); + if wrote_field { + qb.push(", "); + } + qb.push("tag_id = ").push_bind(tag_id.as_ref()); + wrote_field = true; } if let Some(equipment_id) = &payload.equipment_id { - sep.push("equipment_id = ").push_bind(equipment_id); + if wrote_field { + qb.push(", "); + } + qb.push("equipment_id = ").push_bind(equipment_id.as_ref()); + wrote_field = true; } if let Some(signal_role) = &payload.signal_role { - sep.push("signal_role = ").push_bind(signal_role); + if wrote_field { + qb.push(", "); + } + qb.push("signal_role = ").push_bind(signal_role.as_deref()); + wrote_field = true; } - sep.push("updated_at = NOW()"); + if wrote_field { + qb.push(", "); + } + qb.push("updated_at = NOW()"); qb.push(" WHERE id = ").push_bind(point_id); qb.build().execute(pool).await?;