新增 FlowScope Git 包雏形
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FlowScope.Save
|
||||
{
|
||||
public sealed class SaveMigrationRegistry
|
||||
{
|
||||
private readonly Dictionary<MigrationKey, ISaveMigration> _migrations = new();
|
||||
|
||||
public void Register(ISaveMigration migration)
|
||||
{
|
||||
if (migration == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(migration));
|
||||
}
|
||||
|
||||
_migrations[new MigrationKey(migration.Key, migration.FromVersion)] = migration;
|
||||
}
|
||||
|
||||
public string Migrate(
|
||||
string key,
|
||||
int fromVersion,
|
||||
int currentVersion,
|
||||
string json)
|
||||
{
|
||||
var current = fromVersion;
|
||||
var payload = json;
|
||||
while (current < currentVersion)
|
||||
{
|
||||
if (!_migrations.TryGetValue(new MigrationKey(key, current), out var migration) ||
|
||||
migration.ToVersion != current + 1)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Missing save migration for key '{key}' from version {current}.");
|
||||
}
|
||||
|
||||
payload = migration.Migrate(payload);
|
||||
current = migration.ToVersion;
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
private readonly struct MigrationKey : IEquatable<MigrationKey>
|
||||
{
|
||||
private readonly string _key;
|
||||
private readonly int _fromVersion;
|
||||
|
||||
public MigrationKey(string key, int fromVersion)
|
||||
{
|
||||
_key = key ?? string.Empty;
|
||||
_fromVersion = fromVersion;
|
||||
}
|
||||
|
||||
public bool Equals(MigrationKey other)
|
||||
{
|
||||
return _key == other._key && _fromVersion == other._fromVersion;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is MigrationKey other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ((_key != null ? _key.GetHashCode() : 0) * 397) ^ _fromVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user