feat(etl): add MapOrdinal to IDataTransformer interface
Add MapOrdinal method to the IDataTransformer interface and provide a default implementation in DataTransformerBase. This enables transformers to report the mapping between transformed ordinals and source ordinals, supporting use cases like computed columns which return -1 to indicate no source ordinal. - Add MapOrdinal(int, IDataReader) to IDataTransformer interface - Add virtual MapOrdinal implementation in DataTransformerBase - Add DataTransformerBaseTests with test for default behavior
This commit is contained in:
@@ -18,4 +18,13 @@ public interface IDataTransformer
|
||||
/// Gets the name of this transformer for logging and identification.
|
||||
/// </summary>
|
||||
string TransformerName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Maps a transformed ordinal to the source ordinal.
|
||||
/// Returns -1 for computed columns that have no source ordinal.
|
||||
/// </summary>
|
||||
/// <param name="transformedOrdinal">The ordinal in the transformed output.</param>
|
||||
/// <param name="source">The source data reader.</param>
|
||||
/// <returns>The corresponding source ordinal, or -1 for computed columns.</returns>
|
||||
int MapOrdinal(int transformedOrdinal, IDataReader source);
|
||||
}
|
||||
|
||||
@@ -62,4 +62,13 @@ public abstract class DataTransformerBase : IDataTransformer
|
||||
/// Override to handle null transformations.
|
||||
/// </summary>
|
||||
public virtual bool IsDBNull(int ordinal, IDataReader source) => source.IsDBNull(ordinal);
|
||||
|
||||
/// <summary>
|
||||
/// Maps a transformed ordinal to the source ordinal.
|
||||
/// Override to support column reordering or computed columns.
|
||||
/// </summary>
|
||||
/// <param name="transformedOrdinal">The ordinal in the transformed output.</param>
|
||||
/// <param name="source">The source data reader.</param>
|
||||
/// <returns>The corresponding source ordinal, or -1 for computed columns.</returns>
|
||||
public virtual int MapOrdinal(int transformedOrdinal, IDataReader source) => transformedOrdinal;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Data;
|
||||
using JdeScoping.DataSync.Etl.Transformers;
|
||||
using NSubstitute;
|
||||
|
||||
namespace JdeScoping.DataSync.Tests.Etl.Transformers;
|
||||
|
||||
public class DataTransformerBaseTests
|
||||
{
|
||||
[Fact]
|
||||
public void MapOrdinal_DefaultImplementation_ReturnsOrdinalUnchanged()
|
||||
{
|
||||
// Arrange
|
||||
var transformer = new PassThroughTransformer();
|
||||
var reader = CreateMockReader(new[] { "A", "B", "C" });
|
||||
|
||||
// Act
|
||||
var result = transformer.MapOrdinal(1, reader);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1, result);
|
||||
}
|
||||
|
||||
private static IDataReader CreateMockReader(string[] columns)
|
||||
{
|
||||
var reader = Substitute.For<IDataReader>();
|
||||
reader.FieldCount.Returns(columns.Length);
|
||||
for (int i = 0; i < columns.Length; i++)
|
||||
{
|
||||
var index = i;
|
||||
reader.GetName(index).Returns(columns[index]);
|
||||
reader.GetOrdinal(columns[index]).Returns(index);
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
|
||||
private class PassThroughTransformer : DataTransformerBase
|
||||
{
|
||||
public override string TransformerName => "PassThrough";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user