From 0550c4f6deecb7a0c89a3b757c3322ac8cb9938f Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Mon, 2 Jun 2025 20:29:03 +0800 Subject: [PATCH] :sparkles: Now the migration helps recreate mis-references post attachments --- .../Storage/FileReferenceService.cs | 6 +- .../Storage/FileService.ReferenceMigration.cs | 94 ++++++++----------- 2 files changed, 40 insertions(+), 60 deletions(-) diff --git a/DysonNetwork.Sphere/Storage/FileReferenceService.cs b/DysonNetwork.Sphere/Storage/FileReferenceService.cs index d2c4a5d..4353ecc 100644 --- a/DysonNetwork.Sphere/Storage/FileReferenceService.cs +++ b/DysonNetwork.Sphere/Storage/FileReferenceService.cs @@ -25,11 +25,9 @@ public class FileReferenceService(AppDatabase db, FileService fileService, ICach Duration? duration = null) { // Calculate expiration time if needed - Instant? finalExpiration = expiredAt; + var finalExpiration = expiredAt; if (duration.HasValue) - { finalExpiration = SystemClock.Instance.GetCurrentInstant() + duration.Value; - } var reference = new CloudFileReference { @@ -42,8 +40,6 @@ public class FileReferenceService(AppDatabase db, FileService fileService, ICach db.FileReferences.Add(reference); await db.SaveChangesAsync(); - - // Purge cache for the file since its usage count has effectively changed await fileService._PurgeCacheAsync(fileId); return reference; diff --git a/DysonNetwork.Sphere/Storage/FileService.ReferenceMigration.cs b/DysonNetwork.Sphere/Storage/FileService.ReferenceMigration.cs index 548fa02..d377aba 100644 --- a/DysonNetwork.Sphere/Storage/FileService.ReferenceMigration.cs +++ b/DysonNetwork.Sphere/Storage/FileService.ReferenceMigration.cs @@ -1,4 +1,6 @@ +using EFCore.BulkExtensions; using Microsoft.EntityFrameworkCore; +using NodaTime; namespace DysonNetwork.Sphere.Storage; @@ -35,38 +37,33 @@ public class FileReferenceMigrationService(AppDatabase db) .Where(p => p.OutdatedAttachments.Any()) .ToListAsync(); + var attachmentsId = posts.SelectMany(p => p.OutdatedAttachments.Select(a => a.Id)).ToList(); + var attachments = await db.Files.Where(f => attachmentsId.Contains(f.Id)).ToListAsync(); + var attachmentsDict = attachments + .GroupBy(a => posts.First(p => p.OutdatedAttachments.Any(oa => oa.Id == a.Id)).Id) + .ToDictionary(g => g.Key, g => g.ToList()); + + var fileReferences = posts.SelectMany(post => + attachmentsDict[post.Id].Select(attachment => + new CloudFileReference + { + FileId = attachment.Id, + File = attachment, + Usage = "post", + ResourceId = post.Id.ToString(), + CreatedAt = SystemClock.Instance.GetCurrentInstant(), + UpdatedAt = SystemClock.Instance.GetCurrentInstant() + }) + ) + .ToList(); + foreach (var post in posts) { - var updatedAttachments = new List(); - - foreach (var attachment in post.OutdatedAttachments) - { - var file = await db.Files.FirstOrDefaultAsync(f => f.Id == attachment.Id); - if (file != null) - { - // Create a reference for the file - var reference = new CloudFileReference - { - FileId = file.Id, - File = file, - Usage = "post", - ResourceId = post.Id.ToString() - }; - - await db.FileReferences.AddAsync(reference); - updatedAttachments.Add(file.ToReferenceObject()); - } - else - { - // Keep the existing reference object if file not found - updatedAttachments.Add(attachment.ToReferenceObject()); - } - } - - post.Attachments = updatedAttachments; + post.Attachments = post.OutdatedAttachments.Select(a => a.ToReferenceObject()).ToList(); db.Posts.Update(post); } + await db.BulkInsertAsync(fileReferences); await db.SaveChangesAsync(); } @@ -74,41 +71,28 @@ public class FileReferenceMigrationService(AppDatabase db) { var messages = await db.ChatMessages .Include(m => m.OutdatedAttachments) - .Where(m => m.OutdatedAttachments.Any() && m.DeletedAt == null) + .Where(m => m.OutdatedAttachments.Any()) .ToListAsync(); + var fileReferences = messages.SelectMany(message => message.OutdatedAttachments.Select(attachment => + new CloudFileReference + { + FileId = attachment.Id, + File = attachment, + Usage = "chat", + ResourceId = message.Id.ToString(), + CreatedAt = SystemClock.Instance.GetCurrentInstant(), + UpdatedAt = SystemClock.Instance.GetCurrentInstant() + }) + ).ToList(); + foreach (var message in messages) { - var updatedAttachments = new List(); - - foreach (var attachment in message.OutdatedAttachments) - { - var file = await db.Files.FirstOrDefaultAsync(f => f.Id == attachment.Id); - if (file != null) - { - // Create a reference for the file - var reference = new CloudFileReference - { - FileId = file.Id, - File = file, - Usage = "chat", - ResourceId = message.Id.ToString() - }; - - await db.FileReferences.AddAsync(reference); - updatedAttachments.Add(file.ToReferenceObject()); - } - else - { - // Keep the existing reference object if file not found - updatedAttachments.Add(attachment.ToReferenceObject()); - } - } - - message.Attachments = updatedAttachments; + message.Attachments = message.OutdatedAttachments.Select(a => a.ToReferenceObject()).ToList(); db.ChatMessages.Update(message); } + await db.BulkInsertAsync(fileReferences); await db.SaveChangesAsync(); }