treewide: better cross-device sync capabilities; in-database storage

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Id99798df6f7e4470caae8a193c2654aa6a6a6964
This commit is contained in:
raf 2026-02-05 08:28:50 +03:00
commit f34c78b238
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
41 changed files with 8806 additions and 138 deletions

View file

@ -511,6 +511,236 @@ pub trait StorageBackend: Send + Sync + 'static {
language: Option<&str>,
pagination: &Pagination,
) -> Result<Vec<MediaItem>>;
// ===== Managed Storage =====
/// Insert a media item that uses managed storage
async fn insert_managed_media(&self, item: &MediaItem) -> Result<()>;
/// Get or create a managed blob record (for deduplication tracking)
async fn get_or_create_blob(
&self,
hash: &ContentHash,
size: u64,
mime_type: &str,
) -> Result<ManagedBlob>;
/// Get a managed blob by its content hash
async fn get_blob(&self, hash: &ContentHash) -> Result<Option<ManagedBlob>>;
/// Increment the reference count for a blob
async fn increment_blob_ref(&self, hash: &ContentHash) -> Result<()>;
/// Decrement the reference count for a blob. Returns true if blob should be deleted.
async fn decrement_blob_ref(&self, hash: &ContentHash) -> Result<bool>;
/// Update the last_verified timestamp for a blob
async fn update_blob_verified(&self, hash: &ContentHash) -> Result<()>;
/// List orphaned blobs (reference_count = 0)
async fn list_orphaned_blobs(&self) -> Result<Vec<ManagedBlob>>;
/// Delete a blob record
async fn delete_blob(&self, hash: &ContentHash) -> Result<()>;
/// Get managed storage statistics
async fn managed_storage_stats(&self) -> Result<ManagedStorageStats>;
// ===== Sync Devices =====
/// Register a new sync device
async fn register_device(
&self,
device: &crate::sync::SyncDevice,
token_hash: &str,
) -> Result<crate::sync::SyncDevice>;
/// Get a sync device by ID
async fn get_device(&self, id: crate::sync::DeviceId) -> Result<crate::sync::SyncDevice>;
/// Get a sync device by its token hash
async fn get_device_by_token(
&self,
token_hash: &str,
) -> Result<Option<crate::sync::SyncDevice>>;
/// List all devices for a user
async fn list_user_devices(&self, user_id: UserId) -> Result<Vec<crate::sync::SyncDevice>>;
/// Update a sync device
async fn update_device(&self, device: &crate::sync::SyncDevice) -> Result<()>;
/// Delete a sync device
async fn delete_device(&self, id: crate::sync::DeviceId) -> Result<()>;
/// Update the last_seen_at timestamp for a device
async fn touch_device(&self, id: crate::sync::DeviceId) -> Result<()>;
// ===== Sync Log =====
/// Record a change in the sync log
async fn record_sync_change(&self, change: &crate::sync::SyncLogEntry) -> Result<()>;
/// Get changes since a cursor position
async fn get_changes_since(
&self,
cursor: i64,
limit: u64,
) -> Result<Vec<crate::sync::SyncLogEntry>>;
/// Get the current sync cursor (highest sequence number)
async fn get_current_sync_cursor(&self) -> Result<i64>;
/// Clean up old sync log entries
async fn cleanup_old_sync_log(&self, before: DateTime<Utc>) -> Result<u64>;
// ===== Device Sync State =====
/// Get sync state for a device and path
async fn get_device_sync_state(
&self,
device_id: crate::sync::DeviceId,
path: &str,
) -> Result<Option<crate::sync::DeviceSyncState>>;
/// Insert or update device sync state
async fn upsert_device_sync_state(&self, state: &crate::sync::DeviceSyncState) -> Result<()>;
/// List all pending sync items for a device
async fn list_pending_sync(
&self,
device_id: crate::sync::DeviceId,
) -> Result<Vec<crate::sync::DeviceSyncState>>;
// ===== Upload Sessions (Chunked Uploads) =====
/// Create a new upload session
async fn create_upload_session(&self, session: &crate::sync::UploadSession) -> Result<()>;
/// Get an upload session by ID
async fn get_upload_session(&self, id: Uuid) -> Result<crate::sync::UploadSession>;
/// Update an upload session
async fn update_upload_session(&self, session: &crate::sync::UploadSession) -> Result<()>;
/// Record a received chunk
async fn record_chunk(&self, upload_id: Uuid, chunk: &crate::sync::ChunkInfo) -> Result<()>;
/// Get all chunks for an upload
async fn get_upload_chunks(&self, upload_id: Uuid) -> Result<Vec<crate::sync::ChunkInfo>>;
/// Clean up expired upload sessions
async fn cleanup_expired_uploads(&self) -> Result<u64>;
// ===== Sync Conflicts =====
/// Record a sync conflict
async fn record_conflict(&self, conflict: &crate::sync::SyncConflict) -> Result<()>;
/// Get unresolved conflicts for a device
async fn get_unresolved_conflicts(
&self,
device_id: crate::sync::DeviceId,
) -> Result<Vec<crate::sync::SyncConflict>>;
/// Resolve a conflict
async fn resolve_conflict(
&self,
id: Uuid,
resolution: crate::config::ConflictResolution,
) -> Result<()>;
// ===== Enhanced Sharing =====
/// Create a new share
async fn create_share(&self, share: &crate::sharing::Share) -> Result<crate::sharing::Share>;
/// Get a share by ID
async fn get_share(&self, id: crate::sharing::ShareId) -> Result<crate::sharing::Share>;
/// Get a share by its public token
async fn get_share_by_token(&self, token: &str) -> Result<crate::sharing::Share>;
/// List shares created by a user
async fn list_shares_by_owner(
&self,
owner_id: UserId,
pagination: &Pagination,
) -> Result<Vec<crate::sharing::Share>>;
/// List shares received by a user
async fn list_shares_for_user(
&self,
user_id: UserId,
pagination: &Pagination,
) -> Result<Vec<crate::sharing::Share>>;
/// List all shares for a specific target
async fn list_shares_for_target(
&self,
target: &crate::sharing::ShareTarget,
) -> Result<Vec<crate::sharing::Share>>;
/// Update a share
async fn update_share(&self, share: &crate::sharing::Share) -> Result<crate::sharing::Share>;
/// Delete a share
async fn delete_share(&self, id: crate::sharing::ShareId) -> Result<()>;
/// Record that a share was accessed
async fn record_share_access(&self, id: crate::sharing::ShareId) -> Result<()>;
/// Check share access for a user and target
async fn check_share_access(
&self,
user_id: Option<UserId>,
target: &crate::sharing::ShareTarget,
) -> Result<Option<crate::sharing::SharePermissions>>;
/// Get effective permissions for a media item (considering inheritance)
async fn get_effective_share_permissions(
&self,
user_id: Option<UserId>,
media_id: MediaId,
) -> Result<Option<crate::sharing::SharePermissions>>;
/// Batch delete shares
async fn batch_delete_shares(&self, ids: &[crate::sharing::ShareId]) -> Result<u64>;
/// Clean up expired shares
async fn cleanup_expired_shares(&self) -> Result<u64>;
// ===== Share Activity =====
/// Record share activity
async fn record_share_activity(&self, activity: &crate::sharing::ShareActivity) -> Result<()>;
/// Get activity for a share
async fn get_share_activity(
&self,
share_id: crate::sharing::ShareId,
pagination: &Pagination,
) -> Result<Vec<crate::sharing::ShareActivity>>;
// ===== Share Notifications =====
/// Create a share notification
async fn create_share_notification(
&self,
notification: &crate::sharing::ShareNotification,
) -> Result<()>;
/// Get unread notifications for a user
async fn get_unread_notifications(
&self,
user_id: UserId,
) -> Result<Vec<crate::sharing::ShareNotification>>;
/// Mark a notification as read
async fn mark_notification_read(&self, id: Uuid) -> Result<()>;
/// Mark all notifications as read for a user
async fn mark_all_notifications_read(&self, user_id: UserId) -> Result<()>;
}
/// Comprehensive library statistics.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff