treewide: better cross-device sync capabilities; in-database storage
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Id99798df6f7e4470caae8a193c2654aa6a6a6964
This commit is contained in:
parent
5521488a93
commit
f34c78b238
41 changed files with 8806 additions and 138 deletions
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue