This repository has been archived on 2024-08-23. You can view files and clone it, but cannot push or open issues or pull requests.
project/src/db/folder.rs
2024-08-02 12:32:23 +03:00

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)
}