//! GoingsOn's [`BlobPolicy`]: attachment blobs are content-addressed files under //! the app data dir, tracked purely by disk existence (no `cloud_only` flag), so //! the three presence hooks stay no-ops. This mirrors the retiring //! `sync_service/blob_sync.rs`, but the engine now owns the invariant machinery: //! dedup-aware upload, integrity-verified download, and atomic writes. use std::path::PathBuf; use rusqlite::Connection; use synckit_client::{BlobPolicy, BlobRef, Result, SyncKitError}; use crate::state::DESKTOP_USER_ID; /// Attachment blob policy for the single desktop user. pub(crate) struct AttachmentBlobs { data_dir: PathBuf, user_id: String, } impl AttachmentBlobs { pub(crate) fn new(data_dir: PathBuf) -> Self { Self { data_dir, user_id: DESKTOP_USER_ID.to_string(), } } /// Every distinct attachment blob for the desktop user. The engine filters /// this candidate set per pass: uploads skip blobs with no local file, /// downloads skip blobs already present on disk (then SHA-256-verify). fn all_blobs(&self, conn: &Connection) -> Result> { let mut stmt = conn .prepare("SELECT DISTINCT blob_hash, file_size FROM attachments WHERE user_id = ?1") .map_err(map_err)?; let rows = stmt .query_map([&self.user_id], |r| { let hash: String = r.get(0)?; let size: i64 = r.get(1)?; Ok(BlobRef { hash, ext: String::new(), size: size.max(0) as u64, }) }) .map_err(map_err)?; rows.collect::>>().map_err(map_err) } } #[allow( clippy::needless_pass_by_value, reason = "used as a `.map_err(map_err)` callback, which passes the error by value" )] fn map_err(e: rusqlite::Error) -> SyncKitError { SyncKitError::Internal(format!("attachment blob query: {e}")) } impl BlobPolicy for AttachmentBlobs { fn pending_uploads(&self, conn: &Connection) -> Result> { self.all_blobs(conn) } fn pending_downloads(&self, conn: &Connection) -> Result> { self.all_blobs(conn) } fn local_path(&self, blob: &BlobRef) -> PathBuf { crate::commands::attachment::blob_path(&self.data_dir, &blob.hash) } // reconcile / on_uploaded / on_downloaded: inherited no-ops (presence is disk // existence, so there is no flag to reconcile). }