Skip to content

Commit

Permalink
Fixed default value when there value is NOT DbNull
Browse files Browse the repository at this point in the history
  • Loading branch information
seesharper committed Jan 10, 2025
1 parent 9a9c923 commit 1ba3d60
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 10 deletions.
11 changes: 11 additions & 0 deletions src/DbReader.Tests/InstanceReaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,17 @@ public void ShouldUseDefaultValue()
instance.Property.Value.ShouldBe(42);
}

[Fact]
public void ShouldNotUseDefaultValue()
{
var dataRecord = new { Id = 1, Property = 42 }.ToDataRecord();
DbReaderOptions.WhenReading<CustomValueType>().Use((dr, i) => new CustomValueType(dr.GetInt32(i))).WithDefaultValue(new CustomValueType(82));
var reader = GetReader<ClassWithProperty<CustomValueType>>();
var instance = reader.Read(dataRecord, string.Empty);
instance.Property.Value.ShouldBe(42);
}



public class CustomValueType
{
Expand Down
4 changes: 2 additions & 2 deletions src/DbReader/Construction/ConstructorReaderMethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/// an instance of <typeparamref name="T"/> using constructor arguments.
/// </summary>
/// <typeparam name="T">The type of object to be created.</typeparam>
public class ConstructorReaderMethodBuilder<T> : ReaderMethodBuilder<T>
public class ConstructorReaderMethodBuilder<T> : ReaderMethodBuilder<T>
{
private readonly IConstructorSelector constructorSelector;

Expand Down Expand Up @@ -50,7 +50,7 @@ private void LoadConstructorArguments(ILGenerator il, ConstructorInfo constructo
for (int parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++)
{
EmitCheckForValidOrdinal(il, parameterIndex, tryLoadNullValue);
EmitCheckForDbNull(il, parameterIndex, tryLoadNullValue);
EmitGoLabelIfDbNull(il, parameterIndex, tryLoadNullValue);
}

for (int i = 0; i < parameters.Length; i++)
Expand Down
10 changes: 7 additions & 3 deletions src/DbReader/Construction/PropertyReaderMethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,16 @@ private void EmitPropertySetters(ILGenerator generator, LocalBuilder instanceVar
private void EmitPropertySetter(ILGenerator il, PropertyInfo property, int propertyIndex, LocalBuilder instanceVariable)
{
MethodInfo getMethod = MethodSelector.Execute(property.PropertyType);
var checkForDefaultValueLabel = il.DefineLabel();
var endLabel = il.DefineLabel();
EmitCheckForValidOrdinal(il, propertyIndex, endLabel);
EmitCheckForDbNull(il, propertyIndex, endLabel);
EmitCheckForValidOrdinal(il, propertyIndex, checkForDefaultValueLabel);
EmitGoLabelIfDbNull(il, propertyIndex, checkForDefaultValueLabel);
LoadInstance(il, instanceVariable);
EmitGetValue(il, propertyIndex, getMethod, property.PropertyType);
EmitCallPropertySetterMethod(il, property);
il.MarkLabel(endLabel);
il.MarkLabel(checkForDefaultValueLabel);
EmitCheckForValidOrdinal(il, propertyIndex, endLabel);
EmitGoLabelIfNotDbNull(il, propertyIndex, endLabel);
if (ValueConverter.HasDefaultValue(property.PropertyType))
{
var openGenericGetDefaultValueMethod = typeof(ValueConverter).GetMethod(nameof(ValueConverter.GetDefaultValue), BindingFlags.Static | BindingFlags.NonPublic);
Expand All @@ -148,6 +151,7 @@ private void EmitPropertySetter(ILGenerator il, PropertyInfo property, int prope
il.Emit(OpCodes.Call, getDefaultValueMethod);
EmitCallPropertySetterMethod(il, property);
}
il.MarkLabel(endLabel);
}
}
}
23 changes: 18 additions & 5 deletions src/DbReader/Construction/ReaderMethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ protected void EmitCheckForValidOrdinal(ILGenerator il, int index, Label trueLab
LoadOrdinal(il, index);
LoadIntegerValueOfMinusOne(il);
EmitCompareValues(il);
EmitGotoEndLabelIfValueIsTrue(il, trueLabel);
EmitGotoLabelIfValueIsTrue(il, trueLabel);
}

/// <summary>
Expand All @@ -76,12 +76,20 @@ protected void EmitCheckForValidOrdinal(ILGenerator il, int index, Label trueLab
/// <param name="index">The index of the ordinal to check.</param>
/// <param name="trueLabel">The <see cref="Label"/> that represents where to jump if
/// the value about to be read from the <see cref="IDataRecord"/> is <see cref="DBNull"/>.</param>
protected void EmitCheckForDbNull(ILGenerator il, int index, Label trueLabel)
protected void EmitGoLabelIfDbNull(ILGenerator il, int index, Label trueLabel)
{
LoadDataRecord(il);
LoadOrdinal(il, index);
EmitCallIsDbNullMethod(il);
EmitGotoEndLabelIfValueIsTrue(il, trueLabel);
EmitGotoLabelIfValueIsTrue(il, trueLabel);
}

protected void EmitGoLabelIfNotDbNull(ILGenerator il, int index, Label falseLabel)

Check warning on line 87 in src/DbReader/Construction/ReaderMethodBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ReaderMethodBuilder<T>.EmitGoLabelIfNotDbNull(ILGenerator, int, Label)'

Check warning on line 87 in src/DbReader/Construction/ReaderMethodBuilder.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ReaderMethodBuilder<T>.EmitGoLabelIfNotDbNull(ILGenerator, int, Label)'
{
LoadDataRecord(il);
LoadOrdinal(il, index);
EmitCallIsDbNullMethod(il);
EmitGotoLabelIfValueIsFalse(il, falseLabel);
}

/// <summary>
Expand Down Expand Up @@ -168,9 +176,14 @@ private static void EmitCompareValues(ILGenerator il)
il.Emit(OpCodes.Ceq);
}

private static void EmitGotoEndLabelIfValueIsTrue(ILGenerator il, Label endLabel)
private static void EmitGotoLabelIfValueIsTrue(ILGenerator il, Label trueLabel)
{
il.Emit(OpCodes.Brtrue, trueLabel);
}

private static void EmitGotoLabelIfValueIsFalse(ILGenerator il, Label trueLabel)
{
il.Emit(OpCodes.Brtrue, endLabel);
il.Emit(OpCodes.Brfalse, trueLabel);
}

private static Func<IDataRecord, int[], T> CreateDelegate(IMethodSkeleton methodSkeleton)
Expand Down

0 comments on commit 1ba3d60

Please sign in to comment.