Skip to content

Commit

Permalink
Fixed a bug in the key prefix and added a test of failed migration (c…
Browse files Browse the repository at this point in the history
…onverting a URI to a ulong)
  • Loading branch information
halgari committed Oct 15, 2024
1 parent ccfb849 commit 3f82eed
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public bool IsRetract
public ValueTag ValueTag
{
get => (ValueTag)((_lower >> 1) & 0x7F);
init => _lower = (_lower & 0xFF00000000000001) | ((ulong)value << 1);
init => _lower = (_lower & 0xFFFFFFFFFFFFFF01) | ((ulong)value << 1);
}

/// <summary>
Expand Down
27 changes: 20 additions & 7 deletions src/NexusMods.MnemonicDB.Abstractions/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,27 @@ public static void ConvertValue<TWriter>(this ValueTag srcTag, ReadOnlySpan<byte
where TWriter : IBufferWriter<byte>
{

switch (srcTag, destTag)
try
{
case (ValueTag.UInt8, ValueTag.UInt16):
WriteUnmanaged((ushort)MemoryMarshal.Read<byte>(srcSpan), destWriter);
break;

default:
throw new NotSupportedException("Conversion not supported from " + srcTag + " to " + destTag);
switch (srcTag, destTag)
{
case (ValueTag.UInt8, ValueTag.UInt16):
WriteUnmanaged((ushort)MemoryMarshal.Read<byte>(srcSpan), destWriter);
break;
case (ValueTag.Utf8, ValueTag.UInt64):
{
var val = srcTag.Read<string>(srcSpan);
WriteUnmanaged(Convert.ToUInt64(val), destWriter);
break;
}

default:
throw new NotSupportedException("Conversion not supported from " + srcTag + " to " + destTag);
}
}
catch (Exception e)
{
throw new InvalidOperationException($"Failed to convert ({srcTag.Read<object>(srcSpan)}) value from " + srcTag + " to " + destTag, e);
}
}

Expand Down
30 changes: 30 additions & 0 deletions tests/NexusMods.MnemonicDB.Tests/MigrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,34 @@ public async Task CanRemoveIndex()
Action act = () => Connection.Db.Datoms(Mod.Source, new Uri("http://mod0.com")).ToArray();
act.Should().Throw<InvalidOperationException>();
}

[Fact]
public async Task CanConvertValues()
{
await AddData();

var cache = Connection.AttributeCache;
var aid = cache.GetAttributeId(Mod.Description.Id);
cache.IsIndexed(aid).Should().BeFalse();

var withIndex = new ULongAttribute(Mod.Description.Id.Namespace, Mod.Description.Id.Name) { IsIndexed = true, IsOptional = false };
var prevTxId = Connection.Db.BasisTxId;

await Connection.UpdateSchema(withIndex);

Connection.Db.BasisTxId.Value.Should().Be(prevTxId.Value + 1);
cache.IsIndexed(cache.GetAttributeId(Mod.Description.Id)).Should().BeTrue();

var foundByDocs = Connection.Db.Datoms(withIndex, 0UL).ToArray();
foundByDocs.Length.Should().Be(10);
}

[Fact]
public async Task ConvertingValuesIncorrectlyFails()
{
await AddData();
var withIndex = new ULongAttribute(Mod.Source.Id.Namespace, Mod.Source.Id.Name) { IsIndexed = true, IsOptional = false };
var act = async () => await Connection.UpdateSchema(withIndex);
await act.Should().ThrowAsync<InvalidOperationException>("Converting values for attribute Mod.Source from String to ULong where the source is a URI should fail");
}
}

0 comments on commit 3f82eed

Please sign in to comment.