use serde_derive::Serialize; use std::ops::DerefMut; use sqlx::pool::PoolConnection; use sqlx::Sqlite; use crate::db::errors::DatabaseError; use crate::db::DbTag; use crate::types::ControllerUid; #[derive(Debug, Serialize, Clone)] pub struct DbController { pub id: i64, pub uid: ControllerUid, pub name: String, pub relay_count: i64, pub active: bool, } impl DbController { pub async fn get_all( conn: &mut PoolConnection<Sqlite>, ) -> Result<Vec<DbController>, DatabaseError> { Ok(sqlx::query_as!(DbController, "SELECT * FROM controllers") .fetch_all(conn.deref_mut()) .await?) } pub async fn get( conn: &mut PoolConnection<Sqlite>, id: i64, ) -> Result<DbController, DatabaseError> { sqlx::query_as!(DbController, "SELECT * FROM controllers WHERE id = ?", id) .fetch_optional(conn.deref_mut()) .await .map(|s| s.ok_or(DatabaseError::NotFound))? } pub async fn get_by_uid( conn: &mut PoolConnection<Sqlite>, filter_uid: &ControllerUid, ) -> Result<DbController, DatabaseError> { sqlx::query_as!( DbController, "SELECT * FROM controllers WHERE uid = ?", filter_uid ) .fetch_optional(conn.deref_mut()) .await .map(|s| s.ok_or(DatabaseError::NotFound))? } pub async fn get_by_tag( conn: &mut PoolConnection<Sqlite>, tag: &DbTag, ) -> Result<Vec<DbController>, DatabaseError> { Ok(sqlx::query_as!(DbController, "SELECT schedule.* FROM controllers AS schedule INNER JOIN junction_tag ON junction_tag.schedule_id = schedule.id WHERE junction_tag.tag_id = ?", tag.id) .fetch_all(conn.deref_mut()) .await?) } pub async fn delete_by_uid( conn: &mut PoolConnection<Sqlite>, filter_uid: ControllerUid, ) -> Result<(), DatabaseError> { sqlx::query!("DELETE FROM controllers WHERE uid = ?", filter_uid) .execute(conn.deref_mut()) .await .map(|res| match res.rows_affected() { 0 => Err(DatabaseError::DeleteError), _ => Ok(()), })? } pub async fn create( conn: &mut PoolConnection<Sqlite>, new_uid: &ControllerUid, new_name: &str, new_relay_count: i64, new_active: bool, ) -> Result<DbController, DatabaseError> { sqlx::query_as!( DbController, "INSERT INTO controllers (uid, name, relay_count, active) VALUES (?, ?, ?, ?) RETURNING *", new_uid, new_name, new_relay_count, new_active, ) .fetch_optional(conn.deref_mut()) .await? .ok_or(DatabaseError::InsertGetError) } pub async fn update( &self, conn: &mut PoolConnection<Sqlite>, new_name: &str, new_relay_count: i64, new_active: bool, ) -> Result<DbController, DatabaseError> { sqlx::query!( "UPDATE controllers SET name = ?, relay_count = ?, active = ? WHERE id = ?", new_name, new_relay_count, new_active, self.id, ) .execute(conn.deref_mut()) .await?; Self::get(conn, self.id).await } }