Structure optimized

This commit is contained in:
StNicolay 2024-08-01 20:40:49 +03:00
parent 1eba969197
commit 1830e8a2f3
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
5 changed files with 18 additions and 27 deletions

2
Cargo.lock generated
View File

@ -1142,7 +1142,6 @@ checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
"serde",
]
[[package]]
@ -1535,7 +1534,6 @@ dependencies = [
"futures",
"jsonwebtoken",
"oauth2",
"parking_lot",
"reqwest 0.12.5",
"serde",
"sha2",

View File

@ -26,7 +26,6 @@ dotenvy = "0.15"
futures = "0.3"
jsonwebtoken = "9"
oauth2 = "4"
parking_lot = { version = "0.12.3", features = ["serde"] }
reqwest = { version = "0.12", features = [
"http2",
"rustls-tls",

View File

@ -69,19 +69,18 @@ pub async fn get_by_id(
/// # Warning
///
/// This function doesn't check that the user can read the parent folder itself
pub async fn get_folders(
pub fn get_folders(
parent_folder_id: Uuid,
user_id: i32,
pool: &Pool,
) -> sqlx::Result<Vec<FolderWithoutParentId>> {
) -> impl Stream<Item = sqlx::Result<FolderWithoutParentId>> + '_ {
sqlx::query_file_as!(
FolderWithoutParentId,
"sql/get_folders.sql",
parent_folder_id,
user_id
)
.fetch_all(pool)
.await
.fetch(pool)
}
pub async fn name_exists(parent_folder_id: Uuid, name: &str, pool: &Pool) -> sqlx::Result<bool> {

View File

@ -1,6 +1,4 @@
use std::sync::Arc;
use parking_lot::Mutex;
use futures::TryStreamExt;
use tokio::try_join;
use super::list::Params;
@ -10,27 +8,24 @@ use crate::prelude::*;
pub struct FolderStructure {
#[serde(flatten)]
folder_base: db::folder::FolderWithoutParentId,
folders: Vec<WrappedStructure>,
folders: Vec<FolderStructure>,
files: Vec<db::file::FileWithoutParentId>,
}
type WrappedStructure = Arc<Mutex<FolderStructure>>;
impl From<db::folder::FolderWithoutParentId> for WrappedStructure {
impl From<db::folder::FolderWithoutParentId> for FolderStructure {
fn from(value: db::folder::FolderWithoutParentId) -> Self {
let fs = FolderStructure {
FolderStructure {
folder_base: value,
folders: Vec::new(),
files: Vec::new(),
};
Arc::new(Mutex::new(fs))
}
}
}
#[derive(Debug, Serialize)]
pub struct Response {
folder_id: Uuid,
structure: WrappedStructure,
structure: FolderStructure,
}
pub async fn structure(
@ -46,24 +41,23 @@ pub async fn structure(
.await
.handle_internal()?
.ok_or(StatusCode::NOT_FOUND)?;
let response = Response {
let mut response = Response {
folder_id,
structure: folder.into(),
};
// TODO: Spawn tasks instead of a single loop
let mut stack: Vec<WrappedStructure> = vec![Arc::clone(&response.structure)];
let mut stack: Vec<&mut FolderStructure> = vec![&mut response.structure];
while let Some(folder) = stack.pop() {
let folder_id = folder.lock().folder_base.folder_id;
let (files, folders) = try_join!(
db::file::get_files(folder_id, &pool),
db::folder::get_folders(folder_id, claims.user_id, &pool)
.map_ok(Into::into)
.try_collect()
)
.handle_internal()?;
let folders: Vec<_> = folders.into_iter().map(Into::into).collect();
stack.extend(folders.iter().cloned());
let mut lock = folder.lock();
lock.folders = folders;
lock.files = files;
folder.folders = folders;
folder.files = files;
stack.extend(folder.folders.iter_mut());
}
Ok(Json(response))
}

View File

@ -1,3 +1,4 @@
use futures::TryStreamExt;
use tokio::try_join;
use crate::prelude::*;
@ -26,7 +27,7 @@ pub async fn list(
let (files, folders) = try_join!(
db::file::get_files(folder_id, &pool),
db::folder::get_folders(folder_id, claims.user_id, &pool)
db::folder::get_folders(folder_id, claims.user_id, &pool).try_collect()
)
.handle_internal()?;