Commit Graph

10 Commits

Author SHA1 Message Date
Joseph Doherty 7dcbacd5ca fix(etl): address Codex MCP review findings for Phase 2
- Filter MERGE SQL columns to only include columns that exist in destination
  (allColumns and updateColumns were using unfiltered source columns)
- Fix schema-qualified table names to use proper [schema].[table] format
  instead of wrapping entire name in single brackets
- Add empty column mapping validation to throw early if no columns intersect
- Add JdeDateTransformer output column collision detection in OnInitialize
- Add TODO comment for WithCommandTimeout (stored but not yet passed to
  destinations)
- Add tests for FormatQualifiedTableName and output column collision
2026-01-03 11:27:07 -05:00
Joseph Doherty 0820a9b024 feat(etl): add collision detection to ColumnRenameTransformer 2026-01-03 10:50:03 -05:00
Joseph Doherty ae84cb3d75 feat(etl): add MapOrdinal and date validation with sentinel to JdeDateTransformer
- Add DefaultInvalidDateSentinel (1900-01-01) for invalid date handling
- Add optional invalidDateSentinel constructor parameter
- Add MapOrdinal override returning -1 for computed DateTime column
- Add GetDataTypeName override returning "datetime" for computed column
- Update ParseJdeDateTime with comprehensive validation:
  - Validate date is positive
  - Validate century (0 or 1)
  - Validate year (0-99)
  - Validate day of year (1-366 and respects leap year)
  - Validate time components (hours 0-23, minutes/seconds 0-59)
- Add tests for all new functionality
2026-01-03 10:46:19 -05:00
Joseph Doherty 577e67ec64 feat(etl): add MapOrdinal override to ColumnDropTransformer 2026-01-03 10:35:54 -05:00
Joseph Doherty 506ba5c61d feat(etl): add binary method overrides to DataTransformerBase
Add virtual methods to DataTransformerBase for GetBytes, GetChars,
GetData, and GetDataTypeName that properly handle computed columns
by throwing NotSupportedException when MapOrdinal returns -1.

Update TransformingDataReader to delegate these methods to the
transformer instead of directly to the source reader.
2026-01-03 10:33:13 -05:00
Joseph Doherty f5468d019f 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
2026-01-03 10:28:49 -05:00
Joseph Doherty 74c3f37446 feat(etl): implement JdeDateTransformer for Julian date parsing
Add transformer that combines JDE Julian date (CYYDDD) and time (HHMMSS)
columns into a single DateTime column. Includes static ParseJdeDateTime
method for direct date conversion.
2026-01-03 09:16:11 -05:00
Joseph Doherty 81cb0df6bf feat(etl): implement ColumnRenameTransformer
Add transformer for renaming columns in the data stream during ETL.
Supports case-insensitive column name matching and multiple renames.
2026-01-03 09:13:02 -05:00
Joseph Doherty f1b7809a45 feat(etl): implement ColumnDropTransformer
Add a data transformer that removes specified columns from the data stream.
Columns are matched by name (case-insensitive) and multiple columns can be
dropped in a single transformer. Includes comprehensive tests using NSubstitute
for mock IDataReader.
2026-01-03 09:10:54 -05:00
Joseph Doherty 6e7bcadf68 feat(etl): implement TransformingDataReader and DataTransformerBase
Add core transformer infrastructure for the ETL pipeline:
- DataTransformerBase: abstract base class with virtual methods for
  field count, names, types, values, ordinals, and null checking
- TransformingDataReader: IDataReader wrapper that delegates to
  transformer, enabling on-the-fly data transformations
2026-01-03 09:08:17 -05:00