Fix metadata

This commit is contained in:
Kieran 2022-02-17 22:10:37 +00:00
parent 6a5e1e24bd
commit 71d37fc2e6
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 126 additions and 3 deletions

View File

@ -3,15 +3,25 @@ using VoidCat.Services.Abstractions;
namespace VoidCat.Model;
/// <summary>
/// Base metadata must contain version number
/// </summary>
public interface IVoidFileMeta
{
const int CurrentVersion = 3;
int Version { get; init; }
}
/// <summary>
/// File metadata which is managed by <see cref="IFileMetadataStore"/>
/// </summary>
public record VoidFileMeta
public record VoidFileMeta : IVoidFileMeta
{
/// <summary>
/// Metadata version
/// </summary>
public int Version { get; init; } = 2;
public int Version { get; init; } = IVoidFileMeta.CurrentVersion;
/// <summary>
/// Filename

View File

@ -7,7 +7,7 @@ namespace VoidCat.Services;
public class LocalDiskFileMetadataStore : IFileMetadataStore
{
private const string MetadataDir = "metadata-v2";
private const string MetadataDir = "metadata-v3";
private readonly VoidSettings _settings;
public LocalDiskFileMetadataStore(VoidSettings settings)

View File

@ -0,0 +1,46 @@
using Newtonsoft.Json;
using VoidCat.Model;
namespace VoidCat.Services.Migrations;
public class FixMigration_20220218 : MetadataMigrator<WrongFile, WrongMeta>
{
public FixMigration_20220218(VoidSettings settings, ILogger<MetadataMigrator<WrongFile, WrongMeta>> logger) : base(settings, logger)
{
}
protected override string OldPath => "metadata-v2";
protected override string NewPath => "metadata-v3";
protected override bool ShouldMigrate(string json)
{
var metaBase = JsonConvert.DeserializeObject<WrongFile>(json);
return metaBase?.Metadata?.Version == 2 && metaBase?.Metadata?.Size > 0;
}
protected override WrongMeta MigrateModel(WrongFile old)
{
return old.Metadata!;
}
}
public class WrongFile
{
[JsonConverter(typeof(Base58GuidConverter))]
public Guid Id { get; init; }
public WrongMeta? Metadata { get; init; }
public Paywall? Paywall { get; init; }
}
public class WrongMeta
{
public int Version { get; init; } = 2;
public string? Name { get; init; }
public ulong Size { get; init; }
public DateTimeOffset Uploaded { get; init; } = DateTimeOffset.UtcNow;
public string? Description { get; init; }
public string? MimeType { get; init; }
public string? Digest { get; init; }
[JsonConverter(typeof(Base58GuidConverter))]
public Guid EditSecret { get; init; }
}

View File

@ -10,6 +10,7 @@ public static class Migrations
public static IServiceCollection AddVoidMigrations(this IServiceCollection svc)
{
svc.AddTransient<IMigration, MigrateMetadata_20220217>();
svc.AddTransient<IMigration, FixMigration_20220218>();
return svc;
}
}

View File

@ -0,0 +1,66 @@
using Newtonsoft.Json;
using VoidCat.Model;
namespace VoidCat.Services.Migrations;
public abstract class MetadataMigrator<TOld, TNew> : IMigration
{
private readonly VoidSettings _settings;
private readonly ILogger<MetadataMigrator<TOld, TNew>> _logger;
protected MetadataMigrator(VoidSettings settings, ILogger<MetadataMigrator<TOld, TNew>> logger)
{
_settings = settings;
_logger = logger;
}
public async ValueTask Migrate()
{
var newMeta = Path.Combine(_settings.DataDirectory, OldPath);
if (!Directory.Exists(newMeta))
{
Directory.CreateDirectory(newMeta);
}
foreach (var fe in Directory.EnumerateFiles(_settings.DataDirectory))
{
var filename = Path.GetFileNameWithoutExtension(fe);
if (!Guid.TryParse(filename, out var id)) continue;
var fp = MapOldMeta(id);
if (File.Exists(fp))
{
_logger.LogInformation("Migrating metadata for {file}", fp);
try
{
var oldJson = await File.ReadAllTextAsync(fp);
if (!ShouldMigrate(oldJson)) continue;
var old = JsonConvert.DeserializeObject<TOld>(oldJson);
if(old == null) continue;
var newObj = MigrateModel(old);
await File.WriteAllTextAsync(MapNewMeta(id), JsonConvert.SerializeObject(newObj));
// delete old metadata
File.Delete(fp);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error migrating metadata: {Message}", ex.Message);
}
}
}
}
protected abstract string OldPath { get; }
protected abstract string NewPath { get; }
protected abstract bool ShouldMigrate(string json);
protected abstract TNew MigrateModel(TOld old);
private string MapOldMeta(Guid id) =>
Path.ChangeExtension(Path.Join(_settings.DataDirectory, OldPath, id.ToString()), ".json");
private string MapNewMeta(Guid id) =>
Path.ChangeExtension(Path.Join(_settings.DataDirectory, NewPath, id.ToString()), ".json");
}