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, db_items: &HashMap, client: &sea_orm::DatabaseConnection, ) { let mut to_insert: Vec = vec![]; let mut to_update: Vec = vec![]; let mut to_delete: Vec = vec![]; let mut to_save_music: Vec = 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 = 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(future: F) -> F::Output { return tokio::runtime::Builder::new_current_thread() .enable_io() .enable_time() .build() .unwrap() .block_on(future); }