common/src/db/junction_relay_schedule.rs

146 lines
3.8 KiB
Rust

use std::ops::DerefMut;
use sqlx::pool::PoolConnection;
use sqlx::Sqlite;
use crate::db::{DbRelay, DbSchedule};
use crate::errors::DatabaseError;
use crate::types::Weekday;
pub struct DbJunctionRelaySchedule {
pub id: i64,
pub weekday: Weekday,
pub relay_id: i64,
pub schedule_id: i64,
}
impl DbJunctionRelaySchedule {
pub async fn get(
conn: &mut PoolConnection<Sqlite>,
id: i64,
) -> Result<Option<DbJunctionRelaySchedule>, DatabaseError> {
sqlx::query_as!(
DbJunctionRelaySchedule,
"SELECT * FROM junction_relay_schedule WHERE id = ?",
id
)
.fetch_optional(conn.deref_mut())
.await
.map_err(DatabaseError::from)
}
pub async fn get_junction_by_relay_and_weekday(
conn: &mut PoolConnection<Sqlite>,
relay: &DbRelay,
weekday: Weekday,
) -> Result<Option<DbJunctionRelaySchedule>, DatabaseError> {
sqlx::query_as!(
DbJunctionRelaySchedule,
"SELECT * FROM junction_relay_schedule WHERE relay_id = ? AND weekday = ?",
relay.id,
weekday
)
.fetch_optional(conn.deref_mut())
.await
.map_err(DatabaseError::from)
}
pub async fn get_relays(
conn: &mut PoolConnection<Sqlite>,
schedule: &DbSchedule,
) -> Result<Vec<DbRelay>, DatabaseError> {
sqlx::query_as!(
DbRelay,
r#"SELECT relays.* FROM relays INNER JOIN junction_relay_schedule
ON junction_relay_schedule.relay_id = relays.id
WHERE junction_relay_schedule.schedule_id = ?
ORDER BY junction_relay_schedule.weekday"#,
schedule.id
)
.fetch_all(conn.deref_mut())
.await
.map_err(DatabaseError::from)
}
pub async fn get_schedule(
conn: &mut PoolConnection<Sqlite>,
relay: &DbRelay,
weekday: Weekday,
) -> Result<Option<DbSchedule>, DatabaseError> {
sqlx::query_as!(
DbSchedule,
r#"SELECT schedules.* FROM schedules INNER JOIN junction_relay_schedule
ON junction_relay_schedule.schedule_id = schedules.id
WHERE junction_relay_schedule.relay_id = ? AND junction_relay_schedule.weekday = ?"#,
relay.id,
weekday
)
.fetch_optional(conn.deref_mut())
.await
.map_err(DatabaseError::from)
}
pub async fn get_schedules(
conn: &mut PoolConnection<Sqlite>,
relay: &DbRelay,
) -> Result<Vec<DbSchedule>, DatabaseError> {
sqlx::query_as!(
DbSchedule,
r#"SELECT schedules.* FROM schedules INNER JOIN junction_relay_schedule
ON junction_relay_schedule.schedule_id = schedules.id
WHERE junction_relay_schedule.relay_id = ?
ORDER BY junction_relay_schedule.weekday"#,
relay.id
)
.fetch_all(conn.deref_mut())
.await
.map_err(DatabaseError::from)
}
pub async fn set_schedule(
conn: &mut PoolConnection<Sqlite>,
relay: &DbRelay,
schedule: &DbSchedule,
weekday: Weekday,
) -> Result<DbJunctionRelaySchedule, DatabaseError> {
match Self::get_junction_by_relay_and_weekday(conn, relay, weekday).await? {
None => sqlx::query_as!(
DbJunctionRelaySchedule,
"INSERT INTO junction_relay_schedule (weekday, relay_id, schedule_id) VALUES (?, ?, ?) RETURNING *",
weekday,
relay.id,
schedule.id
)
.fetch_optional(conn.deref_mut())
.await?
.ok_or(DatabaseError::InsertGetError),
Some(junction) => {
sqlx::query!(
"UPDATE junction_relay_schedule SET weekday = ?, relay_id = ?, schedule_id= ? WHERE id = ?",
weekday,
relay.id,
schedule.id,
junction.id
)
.execute(conn.deref_mut())
.await?;
Self::get(conn, junction.id)
.await?
.ok_or(DatabaseError::UpdateGetError)
}
}
}
pub async fn set_schedules(
conn: &mut PoolConnection<Sqlite>,
relay: &DbRelay,
schedules: Vec<&DbSchedule>,
) -> Result<(), DatabaseError> {
for (weekday, schedule) in schedules.iter().enumerate() {
Self::set_schedule(conn, relay, schedule, weekday as Weekday).await?;
}
Ok(())
}
}