diff --git a/DysonNetwork.Drive/Storage/FileReferenceService.cs b/DysonNetwork.Drive/Storage/FileReferenceService.cs index 31fc1a2..439eeb7 100644 --- a/DysonNetwork.Drive/Storage/FileReferenceService.cs +++ b/DysonNetwork.Drive/Storage/FileReferenceService.cs @@ -190,10 +190,8 @@ public class FileReferenceService(AppDatabase db, FileService fileService, ICach .Where(r => r.ResourceId == resourceId && r.Usage == usage) .ToListAsync(); - if (!references.Any()) - { + if (references.Count == 0) return 0; - } var fileIds = references.Select(r => r.FileId).Distinct().ToList(); @@ -207,6 +205,28 @@ public class FileReferenceService(AppDatabase db, FileService fileService, ICach return deletedCount; } + + public async Task DeleteResourceReferencesBatchAsync(IEnumerable resourceIds, string? usage = null) + { + var references = await db.FileReferences + .Where(r => resourceIds.Contains(r.ResourceId)) + .If(usage != null, q => q.Where(q => q.Usage == usage)) + .ToListAsync(); + + if (references.Count == 0) + return 0; + + var fileIds = references.Select(r => r.FileId).Distinct().ToList(); + + db.FileReferences.RemoveRange(references); + var deletedCount = await db.SaveChangesAsync(); + + // Purge caches + var tasks = fileIds.Select(fileService._PurgeCacheAsync).ToList(); + await Task.WhenAll(tasks); + + return deletedCount; + } /// /// Deletes a specific file reference diff --git a/DysonNetwork.Drive/Storage/FileReferenceServiceGrpc.cs b/DysonNetwork.Drive/Storage/FileReferenceServiceGrpc.cs index 386b982..c1547d6 100644 --- a/DysonNetwork.Drive/Storage/FileReferenceServiceGrpc.cs +++ b/DysonNetwork.Drive/Storage/FileReferenceServiceGrpc.cs @@ -85,7 +85,7 @@ namespace DysonNetwork.Drive.Storage public override async Task DeleteResourceReferences( DeleteResourceReferencesRequest request, ServerCallContext context) { - var deletedCount = 0; + int deletedCount; if (request.Usage is null) deletedCount = await fileReferenceService.DeleteResourceReferencesAsync(request.ResourceId); else @@ -93,6 +93,18 @@ namespace DysonNetwork.Drive.Storage await fileReferenceService.DeleteResourceReferencesAsync(request.ResourceId, request.Usage!); return new DeleteResourceReferencesResponse { DeletedCount = deletedCount }; } + + public override async Task DeleteResourceReferencesBatch(DeleteResourceReferencesBatchRequest request, ServerCallContext context) + { + var resourceIds = request.ResourceIds.ToList(); + int deletedCount; + if (request.Usage is null) + deletedCount = await fileReferenceService.DeleteResourceReferencesBatchAsync(resourceIds); + else + deletedCount = + await fileReferenceService.DeleteResourceReferencesBatchAsync(resourceIds, request.Usage!); + return new DeleteResourceReferencesResponse { DeletedCount = deletedCount }; + } public override async Task DeleteReference(DeleteReferenceRequest request, ServerCallContext context) diff --git a/DysonNetwork.Shared/Proto/file.proto b/DysonNetwork.Shared/Proto/file.proto index 34129b3..470d079 100644 --- a/DysonNetwork.Shared/Proto/file.proto +++ b/DysonNetwork.Shared/Proto/file.proto @@ -206,6 +206,11 @@ message DeleteResourceReferencesRequest { optional string usage = 2; } +message DeleteResourceReferencesBatchRequest { + repeated string resource_ids = 1; + optional string usage = 2; +} + message DeleteResourceReferencesResponse { int32 deleted_count = 1; } @@ -277,6 +282,9 @@ service FileReferenceService { // Deletes references for a specific resource and optional usage rpc DeleteResourceReferences(DeleteResourceReferencesRequest) returns (DeleteResourceReferencesResponse); + + // Deletes references for multiple specific resources and optional usage + rpc DeleteResourceReferencesBatch(DeleteResourceReferencesBatchRequest) returns (DeleteResourceReferencesResponse); // Deletes a specific file reference rpc DeleteReference(DeleteReferenceRequest) returns (DeleteReferenceResponse);