sharp-chat/SharpChatCommon/Storage/StorageMigrator.cs
flashwave 5a7756894b
First bits of the Context overhaul.
Reintroduces separate contexts for users, channels, connections (now split into sessions and connections) and user-channel associations.
It builds which is as much assurance as I can give about the stability of this commit, but its also the bare minimum of what i like to commit sooooo
A lot of things still need to be broadcast through events throughout the application in order to keep states consistent but we'll cross that bridge when we get to it.
I really need to stop using that phrase thingy, I'm overusing it.
2025-05-03 02:49:51 +00:00

54 lines
2.4 KiB
C#

using Microsoft.Extensions.Logging;
using SharpChat.Messages;
using ZLogger;
namespace SharpChat.Storage;
public class StorageMigrator(ILogger logger, StorageBackend source, StorageBackend target) {
public async Task Migrate(CancellationToken cancellationToken) {
try {
logger.ZLogInformation($"Converting from {source.GetType().Name} to {target.GetType().Name}!");
logger.ZLogInformation($"Ensuring both source and target are fully upgraded...");
if(cancellationToken.IsCancellationRequested) return;
await source.UpgradeStorage();
if(cancellationToken.IsCancellationRequested) return;
await target.UpgradeStorage();
if(cancellationToken.IsCancellationRequested) return;
logger.ZLogInformation($"Creating message storage instances...");
MessageStorage sourceMsgs = source.CreateMessageStorage();
MessageStorage targetMsgs = target.CreateMessageStorage();
if(cancellationToken.IsCancellationRequested) return;
long msgCount = await sourceMsgs.CountMessages(includeDeleted: true);
if(msgCount < 1) {
logger.ZLogInformation($"No messages to migrate, skipping...");
} else {
logger.ZLogInformation($"Migrating {msgCount} message{(msgCount == 1 ? "" : "s")}...");
long migrated = 0;
DateTimeOffset lastReport = DateTimeOffset.UtcNow;
IEnumerable<Message> msgs = await sourceMsgs.GetMessages(take: null, includeDeleted: true);
foreach(Message msg in msgs) {
if(cancellationToken.IsCancellationRequested) break;
await targetMsgs.LogMessage(msg);
++migrated;
if(DateTimeOffset.UtcNow - lastReport > TimeSpan.FromMinutes(1)) {
lastReport = DateTimeOffset.UtcNow;
double completion = (double)migrated / msgCount;
logger.ZLogInformation($"{migrated} of {msgCount} message{(migrated == 1 ? "" : "s")} migrated ({completion:P2})...");
}
}
logger.ZLogInformation($"Migrated {migrated} message{(migrated == 1 ? "" : "s")}!");
}
} catch(Exception ex) {
logger.ZLogError($"Error during migration: {ex}");
throw;
}
}
}