From fbeb6c937303c0b797d6fdb4d1cc8ecb5bf892b5 Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Sun, 3 Nov 2024 04:48:07 -0800 Subject: [PATCH] Add unique constraint to volume model, refine volume fingerprint generation, and improve database interaction for system volumes --- core/prisma/schema.prisma | 1 + core/src/volume/actor.rs | 25 ++++++++++++++++++------- core/src/volume/types.rs | 11 +++-------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/core/prisma/schema.prisma b/core/prisma/schema.prisma index 467342ed2e6b..a32a20863a59 100644 --- a/core/prisma/schema.prisma +++ b/core/prisma/schema.prisma @@ -160,6 +160,7 @@ model Volume { device_id Int? device Device? @relation(fields: [device_id], references: [id], onDelete: Cascade) + @@unique([device_id, mount_point, name, total_bytes_capacity, file_system]) @@map("volume") } diff --git a/core/src/volume/actor.rs b/core/src/volume/actor.rs index c22a40dff620..49cac9d331a9 100644 --- a/core/src/volume/actor.rs +++ b/core/src/volume/actor.rs @@ -11,6 +11,7 @@ use crate::{ }; use async_channel as chan; use sd_prisma::prisma::volume; +use serde::de; use std::{collections::HashMap, sync::Arc, time::Duration}; use tokio::sync::{broadcast, oneshot, Mutex, RwLock}; use tracing::{debug, error, info, trace, warn}; @@ -273,7 +274,7 @@ impl VolumeManagerActor { let db_volumes = library .db .volume() - .find_many(vec![]) + .find_many(vec![volume::device_id::equals(Some(db_device.id))]) .exec() .await? .into_iter() @@ -287,13 +288,23 @@ impl VolumeManagerActor { // Create missing system volumes in the database for v in current_volumes.iter() { let fingerprint = v.generate_fingerprint(device_pub_id.clone()); - // ensure that the volume is not already in the db and is a system volume - if !db_volumes - .iter() - .any(|db_volume| fingerprint == db_volume.fingerprint.clone().unwrap()) - && v.mount_type == MountType::System - { + + // Check if the volume already exists in the database + let existing_volume = db_volumes.iter().find(|db_volume| { + db_volume + .fingerprint + .as_ref() + .map(|db_fingerprint| db_fingerprint == &fingerprint) + .unwrap_or(false) + }); + + if existing_volume.is_none() && v.mount_type == MountType::System { + // If the volume doesn't exist in the database and is a system volume, create a new entry v.create(&library.db, device_pub_id.clone()).await?; + } else if let Some(existing_volume) = existing_volume { + // If the volume already exists in the database, update its information + let updated_volume = Volume::merge_with_db_volume(v, existing_volume); + updated_volume.update(&library.db).await?; } } diff --git a/core/src/volume/types.rs b/core/src/volume/types.rs index f750deefe65d..5f9a5e2ea598 100644 --- a/core/src/volume/types.rs +++ b/core/src/volume/types.rs @@ -187,14 +187,9 @@ impl Volume { for id in current_device_pub_id { hasher.update(&[id]); } - - // Add all mount points to make fingerprint unique - for mount_point in &self.mount_points { - hasher.update(mount_point.to_string_lossy().as_bytes()); - } - - // hasher.update(self.name.as_bytes()); - // hasher.update(&self.total_bytes_capacity.to_be_bytes()); + hasher.update(self.mount_point.to_string_lossy().as_bytes()); + hasher.update(self.name.as_bytes()); + hasher.update(&self.total_bytes_capacity.to_be_bytes()); hasher.update(self.file_system.to_string().as_bytes()); hasher.finalize().as_bytes().to_vec()