304 lines
8.4 KiB
Rust
304 lines
8.4 KiB
Rust
use crate::model::{ControlUnit, EventRecord};
|
|
use sqlx::{PgPool, QueryBuilder};
|
|
use uuid::Uuid;
|
|
|
|
pub async fn get_units_count(pool: &PgPool, keyword: Option<&str>) -> Result<i64, sqlx::Error> {
|
|
match keyword {
|
|
Some(keyword) => {
|
|
let like = format!("%{}%", keyword);
|
|
sqlx::query_scalar::<_, i64>(
|
|
r#"
|
|
SELECT COUNT(*)
|
|
FROM unit
|
|
WHERE code ILIKE $1 OR name ILIKE $1
|
|
"#,
|
|
)
|
|
.bind(like)
|
|
.fetch_one(pool)
|
|
.await
|
|
}
|
|
None => sqlx::query_scalar::<_, i64>(r#"SELECT COUNT(*) FROM unit"#)
|
|
.fetch_one(pool)
|
|
.await,
|
|
}
|
|
}
|
|
|
|
pub async fn get_units_paginated(
|
|
pool: &PgPool,
|
|
keyword: Option<&str>,
|
|
page_size: i32,
|
|
offset: u32,
|
|
) -> Result<Vec<ControlUnit>, sqlx::Error> {
|
|
match keyword {
|
|
Some(keyword) => {
|
|
let like = format!("%{}%", keyword);
|
|
if page_size == -1 {
|
|
sqlx::query_as::<_, ControlUnit>(
|
|
r#"
|
|
SELECT *
|
|
FROM unit
|
|
WHERE code ILIKE $1 OR name ILIKE $1
|
|
ORDER BY created_at
|
|
"#,
|
|
)
|
|
.bind(like)
|
|
.fetch_all(pool)
|
|
.await
|
|
} else {
|
|
sqlx::query_as::<_, ControlUnit>(
|
|
r#"
|
|
SELECT *
|
|
FROM unit
|
|
WHERE code ILIKE $1 OR name ILIKE $1
|
|
ORDER BY created_at
|
|
LIMIT $2 OFFSET $3
|
|
"#,
|
|
)
|
|
.bind(like)
|
|
.bind(page_size as i64)
|
|
.bind(offset as i64)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
}
|
|
None => {
|
|
if page_size == -1 {
|
|
sqlx::query_as::<_, ControlUnit>(r#"SELECT * FROM unit ORDER BY created_at"#)
|
|
.fetch_all(pool)
|
|
.await
|
|
} else {
|
|
sqlx::query_as::<_, ControlUnit>(
|
|
r#"
|
|
SELECT *
|
|
FROM unit
|
|
ORDER BY created_at
|
|
LIMIT $1 OFFSET $2
|
|
"#,
|
|
)
|
|
.bind(page_size as i64)
|
|
.bind(offset as i64)
|
|
.fetch_all(pool)
|
|
.await
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn get_unit_by_id(
|
|
pool: &PgPool,
|
|
unit_id: Uuid,
|
|
) -> Result<Option<ControlUnit>, sqlx::Error> {
|
|
sqlx::query_as::<_, ControlUnit>(r#"SELECT * FROM unit WHERE id = $1"#)
|
|
.bind(unit_id)
|
|
.fetch_optional(pool)
|
|
.await
|
|
}
|
|
|
|
pub async fn get_unit_by_code(
|
|
pool: &PgPool,
|
|
code: &str,
|
|
) -> Result<Option<ControlUnit>, sqlx::Error> {
|
|
sqlx::query_as::<_, ControlUnit>(r#"SELECT * FROM unit WHERE code = $1"#)
|
|
.bind(code)
|
|
.fetch_optional(pool)
|
|
.await
|
|
}
|
|
|
|
pub struct CreateUnitParams<'a> {
|
|
pub code: &'a str,
|
|
pub name: &'a str,
|
|
pub description: Option<&'a str>,
|
|
pub enabled: bool,
|
|
pub run_time_sec: i32,
|
|
pub stop_time_sec: i32,
|
|
pub acc_time_sec: i32,
|
|
pub bl_time_sec: i32,
|
|
pub require_manual_ack_after_fault: bool,
|
|
}
|
|
|
|
pub async fn create_unit(
|
|
pool: &PgPool,
|
|
params: CreateUnitParams<'_>,
|
|
) -> Result<Uuid, sqlx::Error> {
|
|
let unit_id = Uuid::new_v4();
|
|
sqlx::query(
|
|
r#"
|
|
INSERT INTO unit (
|
|
id, code, name, description, enabled,
|
|
run_time_sec, stop_time_sec, acc_time_sec, bl_time_sec,
|
|
require_manual_ack_after_fault
|
|
)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
|
"#,
|
|
)
|
|
.bind(unit_id)
|
|
.bind(params.code)
|
|
.bind(params.name)
|
|
.bind(params.description)
|
|
.bind(params.enabled)
|
|
.bind(params.run_time_sec)
|
|
.bind(params.stop_time_sec)
|
|
.bind(params.acc_time_sec)
|
|
.bind(params.bl_time_sec)
|
|
.bind(params.require_manual_ack_after_fault)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
Ok(unit_id)
|
|
}
|
|
|
|
pub struct UpdateUnitParams<'a> {
|
|
pub code: Option<&'a str>,
|
|
pub name: Option<&'a str>,
|
|
pub description: Option<&'a str>,
|
|
pub enabled: Option<bool>,
|
|
pub run_time_sec: Option<i32>,
|
|
pub stop_time_sec: Option<i32>,
|
|
pub acc_time_sec: Option<i32>,
|
|
pub bl_time_sec: Option<i32>,
|
|
pub require_manual_ack_after_fault: Option<bool>,
|
|
}
|
|
|
|
pub async fn update_unit(
|
|
pool: &PgPool,
|
|
unit_id: Uuid,
|
|
params: UpdateUnitParams<'_>,
|
|
) -> Result<(), sqlx::Error> {
|
|
let mut updates = Vec::new();
|
|
let mut param_count = 1;
|
|
|
|
if params.code.is_some() {
|
|
updates.push(format!("code = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.name.is_some() {
|
|
updates.push(format!("name = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.description.is_some() {
|
|
updates.push(format!("description = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.enabled.is_some() {
|
|
updates.push(format!("enabled = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.run_time_sec.is_some() {
|
|
updates.push(format!("run_time_sec = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.stop_time_sec.is_some() {
|
|
updates.push(format!("stop_time_sec = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.acc_time_sec.is_some() {
|
|
updates.push(format!("acc_time_sec = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.bl_time_sec.is_some() {
|
|
updates.push(format!("bl_time_sec = ${}", param_count));
|
|
param_count += 1;
|
|
}
|
|
if params.require_manual_ack_after_fault.is_some() {
|
|
updates.push(format!(
|
|
"require_manual_ack_after_fault = ${}",
|
|
param_count
|
|
));
|
|
param_count += 1;
|
|
}
|
|
|
|
updates.push("updated_at = NOW()".to_string());
|
|
|
|
let sql = format!(
|
|
r#"UPDATE unit SET {} WHERE id = ${}"#,
|
|
updates.join(", "),
|
|
param_count
|
|
);
|
|
|
|
let mut query = sqlx::query(&sql);
|
|
|
|
if let Some(code) = params.code {
|
|
query = query.bind(code);
|
|
}
|
|
if let Some(name) = params.name {
|
|
query = query.bind(name);
|
|
}
|
|
if let Some(description) = params.description {
|
|
query = query.bind(description);
|
|
}
|
|
if let Some(enabled) = params.enabled {
|
|
query = query.bind(enabled);
|
|
}
|
|
if let Some(run_time_sec) = params.run_time_sec {
|
|
query = query.bind(run_time_sec);
|
|
}
|
|
if let Some(stop_time_sec) = params.stop_time_sec {
|
|
query = query.bind(stop_time_sec);
|
|
}
|
|
if let Some(acc_time_sec) = params.acc_time_sec {
|
|
query = query.bind(acc_time_sec);
|
|
}
|
|
if let Some(bl_time_sec) = params.bl_time_sec {
|
|
query = query.bind(bl_time_sec);
|
|
}
|
|
if let Some(require_manual_ack_after_fault) = params.require_manual_ack_after_fault {
|
|
query = query.bind(require_manual_ack_after_fault);
|
|
}
|
|
|
|
query.bind(unit_id).execute(pool).await?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn delete_unit(pool: &PgPool, unit_id: Uuid) -> Result<bool, sqlx::Error> {
|
|
let result = sqlx::query(r#"DELETE FROM unit WHERE id = $1"#)
|
|
.bind(unit_id)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
Ok(result.rows_affected() > 0)
|
|
}
|
|
|
|
pub async fn get_events_count(
|
|
pool: &PgPool,
|
|
unit_id: Option<Uuid>,
|
|
event_type: Option<&str>,
|
|
) -> Result<i64, sqlx::Error> {
|
|
let mut qb =
|
|
QueryBuilder::new("SELECT COUNT(*)::BIGINT FROM event WHERE 1 = 1");
|
|
|
|
if let Some(unit_id) = unit_id {
|
|
qb.push(" AND unit_id = ").push_bind(unit_id);
|
|
}
|
|
if let Some(event_type) = event_type {
|
|
qb.push(" AND event_type = ").push_bind(event_type);
|
|
}
|
|
|
|
qb.build_query_scalar().fetch_one(pool).await
|
|
}
|
|
|
|
pub async fn get_events_paginated(
|
|
pool: &PgPool,
|
|
unit_id: Option<Uuid>,
|
|
event_type: Option<&str>,
|
|
page_size: i32,
|
|
offset: u32,
|
|
) -> Result<Vec<EventRecord>, sqlx::Error> {
|
|
let mut qb = QueryBuilder::new("SELECT * FROM event WHERE 1 = 1");
|
|
|
|
if let Some(unit_id) = unit_id {
|
|
qb.push(" AND unit_id = ").push_bind(unit_id);
|
|
}
|
|
if let Some(event_type) = event_type {
|
|
qb.push(" AND event_type = ").push_bind(event_type);
|
|
}
|
|
|
|
qb.push(" ORDER BY created_at DESC");
|
|
|
|
if page_size != -1 {
|
|
qb.push(" LIMIT ").push_bind(page_size as i64);
|
|
qb.push(" OFFSET ").push_bind(offset as i64);
|
|
}
|
|
|
|
qb.build_query_as::<EventRecord>().fetch_all(pool).await
|
|
}
|