use derive_builder::Builder; use sqlx::query_as; use uuid::Uuid; use crate::client::AppDbClient; #[derive(Clone, Debug)] pub struct Base { pub id: Uuid, pub name: String, pub url: String, pub owner_id: Uuid, pub user_role_prefix: String, } impl Base { pub fn insertable_builder() -> InsertableBaseBuilder { InsertableBaseBuilder::default() } pub fn with_id(id: Uuid) -> WithIdQuery { WithIdQuery { id } } pub fn with_permission_in>( perms: I, ) -> WithPermissionInQueryPartial { let perms: Vec = perms.into_iter().map(ToOwned::to_owned).collect(); WithPermissionInQueryPartial { perms } } } pub struct WithPermissionInQueryPartial { perms: Vec, } impl WithPermissionInQueryPartial { pub fn for_user(self, user_id: Uuid) -> WithPermissionInQuery { WithPermissionInQuery { perms: self.perms, user_id, } } } pub struct WithPermissionInQuery { perms: Vec, user_id: Uuid, } impl WithPermissionInQuery { pub async fn fetch_all(self, app_db: &mut AppDbClient) -> Result, sqlx::Error> { query_as!( Base, " select bases.* from bases inner join base_user_perms as p on p.base_id = bases.id where p.user_id = $1 and perm = ANY($2) ", self.user_id, self.perms.as_slice(), ) .fetch_all(&mut *app_db.conn) .await } } pub struct WithIdQuery { id: Uuid, } impl WithIdQuery { pub async fn fetch_optional( self, app_db: &mut AppDbClient, ) -> Result, sqlx::Error> { query_as!(Base, "select * from bases where id = $1", &self.id) .fetch_optional(&mut *app_db.conn) .await } pub async fn fetch_one(self, app_db: &mut AppDbClient) -> Result { query_as!(Base, "select * from bases where id = $1", &self.id) .fetch_one(&mut *app_db.conn) .await } } #[derive(Builder)] pub struct InsertableBase { url: String, owner_id: Uuid, } impl InsertableBase { pub async fn insert(self, app_db: &mut AppDbClient) -> Result { query_as!( Base, " insert into bases (id, url, owner_id) values ($1, $2, $3) returning * ", Uuid::now_v7(), self.url, self.owner_id ) .fetch_one(&mut *app_db.conn) .await } }