diff --git a/NEW/src/JdeScoping.DataSync/Etl/Contracts/IDataTransformer.cs b/NEW/src/JdeScoping.DataSync/Etl/Contracts/IDataTransformer.cs index f3ac31c..bb96bcd 100644 --- a/NEW/src/JdeScoping.DataSync/Etl/Contracts/IDataTransformer.cs +++ b/NEW/src/JdeScoping.DataSync/Etl/Contracts/IDataTransformer.cs @@ -18,4 +18,13 @@ public interface IDataTransformer /// Gets the name of this transformer for logging and identification. /// string TransformerName { get; } + + /// + /// Maps a transformed ordinal to the source ordinal. + /// Returns -1 for computed columns that have no source ordinal. + /// + /// The ordinal in the transformed output. + /// The source data reader. + /// The corresponding source ordinal, or -1 for computed columns. + int MapOrdinal(int transformedOrdinal, IDataReader source); } diff --git a/NEW/src/JdeScoping.DataSync/Etl/Transformers/DataTransformerBase.cs b/NEW/src/JdeScoping.DataSync/Etl/Transformers/DataTransformerBase.cs index 386a88b..f3819f7 100644 --- a/NEW/src/JdeScoping.DataSync/Etl/Transformers/DataTransformerBase.cs +++ b/NEW/src/JdeScoping.DataSync/Etl/Transformers/DataTransformerBase.cs @@ -62,4 +62,13 @@ public abstract class DataTransformerBase : IDataTransformer /// Override to handle null transformations. /// public virtual bool IsDBNull(int ordinal, IDataReader source) => source.IsDBNull(ordinal); + + /// + /// Maps a transformed ordinal to the source ordinal. + /// Override to support column reordering or computed columns. + /// + /// The ordinal in the transformed output. + /// The source data reader. + /// The corresponding source ordinal, or -1 for computed columns. + public virtual int MapOrdinal(int transformedOrdinal, IDataReader source) => transformedOrdinal; } diff --git a/NEW/tests/JdeScoping.DataSync.Tests/Etl/Transformers/DataTransformerBaseTests.cs b/NEW/tests/JdeScoping.DataSync.Tests/Etl/Transformers/DataTransformerBaseTests.cs new file mode 100644 index 0000000..c8ae020 --- /dev/null +++ b/NEW/tests/JdeScoping.DataSync.Tests/Etl/Transformers/DataTransformerBaseTests.cs @@ -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(); + 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"; + } +}