Exemplo n.º 1
0
        public static DetectTypeItem DetectType(string[] values)
        {
            var item = new DetectTypeItem();

            DetectType(ref item, values);
            return(item);
        }
Exemplo n.º 2
0
        public static DetectTypeItem DetectType(string[] values)
        {
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }
            var log              = new List <string>();
            var type             = typeof(string);
            var sizeMin          = int.MaxValue;
            var sizeMax          = 0;
            var decimalPrecision = 0;
            var decimalScale     = 0;
            var isAscii          = true;
            var haveEmpty        = false;
            // Order matters. Strictest on the top. First available type will be returned.
            // If all values can be parsed to Int16 then it can be parsed to Int32 and Int64 too.
            var tcs = new TypeCode[]
            {
                TypeCode.Boolean,
                TypeCode.Byte,
                TypeCode.SByte,
                TypeCode.Int16,
                TypeCode.Int32,
                TypeCode.Int64,
                TypeCode.UInt16,
                TypeCode.UInt32,
                TypeCode.UInt64,
                TypeCode.Single,
                TypeCode.Char,
                TypeCode.DateTime,
                TypeCode.Double,
                TypeCode.Decimal,
                TypeCode.String,
                // TypeCode.DBNull,
                // TypeCode.Empty,
                // TypeCode.Object,
            }.ToList();
            // All available types.
            var available = new Dictionary <TypeCode, Type>();

            tcs.ForEach(x => available.Add(x, Type.GetType(nameof(System) + "." + x)));
            //Convert.ChangeType(value, colType);
            for (int i = 0; i < values.Length; i++)
            {
                var value = values[i];
                if (string.IsNullOrEmpty(value))
                {
                    haveEmpty = true;
                    continue;
                }
                // Determine string limits.
                sizeMin  = Math.Min(sizeMin, value.Length);
                sizeMax  = Math.Max(sizeMax, value.Length);
                isAscii &= value.All(x => x < 128);
                // Get available types to test against.
                var availableTypeCodes = available.Keys.ToArray();
                // If only string was left.
                if (availableTypeCodes.Length == 1 && availableTypeCodes[0] == TypeCode.String)
                {
                    break;
                }
                // Test against available types.
                foreach (var tc in availableTypeCodes)
                {
                    switch (tc)
                    {
                    case TypeCode.Boolean:
                        bool resultBool;
                        if (!bool.TryParse(value, out resultBool))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Byte:
                        byte resultByte;
                        if (!byte.TryParse(value, out resultByte))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Char:
                        char resultChar;
                        if (!char.TryParse(value, out resultChar))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.DateTime:
                        DateTime resultDateTime;
                        if (!DateTime.TryParse(value, out resultDateTime))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Decimal:
                        decimal resultDecimal;
                        if (!decimal.TryParse(value, out resultDecimal))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        var d = (System.Data.SqlTypes.SqlDecimal)resultDecimal;
                        decimalPrecision = Math.Max(decimalPrecision, d.Precision);
                        decimalScale     = Math.Max(decimalScale, d.Scale);
                        break;

                    case TypeCode.Double:
                        double resultDouble;
                        if (!double.TryParse(value, out resultDouble))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Int16:
                        short resultShort;
                        if (!short.TryParse(value, out resultShort))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Int32:
                        int resultInt;
                        if (!int.TryParse(value, out resultInt))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Int64:
                        long resultLong;
                        if (!long.TryParse(value, out resultLong))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.SByte:
                        sbyte resultSByte;
                        if (!sbyte.TryParse(value, out resultSByte))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.Single:
                        float resultFloat;
                        if (!float.TryParse(value, out resultFloat))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.UInt16:
                        ushort resultUShort;
                        if (!ushort.TryParse(value, out resultUShort))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.UInt32:
                        uint resultUInt;
                        if (!uint.TryParse(value, out resultUInt))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    case TypeCode.UInt64:
                        ulong resultULong;
                        if (!ulong.TryParse(value, out resultULong))
                        {
                            log.Add(string.Format($"Removed {tc,-8} at {i,4} line. Value: {value}"));
                            available.Remove(tc);
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            type = available.FirstOrDefault().Value;
            var item = new DetectTypeItem()
            {
                Type             = type,
                MinLength        = sizeMin,
                MaxLength        = sizeMax,
                IsAscii          = isAscii,
                DecimalPrecision = decimalPrecision,
                DecimalScale     = decimalScale,
                IsRequired       = !haveEmpty,
                Log = log,
            };

            return(item);
        }
Exemplo n.º 3
0
        public static void DetectType(ref DetectTypeItem item, params string[] values)
        {
            if (values == null)
            {
                throw new ArgumentNullException(nameof(values));
            }
            if (item == null)
            {
                item = new DetectTypeItem();
            }
            // Order matters. Strictest on the top. First available type will be returned.
            // If all values can be parsed to Int16 then it can be parsed to Int32 and Int64 too.
            //Convert.ChangeType(value, colType);
            for (int i = 0; i < values.Length; i++)
            {
                var value = values[i];
                if (string.IsNullOrEmpty(value))
                {
                    item.IsRequired = false;
                    continue;
                }
                // If minimum length not set then use available, otherwise get smaller.
                item.MinLength = item.MinLength == 0 ? value.Length : Math.Min(item.MinLength, value.Length);
                // Determine maximum length.
                item.MaxLength = Math.Max(item.MaxLength, value.Length);
                // Value is not ASCII if character code is outside of 128.
                item.IsAscii &= value.All(x => x < 128);
                // Test against available types.
                var tcs = item.AvailableTypes.ToArray();
                foreach (var tc in tcs)
                {
                    var remove = false;
                    switch (tc)
                    {
                    case TypeCode.Boolean:
                        bool resultBool;
                        if (!bool.TryParse(value, out resultBool))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.Byte:
                        byte resultByte;
                        if (!byte.TryParse(value, out resultByte))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.Char:
                        char resultChar;
                        if (!char.TryParse(value, out resultChar))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.DateTime:
                        DateTime resultDateTime;
                        if (!DateTime.TryParse(value, out resultDateTime))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.Decimal:
                        decimal resultDecimal;
                        if (!decimal.TryParse(value, out resultDecimal))
                        {
                            remove = true;
                        }
                        var d = (System.Data.SqlTypes.SqlDecimal)resultDecimal;
                        item.DecimalPrecision = Math.Max(item.DecimalPrecision, d.Precision);
                        item.DecimalScale     = Math.Max(item.DecimalScale, d.Scale);
                        break;

                    case TypeCode.Double:
                        double resultDouble;
                        if (!double.TryParse(value, out resultDouble))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.Int16:
                        short resultShort;
                        if (!short.TryParse(value, out resultShort) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.Int32:
                        int resultInt;
                        if (!int.TryParse(value, out resultInt) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.Int64:
                        long resultLong;
                        if (!long.TryParse(value, out resultLong) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.SByte:
                        sbyte resultSByte;
                        if (!sbyte.TryParse(value, out resultSByte) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.Single:
                        float resultFloat;
                        if (!float.TryParse(value, out resultFloat) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.UInt16:
                        ushort resultUShort;
                        if (!ushort.TryParse(value, out resultUShort) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.UInt32:
                        uint resultUInt;
                        if (!uint.TryParse(value, out resultUInt) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    case TypeCode.UInt64:
                        ulong resultULong;
                        if (!ulong.TryParse(value, out resultULong) && !HaveLeadingZero(value))
                        {
                            remove = true;
                        }
                        break;

                    default:
                        break;
                    }
                    if (remove)
                    {
                        item.Log.Add(string.Format($"Removed {tc,-8} - Value: {value}"));
                        item.AvailableTypes.Remove(tc);
                        item.Type = item.AvailableTypes.Count == 0 ? null : Type.GetType("System." + item.AvailableTypes[0]);
                    }
                }
            }
        }