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 = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
"serde",
] ]
[[package]] [[package]]
@ -1535,7 +1534,6 @@ dependencies = [
"futures", "futures",
"jsonwebtoken", "jsonwebtoken",
"oauth2", "oauth2",
"parking_lot",
"reqwest 0.12.5", "reqwest 0.12.5",
"serde", "serde",
"sha2", "sha2",

View File

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

View File

@ -69,19 +69,18 @@ pub async fn get_by_id(
/// # Warning /// # Warning
/// ///
/// This function doesn't check that the user can read the parent folder itself /// 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, parent_folder_id: Uuid,
user_id: i32, user_id: i32,
pool: &Pool, pool: &Pool,
) -> sqlx::Result<Vec<FolderWithoutParentId>> { ) -> impl Stream<Item = sqlx::Result<FolderWithoutParentId>> + '_ {
sqlx::query_file_as!( sqlx::query_file_as!(
FolderWithoutParentId, FolderWithoutParentId,
"sql/get_folders.sql", "sql/get_folders.sql",
parent_folder_id, parent_folder_id,
user_id user_id
) )
.fetch_all(pool) .fetch(pool)
.await
} }
pub async fn name_exists(parent_folder_id: Uuid, name: &str, pool: &Pool) -> sqlx::Result<bool> { 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 futures::TryStreamExt;
use parking_lot::Mutex;
use tokio::try_join; use tokio::try_join;
use super::list::Params; use super::list::Params;
@ -10,27 +8,24 @@ use crate::prelude::*;
pub struct FolderStructure { pub struct FolderStructure {
#[serde(flatten)] #[serde(flatten)]
folder_base: db::folder::FolderWithoutParentId, folder_base: db::folder::FolderWithoutParentId,
folders: Vec<WrappedStructure>, folders: Vec<FolderStructure>,
files: Vec<db::file::FileWithoutParentId>, files: Vec<db::file::FileWithoutParentId>,
} }
type WrappedStructure = Arc<Mutex<FolderStructure>>; impl From<db::folder::FolderWithoutParentId> for FolderStructure {
impl From<db::folder::FolderWithoutParentId> for WrappedStructure {
fn from(value: db::folder::FolderWithoutParentId) -> Self { fn from(value: db::folder::FolderWithoutParentId) -> Self {
let fs = FolderStructure { FolderStructure {
folder_base: value, folder_base: value,
folders: Vec::new(), folders: Vec::new(),
files: Vec::new(), files: Vec::new(),
}; }
Arc::new(Mutex::new(fs))
} }
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct Response { pub struct Response {
folder_id: Uuid, folder_id: Uuid,
structure: WrappedStructure, structure: FolderStructure,
} }
pub async fn structure( pub async fn structure(
@ -46,24 +41,23 @@ pub async fn structure(
.await .await
.handle_internal()? .handle_internal()?
.ok_or(StatusCode::NOT_FOUND)?; .ok_or(StatusCode::NOT_FOUND)?;
let response = Response { let mut response = Response {
folder_id, folder_id,
structure: folder.into(), structure: folder.into(),
}; };
// TODO: Spawn tasks instead of a single loop // 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() { while let Some(folder) = stack.pop() {
let folder_id = folder.lock().folder_base.folder_id;
let (files, folders) = try_join!( let (files, folders) = try_join!(
db::file::get_files(folder_id, &pool), 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)
.map_ok(Into::into)
.try_collect()
) )
.handle_internal()?; .handle_internal()?;
let folders: Vec<_> = folders.into_iter().map(Into::into).collect(); folder.folders = folders;
stack.extend(folders.iter().cloned()); folder.files = files;
let mut lock = folder.lock(); stack.extend(folder.folders.iter_mut());
lock.folders = folders;
lock.files = files;
} }
Ok(Json(response)) Ok(Json(response))
} }

View File

@ -1,3 +1,4 @@
use futures::TryStreamExt;
use tokio::try_join; use tokio::try_join;
use crate::prelude::*; use crate::prelude::*;
@ -26,7 +27,7 @@ pub async fn list(
let (files, folders) = try_join!( let (files, folders) = try_join!(
db::file::get_files(folder_id, &pool), 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()?; .handle_internal()?;