use std::sync::Arc; use async_trait::async_trait; use dao::DaoError; use sqlx::{query, query_as, SqlitePool}; pub mod booking; pub mod sales_person; pub mod slot; pub trait ResultDbErrorExt { fn map_db_error(self) -> Result; } impl ResultDbErrorExt for Result { fn map_db_error(self) -> Result { self.map_err(|err| DaoError::DatabaseQueryError(Box::new(err))) } } pub struct HelloDaoImpl { pool: Arc, } impl HelloDaoImpl { pub fn new(pool: Arc) -> Self { Self { pool } } } #[async_trait] impl dao::HelloDao for HelloDaoImpl { async fn get_hello(&self) -> Result, dao::DaoError> { let result = query!(r"SELECT 'Hello, world!' as message") .fetch_all(self.pool.as_ref()) .await .map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))?; let message: Arc = result[0].message.clone().into(); Ok(message) } } pub struct PermissionDaoImpl { pool: Arc, } impl PermissionDaoImpl { pub fn new(pool: Arc) -> Self { Self { pool } } } #[async_trait] impl dao::PermissionDao for PermissionDaoImpl { async fn has_privilege(&self, user: &str, privilege: &str) -> Result { let result = query!( r"SELECT count(*) as results FROM user INNER JOIN user_role ON user.name = user_role.user_name INNER JOIN role ON user_role.role_name = role.name INNER JOIN role_privilege ON role.name = role_privilege.role_name WHERE role_privilege.privilege_name = ? AND user.name = ?", privilege, user, ) .fetch_all(self.pool.as_ref()) .await .map_db_error()?; Ok(result[0].results > 0) } async fn create_user(&self, user: &dao::UserEntity, process: &str) -> Result<(), DaoError> { let name = user.name.as_ref(); query!( r"INSERT INTO user (name, update_process) VALUES (?, ?)", name, process ) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn all_users(&self) -> Result, DaoError> { Ok(query_as!(dao::UserEntity, r"SELECT name FROM user") .fetch_all(self.pool.as_ref()) .await .map(Arc::<[dao::UserEntity]>::from) .map_err(|err| DaoError::DatabaseQueryError(Box::new(err)))?) } async fn delete_user(&self, username: &str) -> Result<(), DaoError> { query!(r"DELETE FROM user WHERE name = ?", username) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn find_user(&self, username: &str) -> Result, DaoError> { let result = query!(r"SELECT name FROM user WHERE name = ?", username) .fetch_optional(self.pool.as_ref()) .await .map_db_error()?; Ok(result.map(|row| dao::UserEntity { name: row.name.clone().into(), })) } async fn create_role(&self, role: &dao::RoleEntity, process: &str) -> Result<(), DaoError> { let name = role.name.as_ref(); query!( "INSERT INTO role (name, update_process) VALUES (?, ?)", name, process ) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn all_roles(&self) -> Result, DaoError> { Ok(query_as!(dao::RoleEntity, r"SELECT name FROM role") .fetch_all(self.pool.as_ref()) .await .map(Arc::<[dao::RoleEntity]>::from) .map_db_error()?) } async fn delete_role(&self, rolename: &str) -> Result<(), DaoError> { query!(r"DELETE FROM role WHERE name = ?", rolename) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn create_privilege( &self, privilege: &dao::PrivilegeEntity, process: &str, ) -> Result<(), DaoError> { let name = privilege.name.as_ref(); query!( r"INSERT INTO privilege (name, update_process) VALUES (?, ?)", name, process, ) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn all_privileges(&self) -> Result, DaoError> { Ok( query_as!(dao::PrivilegeEntity, r"SELECT name FROM privilege") .fetch_all(self.pool.as_ref()) .await .map(Arc::<[dao::PrivilegeEntity]>::from) .map_db_error()?, ) } async fn delete_privilege(&self, privilege: &str) -> Result<(), DaoError> { query!(r"DELETE FROM privilege WHERE name = ?", privilege) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn add_user_role(&self, user: &str, role: &str, process: &str) -> Result<(), DaoError> { query!( r"INSERT INTO user_role (user_name, role_name, update_process) VALUES (?, ?, ?)", user, role, process, ) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn add_role_privilege( &self, role: &str, privilege: &str, process: &str, ) -> Result<(), DaoError> { query!( r"INSERT INTO role_privilege (role_name, privilege_name, update_process) VALUES (?, ?, ?)", role, privilege, process, ).execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn delete_role_privilege(&self, role: &str, privilege: &str) -> Result<(), DaoError> { query!( r"DELETE FROM role_privilege WHERE role_name = ? AND privilege_name = ?", role, privilege ) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } async fn delete_user_role(&self, user: &str, role: &str) -> Result<(), DaoError> { query!( r"DELETE FROM user_role WHERE user_name = ? AND role_name = ?", user, role, ) .execute(self.pool.as_ref()) .await .map_db_error()?; Ok(()) } }