Fix to attached world data (#3618)

* Add AttachedWorldData::remove_for_world

* Box the S3 error for daedelus_client ErrorKind::S3

* Delete attached world data on world deletion
This commit is contained in:
Josiah Glosson 2025-05-06 10:06:46 -05:00 committed by GitHub
parent 8dd32bbe98
commit 2d5d2d5df8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 68 additions and 14 deletions

View File

@ -54,7 +54,7 @@ async function saveServer() {
'server', 'server',
address.value, address.value,
newDisplayStatus.value, newDisplayStatus.value,
) ).catch(handleError)
} }
emit('submit', { emit('submit', {

View File

@ -22,7 +22,7 @@ pub enum ErrorKind {
Fetch { inner: reqwest::Error, item: String }, Fetch { inner: reqwest::Error, item: String },
#[error("Error while uploading file to S3: {file}")] #[error("Error while uploading file to S3: {file}")]
S3 { S3 {
inner: s3::error::S3Error, inner: Box<s3::error::S3Error>,
file: String, file: String,
}, },
#[error("Error acquiring semaphore: {0}")] #[error("Error acquiring semaphore: {0}")]

View File

@ -78,7 +78,7 @@ pub async fn upload_file_to_bucket(
BUCKET.put_object(key.clone(), &bytes).await BUCKET.put_object(key.clone(), &bytes).await
} }
.map_err(|err| ErrorKind::S3 { .map_err(|err| ErrorKind::S3 {
inner: err, inner: Box::new(err),
file: path.clone(), file: path.clone(),
}); });

View File

@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM attached_world_data\n WHERE profile_path = $1 and world_type = $2 and world_id = $3\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "1a979fbc58be7dde562b6f7c8fdcf9a4fc5a9817f4831c66bd56f2f4d0a00f82"
}

View File

@ -62,6 +62,29 @@ impl AttachedWorldData {
}) })
.collect()) .collect())
} }
pub async fn remove_for_world(
instance: &str,
world_type: WorldType,
world_id: &str,
exec: impl sqlx::Executor<'_, Database = sqlx::Sqlite>,
) -> crate::Result<()> {
let world_type = world_type.as_str();
sqlx::query!(
"
DELETE FROM attached_world_data
WHERE profile_path = $1 and world_type = $2 and world_id = $3
",
instance,
world_type,
world_id
)
.execute(exec)
.await?;
Ok(())
}
} }
macro_rules! attached_data_setter { macro_rules! attached_data_setter {

View File

@ -1,6 +1,10 @@
use crate::State;
use crate::event::ProfilePayloadType; use crate::event::ProfilePayloadType;
use crate::event::emit::{emit_profile, emit_warning}; use crate::event::emit::{emit_profile, emit_warning};
use crate::state::{DirectoryInfo, ProfileInstallStage, ProjectType}; use crate::state::{
DirectoryInfo, ProfileInstallStage, ProjectType, attached_world_data,
};
use crate::worlds::WorldType;
use futures::{SinkExt, StreamExt, channel::mpsc::channel}; use futures::{SinkExt, StreamExt, channel::mpsc::channel};
use notify::{RecommendedWatcher, RecursiveMode}; use notify::{RecommendedWatcher, RecursiveMode};
use notify_debouncer_mini::{DebounceEventResult, Debouncer, new_debouncer}; use notify_debouncer_mini::{DebounceEventResult, Debouncer, new_debouncer};
@ -87,16 +91,31 @@ pub async fn init_watcher() -> crate::Result<FileWatcher> {
"World updated: {}", "World updated: {}",
e.path.display() e.path.display()
); );
Some(ProfilePayloadType::WorldUpdated { let world = e
world: e .path
.path .parent()
.parent() .unwrap()
.unwrap() .file_name()
.file_name() .unwrap()
.unwrap() .to_string_lossy()
.to_string_lossy() .to_string();
.to_string(), if !e.path.is_file() {
}) let profile_path_str = profile_path_str.clone();
let world = world.clone();
tokio::spawn(async move {
if let Ok(state) = State::get().await {
if let Err(e) = attached_world_data::AttachedWorldData::remove_for_world(
&profile_path_str,
WorldType::Singleplayer,
&world,
&state.pool
).await {
tracing::warn!("Failed to remove AttachedWorldData for '{world}': {e}")
}
}
});
}
Some(ProfilePayloadType::WorldUpdated { world })
} else if first_file_name } else if first_file_name
.filter(|x| *x == "saves") .filter(|x| *x == "saves")
.is_none() .is_none()