Files
MusicFS/src/db/sync.rs
T
2026-06-27 15:17:13 +02:00

75 lines
2.2 KiB
Rust

use std::collections::{BTreeMap, HashMap, HashSet};
use fuser::INodeNo;
use sea_orm::entity::prelude::*;
use crate::db::entities::{ActiveModel, Entity, Model};
use crate::item::Item;
use crate::music::db::save_music_metadata;
pub async fn sync_items_to_db(
snapshot: &BTreeMap<INodeNo, Item>,
db_items: &HashMap<i64, Model>,
client: &sea_orm::DatabaseConnection,
) {
let mut to_insert: Vec<ActiveModel> = vec![];
let mut to_update: Vec<ActiveModel> = vec![];
let mut to_delete: Vec<i64> = vec![];
let mut to_save_music: Vec<i64> = vec![];
for (ino, item) in snapshot {
let ino_i64 = ino.0 as i64;
match db_items.get(&ino_i64) {
None => {
to_insert.push(ActiveModel::from(item));
if item.music_metadata.is_some() {
to_save_music.push(ino_i64);
}
}
Some(db_item) if db_item.hash != item.hash as i64 => {
to_update.push(ActiveModel::from(item));
if item.music_metadata.is_some() {
to_save_music.push(ino_i64);
}
}
_ => {}
}
}
let fresh_inodes: HashSet<i64> = snapshot.keys().map(|i| i.0 as i64).collect();
for ino in db_items.keys().filter(|i| !fresh_inodes.contains(i)) {
to_delete.push(*ino);
}
if !to_insert.is_empty() {
Entity::insert_many(to_insert).exec(client).await.unwrap();
}
for model in to_update {
model.update(client).await.unwrap();
}
for ino in to_delete {
Entity::delete_by_id(ino).exec(client).await.unwrap();
}
for ino_i64 in &to_save_music {
let ino = INodeNo(*ino_i64 as u64);
if let Some(music_metadata) = snapshot
.get(&ino)
.and_then(|item| item.music_metadata.as_ref())
{
save_music_metadata(*ino_i64, music_metadata, client)
.await
.unwrap();
}
}
}
pub fn run_db_blocking<F: std::future::Future>(future: F) -> F::Output {
return tokio::runtime::Builder::new_current_thread()
.enable_io()
.enable_time()
.build()
.unwrap()
.block_on(future);
}