195 lines
5.1 KiB
Rust
195 lines
5.1 KiB
Rust
use sqlx::PgPool;
|
|
use uuid::Uuid;
|
|
|
|
use crate::model::{Station, StationSignal};
|
|
|
|
pub async fn list_stations(
|
|
pool: &PgPool,
|
|
line_code: Option<&str>,
|
|
) -> Result<Vec<Station>, sqlx::Error> {
|
|
match line_code {
|
|
Some(line) => {
|
|
sqlx::query_as::<_, Station>(
|
|
r#"SELECT * FROM station WHERE line_code = $1 ORDER BY code"#,
|
|
)
|
|
.bind(line)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
None => {
|
|
sqlx::query_as::<_, Station>(r#"SELECT * FROM station ORDER BY code"#)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn get_station_by_id(
|
|
pool: &PgPool,
|
|
station_id: Uuid,
|
|
) -> Result<Option<Station>, sqlx::Error> {
|
|
sqlx::query_as::<_, Station>(r#"SELECT * FROM station WHERE id = $1"#)
|
|
.bind(station_id)
|
|
.fetch_optional(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_station_by_code(
|
|
pool: &PgPool,
|
|
code: &str,
|
|
) -> Result<Option<Station>, sqlx::Error> {
|
|
sqlx::query_as::<_, Station>(r#"SELECT * FROM station WHERE code = $1"#)
|
|
.bind(code)
|
|
.fetch_optional(pool)
|
|
.await
|
|
}
|
|
|
|
pub struct CreateStationParams<'a> {
|
|
pub code: &'a str,
|
|
pub name: &'a str,
|
|
pub line_code: Option<&'a str>,
|
|
pub segment_code: Option<&'a str>,
|
|
pub station_type: &'a str,
|
|
pub enabled: bool,
|
|
pub description: Option<&'a str>,
|
|
}
|
|
|
|
pub async fn create_station(
|
|
pool: &PgPool,
|
|
params: CreateStationParams<'_>,
|
|
) -> Result<Uuid, sqlx::Error> {
|
|
let station_id = Uuid::new_v4();
|
|
sqlx::query(
|
|
r#"
|
|
INSERT INTO station (
|
|
id, code, name, line_code, segment_code, station_type, enabled, description
|
|
)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
"#,
|
|
)
|
|
.bind(station_id)
|
|
.bind(params.code)
|
|
.bind(params.name)
|
|
.bind(params.line_code)
|
|
.bind(params.segment_code)
|
|
.bind(params.station_type)
|
|
.bind(params.enabled)
|
|
.bind(params.description)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
Ok(station_id)
|
|
}
|
|
|
|
pub struct UpdateStationParams<'a> {
|
|
pub code: Option<&'a str>,
|
|
pub name: Option<&'a str>,
|
|
pub line_code: Option<&'a str>,
|
|
pub segment_code: Option<&'a str>,
|
|
pub station_type: Option<&'a str>,
|
|
pub enabled: Option<bool>,
|
|
pub description: Option<&'a str>,
|
|
}
|
|
|
|
pub async fn update_station(
|
|
pool: &PgPool,
|
|
station_id: Uuid,
|
|
params: UpdateStationParams<'_>,
|
|
) -> Result<bool, sqlx::Error> {
|
|
let result = sqlx::query(
|
|
r#"
|
|
UPDATE station SET
|
|
code = COALESCE($2, code),
|
|
name = COALESCE($3, name),
|
|
line_code = COALESCE($4, line_code),
|
|
segment_code = COALESCE($5, segment_code),
|
|
station_type = COALESCE($6, station_type),
|
|
enabled = COALESCE($7, enabled),
|
|
description = COALESCE($8, description),
|
|
updated_at = NOW()
|
|
WHERE id = $1
|
|
"#,
|
|
)
|
|
.bind(station_id)
|
|
.bind(params.code)
|
|
.bind(params.name)
|
|
.bind(params.line_code)
|
|
.bind(params.segment_code)
|
|
.bind(params.station_type)
|
|
.bind(params.enabled)
|
|
.bind(params.description)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
Ok(result.rows_affected() > 0)
|
|
}
|
|
|
|
pub async fn delete_station(pool: &PgPool, station_id: Uuid) -> Result<bool, sqlx::Error> {
|
|
let result = sqlx::query(r#"DELETE FROM station WHERE id = $1"#)
|
|
.bind(station_id)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(result.rows_affected() > 0)
|
|
}
|
|
|
|
pub async fn list_station_signals(
|
|
pool: &PgPool,
|
|
station_id: Uuid,
|
|
) -> Result<Vec<StationSignal>, sqlx::Error> {
|
|
sqlx::query_as::<_, StationSignal>(
|
|
r#"SELECT * FROM station_signal WHERE station_id = $1 ORDER BY signal_role"#,
|
|
)
|
|
.bind(station_id)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
|
|
pub struct UpsertStationSignalParams {
|
|
pub signal_role: String,
|
|
pub point_id: Option<Uuid>,
|
|
pub derived_from_role: Option<String>,
|
|
pub invert_value: bool,
|
|
}
|
|
|
|
pub async fn upsert_station_signal(
|
|
pool: &PgPool,
|
|
station_id: Uuid,
|
|
params: UpsertStationSignalParams,
|
|
) -> Result<StationSignal, sqlx::Error> {
|
|
sqlx::query_as::<_, StationSignal>(
|
|
r#"
|
|
INSERT INTO station_signal (
|
|
station_id, signal_role, point_id, derived_from_role, invert_value
|
|
)
|
|
VALUES ($1, $2, $3, $4, $5)
|
|
ON CONFLICT (station_id, signal_role) DO UPDATE SET
|
|
point_id = EXCLUDED.point_id,
|
|
derived_from_role = EXCLUDED.derived_from_role,
|
|
invert_value = EXCLUDED.invert_value,
|
|
updated_at = NOW()
|
|
RETURNING *
|
|
"#,
|
|
)
|
|
.bind(station_id)
|
|
.bind(¶ms.signal_role)
|
|
.bind(params.point_id)
|
|
.bind(¶ms.derived_from_role)
|
|
.bind(params.invert_value)
|
|
.fetch_one(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn delete_station_signal(
|
|
pool: &PgPool,
|
|
station_id: Uuid,
|
|
signal_role: &str,
|
|
) -> Result<bool, sqlx::Error> {
|
|
let result =
|
|
sqlx::query(r#"DELETE FROM station_signal WHERE station_id = $1 AND signal_role = $2"#)
|
|
.bind(station_id)
|
|
.bind(signal_role)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(result.rows_affected() > 0)
|
|
}
|