Skip to content

Commit 02e23d9

Browse files
committed
Add deserialization hook to bsonmapper
1 parent 25b0940 commit 02e23d9

File tree

3 files changed

+95
-10
lines changed

3 files changed

+95
-10
lines changed

LiteDB.Tests/Database/DocumentUpgrade_Tests.cs

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using FluentAssertions;
1+
using FluentAssertions;
22

33
using LiteDB.Engine;
44

@@ -38,10 +38,24 @@ public void DocumentUpgrade_Test()
3838

3939
ms.Position = 0;
4040

41-
var engine = new LiteEngine(new EngineSettings
41+
using var engine = new LiteEngine(new EngineSettings
4242
{
4343
DataStream = ms,
44-
ReadTransform = ReadTransform
44+
ReadTransform = (collectionName, val) =>
45+
{
46+
if (val is not BsonDocument doc)
47+
{
48+
return val;
49+
}
50+
51+
if (doc.TryGetValue("version", out var version) && version.AsInt32 == 1)
52+
{
53+
doc["version"] = 2;
54+
doc["age"] = 30;
55+
}
56+
57+
return val;
58+
}
4559
});
4660

4761
using (var db = new LiteDatabase(engine))
@@ -58,19 +72,62 @@ public void DocumentUpgrade_Test()
5872
}
5973
}
6074

61-
private BsonValue ReadTransform(string arg1, BsonValue val)
75+
[Fact]
76+
public void DocumentUpgrade_BsonMapper_Test()
6277
{
63-
if (!(val is BsonDocument bdoc))
78+
var ms = new MemoryStream();
79+
using (var db = new LiteDatabase(ms))
6480
{
65-
return val;
81+
var col = db.GetCollection("col");
82+
83+
col.Insert(new BsonDocument { ["version"] = 1, ["_id"] = 1, ["name"] = "John" });
6684
}
6785

68-
if (bdoc.TryGetValue("version", out var version) && version.AsInt32 == 1)
86+
ms.Position = 0;
87+
88+
using (var db = new LiteDatabase(ms))
6989
{
70-
bdoc["version"] = 2;
71-
bdoc["age"] = 30;
90+
var col = db.GetCollection("col");
91+
92+
col.Count().Should().Be(1);
93+
94+
var doc = col.FindById(1);
95+
96+
doc["version"].AsInt32.Should().Be(1);
97+
doc["name"].AsString.Should().Be("John");
98+
doc["age"].AsInt32.Should().Be(0);
7299
}
73100

74-
return val;
101+
ms.Position = 0;
102+
103+
var mapper = new BsonMapper();
104+
mapper.OnDeserialization = (sender, type, val) =>
105+
{
106+
if (val is not BsonDocument doc)
107+
{
108+
return val;
109+
}
110+
111+
if (doc.TryGetValue("version", out var version) && version.AsInt32 == 1)
112+
{
113+
doc["version"] = 2;
114+
doc["age"] = 30;
115+
}
116+
117+
return doc;
118+
};
119+
120+
using (var db = new LiteDatabase(ms, mapper))
121+
{
122+
var col = db.GetCollection("col");
123+
124+
col.Count().Should().Be(1);
125+
126+
var doc = col.FindById(1);
127+
128+
doc["version"].AsInt32.Should().Be(2);
129+
doc["name"].AsString.Should().Be("John");
130+
doc["age"].AsInt32.Should().Be(30);
131+
}
75132
}
76133
}

LiteDB/Client/Mapper/BsonMapper.Deserialize.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ namespace LiteDB
99
{
1010
public partial class BsonMapper
1111
{
12+
#region Deserialization Hooks
13+
14+
/// <summary>
15+
/// Delegate for deserialization callback.
16+
/// </summary>
17+
/// <param name="sender">The BsonMapper instance that triggered the deserialization.</param>
18+
/// <param name="target">The target type for deserialization.</param>
19+
/// <param name="value">The BsonValue to be deserialized.</param>
20+
/// <returns>The deserialized BsonValue.</returns>
21+
public delegate BsonValue DeserializationCallback(BsonMapper sender, Type target, BsonValue value);
22+
23+
/// <summary>
24+
/// Gets called before deserialization of a value
25+
/// </summary>
26+
public DeserializationCallback? OnDeserialization { get; set; }
27+
28+
#endregion Deserialization Hooks
29+
1230
#region Basic direct .NET convert types
1331

1432
// direct bson types
@@ -78,6 +96,15 @@ public T Deserialize<T>(BsonValue value)
7896
/// </summary>
7997
public object Deserialize(Type type, BsonValue value)
8098
{
99+
if (OnDeserialization is not null)
100+
{
101+
var result = OnDeserialization(this, type, value);
102+
if (result is not null)
103+
{
104+
value = result;
105+
}
106+
}
107+
81108
// null value - null returns
82109
if (value.IsNull) return null;
83110

LiteDB/LiteDB.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<SignAssembly Condition="'$(OS)'=='Windows_NT'">true</SignAssembly>
2929
<AssemblyOriginatorKeyFile Condition="'$(Configuration)' == 'Release'">LiteDB.snk</AssemblyOriginatorKeyFile>
3030
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
31+
<LangVersion>9.0</LangVersion>
3132
</PropertyGroup>
3233

3334
<!--

0 commit comments

Comments
 (0)