public ReaderMapping(IDataRecord dataReader, bool addStartLine, bool addRecNum, bool addEndLine, bool addErrorField) { var fileReader = dataReader as IFileReader; if (fileReader != null) { ColumnErrorDictionary = new ColumnErrorDictionary(fileReader); } var readerColumns = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var fieldCount = 0; for (var col = 0; col < dataReader.FieldCount; col++) { ImmutableColumn column; if (fileReader != null) { var icol = fileReader.GetColumn(col); if (icol is ImmutableColumn imcol) { column = imcol; } else { column = new ImmutableColumn(icol.Name, icol.ValueFormat, col, icol.Convert, icol.DestinationName, icol.Ignore, icol.Part, icol.PartSplitter, icol.PartToEnd, icol.TimePart, icol.TimePartFormat, icol.TimeZonePart); } } else { column = new ImmutableColumn(dataReader.GetName(col), new ImmutableValueFormat(dataReader.GetFieldType(col).GetDataType()), col); } m_ReaderColumnsAll.Add(column.Name); if (column.Ignore) { continue; } m_DateTableColumns.Add(column); readerColumns.Add(column.Name); m_Mapping.Add(col, fieldCount++); } // add fields if (addStartLine && !readerColumns.Contains(ReaderConstants.cStartLineNumberFieldName)) { DataTableStartLine = fieldCount++; m_DateTableColumns.Add(new ImmutableColumn(ReaderConstants.cStartLineNumberFieldName, new ImmutableValueFormat(DataType.Integer), DataTableStartLine)); } else { DataTableStartLine = -1; } if (addRecNum && !readerColumns.Contains(ReaderConstants.cRecordNumberFieldName)) { DataTableRecNum = fieldCount++; m_DateTableColumns.Add(new ImmutableColumn(ReaderConstants.cRecordNumberFieldName, new ImmutableValueFormat(DataType.Integer), DataTableRecNum)); } else { DataTableRecNum = -1; } if (addEndLine && !readerColumns.Contains(ReaderConstants.cEndLineNumberFieldName)) { DataTableEndLine = fieldCount++; m_DateTableColumns.Add(new ImmutableColumn(ReaderConstants.cEndLineNumberFieldName, new ImmutableValueFormat(DataType.Integer), DataTableEndLine)); } else { DataTableEndLine = -1; } if (addErrorField && !readerColumns.Contains(ReaderConstants.cErrorField)) { DataTableErrorField = fieldCount; m_DateTableColumns.Add(new ImmutableColumn(ReaderConstants.cErrorField, new ImmutableValueFormat(), DataTableErrorField)); } else { DataTableErrorField = -1; } }
/// <summary> /// Gets the column information based on the SQL Source, but overwritten with the definitions /// </summary> /// <param name="generalFormat"> /// general value format for not explicitly specified columns format /// </param> /// <param name="columnDefinitions"></param> /// <param name="sourceSchemaDataReader">The reader for the source.</param> /// <returns></returns> /// <exception cref="ArgumentNullException">reader</exception> public static IEnumerable <IColumn> GetColumnInformation(IValueFormat generalFormat, IReadOnlyCollection <IColumn> columnDefinitions, DataTable schemaTable) { if (schemaTable == null) { throw new ArgumentNullException(nameof(schemaTable)); } var result = new List <WriterColumn>(); var colName = new BiDirectionalDictionary <int, string>(); // Make names unique and fill the dictionary foreach (DataRow schemaRow in schemaTable.Rows) { var colNo = (int)schemaRow[SchemaTableColumn.ColumnOrdinal]; var newName = StringUtils.MakeUniqueInCollection(colName.Values, schemaRow[SchemaTableColumn.ColumnName].ToString()); colName.Add(colNo, newName); } foreach (DataRow schemaRow in schemaTable.Rows) { var colNo = (int)schemaRow[SchemaTableColumn.ColumnOrdinal]; var column = columnDefinitions.FirstOrDefault(x => x.Name.Equals(colName[colNo], StringComparison.OrdinalIgnoreCase)); if (column != null && column.Ignore) { continue; } // Based on the data Type in the reader defined and the general format create the value format var valueFormat = column?.ValueFormat ?? new ImmutableValueFormat( ((Type)schemaRow[SchemaTableColumn.DataType]).GetDataType(), generalFormat.DateFormat, generalFormat.DateSeparator, generalFormat.TimeSeparator, generalFormat.NumberFormat, generalFormat.GroupSeparator, generalFormat.DecimalSeparator, generalFormat.True, generalFormat.False, generalFormat.DisplayNullAs); var fieldLength = Math.Max((int)schemaRow[SchemaTableColumn.ColumnSize], 0); switch (valueFormat.DataType) { case DataType.Integer: fieldLength = 10; break; case DataType.Boolean: { var lenTrue = valueFormat.True.Length; var lenFalse = valueFormat.False.Length; fieldLength = lenTrue > lenFalse ? lenTrue : lenFalse; break; } case DataType.Double: case DataType.Numeric: fieldLength = 28; break; case DataType.DateTime: fieldLength = valueFormat.DateFormat.Length; break; case DataType.Guid: fieldLength = 36; break; case DataType.String: case DataType.TextToHtml: case DataType.TextToHtmlFull: case DataType.TextPart: break; default: throw new ArgumentOutOfRangeException(); } var constantTimeZone = string.Empty; var columnOrdinalTimeZoneReader = -1; // the timezone information if (column != null) { var tz = column.TimeZonePart; if (!string.IsNullOrEmpty(tz)) { var tzInfo = tz.GetPossiblyConstant(); if (tzInfo.Item2) { constantTimeZone = tzInfo.Item1; } else { if (colName.TryGetByValue(tzInfo.Item1, out var ordinal)) { columnOrdinalTimeZoneReader = ordinal; } } } } var ci = new WriterColumn(colName[colNo], colNo, valueFormat, fieldLength, constantTimeZone, columnOrdinalTimeZoneReader); result.Add(ci); // add an extra column for the time, reading columns they get combined, writing them they // get separated again if (column == null || string.IsNullOrEmpty(column.TimePart) || colName.ContainsValue(column.TimePart)) { continue; } if (ci.ValueFormat.DateFormat.IndexOfAny(new[] { 'h', 'H', 'm', 's' }) != -1) { Logger.Warning( $"'{ci.Name}' will create a separate time column '{column.TimePart}' but seems to write time itself '{ci.ValueFormat.DateFormat}'"); } // In case we have a split column, add the second column (unless the column is also present result.Add(new WriterColumn(column.TimePart, colNo, new ImmutableValueFormat(DataType.DateTime, column.TimePartFormat, timeSeparator: column.ValueFormat.TimeSeparator), column.TimePartFormat.Length, constantTimeZone, columnOrdinalTimeZoneReader)); } return(result); }