Пример #1
0
        /// <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);
        }