114 lines
3.3 KiB
Rust
114 lines
3.3 KiB
Rust
use futures::{Stream, TryStreamExt};
|
|
use uuid::Uuid;
|
|
|
|
use crate::{db::permissions::PermissionRaw, Pool};
|
|
|
|
use super::permissions::PermissionType;
|
|
|
|
pub async fn get_permissions(
|
|
folder_id: Uuid,
|
|
user_id: i32,
|
|
pool: &Pool,
|
|
) -> sqlx::Result<PermissionType> {
|
|
let permission = sqlx::query_file!("sql/get_permissions_for_folder.sql", folder_id, user_id)
|
|
.fetch_optional(pool)
|
|
.await?
|
|
.and_then(|record| record.permission_type);
|
|
Ok(permission.into())
|
|
}
|
|
|
|
pub fn get_names(folder_id: Uuid, pool: &Pool) -> impl Stream<Item = sqlx::Result<String>> + '_ {
|
|
sqlx::query!("SELECT folder_name as name FROM folders WHERE parent_folder_id = $1 UNION SELECT file_name as name FROM files WHERE folder_id = $1", folder_id)
|
|
.fetch(pool)
|
|
.map_ok(|record| record.name.unwrap())
|
|
}
|
|
|
|
pub async fn get_root(user_id: i32, pool: &Pool) -> sqlx::Result<Uuid> {
|
|
sqlx::query!(
|
|
"SELECT folder_id FROM folders WHERE owner_id = $1 AND parent_folder_id IS null",
|
|
user_id
|
|
)
|
|
.fetch_one(pool)
|
|
.await
|
|
.map(|row| row.folder_id)
|
|
}
|
|
|
|
pub async fn process_id(id: Option<Uuid>, user_id: i32, pool: &Pool) -> sqlx::Result<Option<Uuid>> {
|
|
match id {
|
|
Some(id) => get_permissions(id, user_id, pool)
|
|
.await
|
|
.map(|permissions| permissions.can_read().then_some(id)),
|
|
None => get_root(user_id, pool).await.map(Some),
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, serde::Serialize)]
|
|
#[allow(clippy::struct_field_names, clippy::module_name_repetitions)]
|
|
pub struct FolderWithoutParentId {
|
|
pub folder_id: Uuid,
|
|
pub owner_id: i32,
|
|
pub folder_name: String,
|
|
pub created_at: chrono::NaiveDateTime,
|
|
}
|
|
|
|
pub async fn get_by_id(
|
|
folder_id: Uuid,
|
|
pool: &Pool,
|
|
) -> sqlx::Result<Option<FolderWithoutParentId>> {
|
|
sqlx::query_as!(
|
|
FolderWithoutParentId,
|
|
"SELECT folder_id, owner_id, folder_name, created_at FROM folders WHERE folder_id = $1",
|
|
folder_id
|
|
)
|
|
.fetch_optional(pool)
|
|
.await
|
|
}
|
|
|
|
/// Get folders that user can read
|
|
///
|
|
/// # Warning
|
|
///
|
|
/// This function doesn't check that the user can read the parent folder itself
|
|
pub fn get_folders(
|
|
parent_folder_id: Uuid,
|
|
user_id: i32,
|
|
pool: &Pool,
|
|
) -> impl Stream<Item = sqlx::Result<FolderWithoutParentId>> + '_ {
|
|
sqlx::query_file_as!(
|
|
FolderWithoutParentId,
|
|
"sql/get_folders.sql",
|
|
parent_folder_id,
|
|
user_id
|
|
)
|
|
.fetch(pool)
|
|
}
|
|
|
|
pub async fn name_exists(parent_folder_id: Uuid, name: &str, pool: &Pool) -> sqlx::Result<bool> {
|
|
sqlx::query_file!("sql/name_exists.sql", parent_folder_id, name)
|
|
.fetch_one(pool)
|
|
.await
|
|
.map(|row| row.exists.unwrap_or(false))
|
|
}
|
|
|
|
pub async fn insert(
|
|
parent_folder_id: Uuid,
|
|
user_id: i32,
|
|
folder_name: &str,
|
|
pool: &Pool,
|
|
) -> sqlx::Result<Uuid> {
|
|
sqlx::query!("INSERT INTO folders(parent_folder_id, owner_id, folder_name) VALUES ($1, $2, $3) RETURNING folder_id",
|
|
parent_folder_id,
|
|
user_id,
|
|
folder_name
|
|
)
|
|
.fetch_one(pool)
|
|
.await
|
|
.map(|record| record.folder_id)
|
|
}
|
|
|
|
pub fn delete(folder_id: Uuid, pool: &Pool) -> impl Stream<Item = sqlx::Result<Uuid>> + '_ {
|
|
sqlx::query_file!("sql/delete_folder.sql", folder_id)
|
|
.fetch(pool)
|
|
.map_ok(|row| row.file_id)
|
|
}
|