diff --git a/src/service/control.rs b/src/service/control.rs index b6d549f..f539ad8 100644 --- a/src/service/control.rs +++ b/src/service/control.rs @@ -2,6 +2,14 @@ use crate::model::{ControlUnit, EventRecord}; use sqlx::{PgPool, QueryBuilder, Row}; use uuid::Uuid; +fn unit_order_clause() -> &'static str { + "code" +} + +fn equipment_order_clause_with_unit() -> &'static str { + "unit_id, code" +} + #[derive(Debug, Clone)] pub struct EquipmentRolePoint { pub point_id: Uuid, @@ -35,31 +43,36 @@ pub async fn get_units_paginated( page_size: i32, offset: u32, ) -> Result, sqlx::Error> { + let unit_order = unit_order_clause(); match keyword { Some(keyword) => { let like = format!("%{}%", keyword); if page_size == -1 { - sqlx::query_as::<_, ControlUnit>( + let sql = format!( r#" SELECT * FROM unit WHERE code ILIKE $1 OR name ILIKE $1 - ORDER BY created_at + ORDER BY {} "#, - ) + unit_order + ); + sqlx::query_as::<_, ControlUnit>(&sql) .bind(like) .fetch_all(pool) .await } else { - sqlx::query_as::<_, ControlUnit>( + let sql = format!( r#" SELECT * FROM unit WHERE code ILIKE $1 OR name ILIKE $1 - ORDER BY created_at + ORDER BY {} LIMIT $2 OFFSET $3 "#, - ) + unit_order + ); + sqlx::query_as::<_, ControlUnit>(&sql) .bind(like) .bind(page_size as i64) .bind(offset as i64) @@ -69,18 +82,21 @@ pub async fn get_units_paginated( } None => { if page_size == -1 { - sqlx::query_as::<_, ControlUnit>(r#"SELECT * FROM unit ORDER BY created_at"#) + let sql = format!("SELECT * FROM unit ORDER BY {}", unit_order); + sqlx::query_as::<_, ControlUnit>(&sql) .fetch_all(pool) .await } else { - sqlx::query_as::<_, ControlUnit>( + let sql = format!( r#" SELECT * FROM unit - ORDER BY created_at + ORDER BY {} LIMIT $1 OFFSET $2 "#, - ) + unit_order + ); + sqlx::query_as::<_, ControlUnit>(&sql) .bind(page_size as i64) .bind(offset as i64) .fetch_all(pool) @@ -309,9 +325,11 @@ pub async fn get_events_paginated( } pub async fn get_all_enabled_units(pool: &PgPool) -> Result, sqlx::Error> { - sqlx::query_as::<_, ControlUnit>( - r#"SELECT * FROM unit WHERE enabled = TRUE ORDER BY created_at"#, - ) + let sql = format!( + "SELECT * FROM unit WHERE enabled = TRUE ORDER BY {}", + unit_order_clause() + ); + sqlx::query_as::<_, ControlUnit>(&sql) .fetch_all(pool) .await } @@ -323,9 +341,11 @@ pub async fn get_equipment_by_unit_ids( if unit_ids.is_empty() { return Ok(vec![]); } - sqlx::query_as::<_, crate::model::Equipment>( - r#"SELECT * FROM equipment WHERE unit_id = ANY($1) ORDER BY unit_id, created_at"#, - ) + let sql = format!( + "SELECT * FROM equipment WHERE unit_id = ANY($1) ORDER BY {}", + equipment_order_clause_with_unit() + ); + sqlx::query_as::<_, crate::model::Equipment>(&sql) .bind(unit_ids) .fetch_all(pool) .await @@ -335,9 +355,11 @@ pub async fn get_equipment_by_unit_id( pool: &PgPool, unit_id: Uuid, ) -> Result, sqlx::Error> { - sqlx::query_as::<_, crate::model::Equipment>( - r#"SELECT * FROM equipment WHERE unit_id = $1 ORDER BY created_at"#, - ) + let sql = format!( + "SELECT * FROM equipment WHERE unit_id = $1 ORDER BY {}", + unit_order_clause() + ); + sqlx::query_as::<_, crate::model::Equipment>(&sql) .bind(unit_id) .fetch_all(pool) .await @@ -395,6 +417,21 @@ pub async fn get_signal_role_points_batch( .collect()) } +#[cfg(test)] +mod tests { + use super::{equipment_order_clause_with_unit, unit_order_clause}; + + #[test] + fn unit_ordering_defaults_to_code() { + assert_eq!(unit_order_clause(), "code"); + } + + #[test] + fn unit_equipment_ordering_uses_code_within_unit() { + assert_eq!(equipment_order_clause_with_unit(), "unit_id, code"); + } +} + pub async fn get_equipment_role_points( pool: &PgPool, equipment_id: Uuid, diff --git a/src/service/equipment.rs b/src/service/equipment.rs index a1d6045..6cb31c7 100644 --- a/src/service/equipment.rs +++ b/src/service/equipment.rs @@ -5,6 +5,10 @@ use crate::{ use sqlx::{query_as, PgPool, Row}; use uuid::Uuid; +fn equipment_order_clause() -> &'static str { + "e.code" +} + pub async fn get_points_by_equipment_id( pool: &PgPool, equipment_id: uuid::Uuid, @@ -49,11 +53,12 @@ pub async fn get_equipment_paginated( page_size: i32, offset: u32, ) -> Result, sqlx::Error> { + let equipment_order = equipment_order_clause(); let rows = match keyword { Some(keyword) => { let like = format!("%{}%", keyword); if page_size == -1 { - sqlx::query( + let sql = format!( r#" SELECT e.*, @@ -62,14 +67,16 @@ pub async fn get_equipment_paginated( LEFT JOIN point p ON p.equipment_id = e.id WHERE e.code ILIKE $1 OR e.name ILIKE $1 GROUP BY e.id - ORDER BY e.created_at + ORDER BY {} "#, - ) + equipment_order + ); + sqlx::query(&sql) .bind(like) .fetch_all(pool) .await? } else { - sqlx::query( + let sql = format!( r#" SELECT e.*, @@ -78,10 +85,12 @@ pub async fn get_equipment_paginated( LEFT JOIN point p ON p.equipment_id = e.id WHERE e.code ILIKE $1 OR e.name ILIKE $1 GROUP BY e.id - ORDER BY e.created_at + ORDER BY {} LIMIT $2 OFFSET $3 "#, - ) + equipment_order + ); + sqlx::query(&sql) .bind(like) .bind(page_size as i64) .bind(offset as i64) @@ -91,7 +100,7 @@ pub async fn get_equipment_paginated( } None => { if page_size == -1 { - sqlx::query( + let sql = format!( r#" SELECT e.*, @@ -99,13 +108,15 @@ pub async fn get_equipment_paginated( FROM equipment e LEFT JOIN point p ON p.equipment_id = e.id GROUP BY e.id - ORDER BY e.created_at + ORDER BY {} "#, - ) + equipment_order + ); + sqlx::query(&sql) .fetch_all(pool) .await? } else { - sqlx::query( + let sql = format!( r#" SELECT e.*, @@ -113,10 +124,12 @@ pub async fn get_equipment_paginated( FROM equipment e LEFT JOIN point p ON p.equipment_id = e.id GROUP BY e.id - ORDER BY e.created_at + ORDER BY {} LIMIT $1 OFFSET $2 "#, - ) + equipment_order + ); + sqlx::query(&sql) .bind(page_size as i64) .bind(offset as i64) .fetch_all(pool) @@ -284,3 +297,13 @@ pub async fn batch_set_equipment_unit( Ok(result.rows_affected()) } + +#[cfg(test)] +mod tests { + use super::equipment_order_clause; + + #[test] + fn equipment_ordering_defaults_to_code() { + assert_eq!(equipment_order_clause(), "e.code"); + } +}