Exemplo n.º 1
0
        [TestCase("5,000", typeof(int), "de-de", 5, 1, 0, 5)]                  //germans swap commas and dots

        public void Test_OneString_IsType(string guessFor, Type expectedGuess, string culture, int expectedStringLength, int expectedBefore, int expectedAfter, object expectedParseValue)
        {
            var cultureInfo = new CultureInfo(culture);
            var guesser     = new Guesser()
            {
                Culture = cultureInfo
            };

            guesser.AdjustToCompensateForValue(guessFor);
            Assert.AreEqual(expectedGuess, guesser.Guess.CSharpType, "Guessed Type did not match");
            Assert.AreEqual(expectedStringLength, guesser.Guess.Width, "String length guessed didn't match");
            Assert.AreEqual(expectedBefore, guesser.Guess.Size.NumbersBeforeDecimalPlace, "BeforeDecimalPlace didn't match");
            Assert.AreEqual(expectedAfter, guesser.Guess.Size.NumbersAfterDecimalPlace, "AfterDecimalPlace didn't match");


            TypeDeciderFactory factory = new TypeDeciderFactory(cultureInfo);

            if (factory.IsSupported(guesser.Guess.CSharpType))
            {
                Assert.AreEqual(expectedParseValue, factory.Create(guesser.Guess.CSharpType).Parse(guessFor));
            }
            else
            {
                Assert.AreEqual(expectedParseValue, guessFor);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Replaces all string representations for data types that can be problematic/ambiguous (e.g. DateTime or TimeSpan)
        ///  into hard typed objects using appropriate decider e.g. <see cref="DateTimeDecider"/>.
        /// </summary>
        /// <param name="dt"></param>
        protected void ConvertStringTypesToHardTypes(DataTable dt)
        {
            var dict = GetMapping(dt.Columns.Cast <DataColumn>(), out _);

            var factory = new TypeDeciderFactory(Culture);

            //These are the problematic Types
            Dictionary <Type, IDecideTypesForStrings> deciders = factory.Dictionary;

            //for each column in the destination
            foreach (var kvp in dict)
            {
                //if the destination column is a problematic type
                var dataType = kvp.Value.DataType.GetCSharpDataType();
                if (deciders.ContainsKey(dataType))
                {
                    //if it's already not a string then that's fine (hopefully its a legit Type e.g. DateTime!)
                    if (kvp.Key.DataType != typeof(string))
                    {
                        continue;
                    }

                    //create a new column hard typed to DateTime
                    var newColumn = dt.Columns.Add(kvp.Key.ColumnName + "_" + Guid.NewGuid().ToString(), dataType);

                    var decider = deciders[dataType];

                    //if it's a DateTime decider then guess DateTime culture based on values in the table
                    if (decider is DateTimeTypeDecider dtDecider)
                    {
                        dtDecider.GuessDateFormat(dt.Rows.Cast <DataRow>().Take(500).Select(r => r[kvp.Key] as string));
                    }

                    foreach (DataRow dr in dt.Rows)
                    {
                        //parse the value
                        dr[newColumn] = decider.Parse(dr[kvp.Key] as string) ?? DBNull.Value;
                    }

                    //if the DataColumn is part of the Primary Key of the DataTable (in memory)
                    //then we need to update the primary key to include the new column not the old one
                    if (dt.PrimaryKey != null && dt.PrimaryKey.Contains(kvp.Key))
                    {
                        dt.PrimaryKey = dt.PrimaryKey.Except(new [] { kvp.Key }).Union(new [] { newColumn }).ToArray();
                    }

                    var oldOrdinal = kvp.Key.Ordinal;

                    //drop the original column
                    dt.Columns.Remove(kvp.Key);

                    //rename the hard typed column to match the old column name
                    newColumn.ColumnName = kvp.Key.ColumnName;
                    if (oldOrdinal != -1)
                    {
                        newColumn.SetOrdinal(oldOrdinal);
                    }
                }
            }
        }
Exemplo n.º 3
0
        public void BigInt_TypeDeciderFactory()
        {
            var factory = new TypeDeciderFactory(new CultureInfo("en-US"));

            // The IDecideTypesForStrings for long should be DecimalTypeDecider
            Assert.IsTrue(factory.Dictionary[typeof(Int64)] is DecimalTypeDecider);
            Assert.IsTrue(factory.Dictionary[typeof(long)] is DecimalTypeDecider);
        }
Exemplo n.º 4
0
        public DataTable StronglyTypeTable(DataTable workingTable, ExplicitTypingCollection explicitTypingCollection)
        {
            Dictionary <int, IDecideTypesForStrings> deciders = new Dictionary <int, IDecideTypesForStrings>();
            var factory = new TypeDeciderFactory(_culture);

            if (!string.IsNullOrWhiteSpace(_explicitDateTimeFormat))
            {
                factory.Settings.ExplicitDateFormats = new [] { _explicitDateTimeFormat }
            }
            ;

            DataTable dtCloned = workingTable.Clone();

            bool typeChangeNeeded = false;

            foreach (DataColumn col in workingTable.Columns)
            {
                //if we have already handled it
                if (explicitTypingCollection != null && explicitTypingCollection.ExplicitTypesCSharp.ContainsKey(col.ColumnName))
                {
                    continue;
                }

                //let's make a decision about the data type to use based on the contents
                var computedType = new Guesser();
                computedType.AdjustToCompensateForValues(col);

                //Type based on the contents of the column
                if (computedType.ShouldDowngradeColumnTypeToMatchCurrentEstimate(col))
                {
                    dtCloned.Columns[col.ColumnName].DataType = computedType.Guess.CSharpType;

                    //if we have a type decider to parse this data type
                    if (factory.IsSupported(computedType.Guess.CSharpType))
                    {
                        deciders.Add(col.Ordinal, factory.Create(computedType.Guess.CSharpType)); //record column index and parser
                    }
                    typeChangeNeeded = true;
                }
            }

            if (typeChangeNeeded)
            {
                foreach (DataRow row in workingTable.Rows)
                {
                    dtCloned.Rows.Add(row.ItemArray.Select((v, idx) =>

                                                           deciders.ContainsKey(idx) && v is string s?
                                                           deciders[idx].Parse(s) :
                                                           v).ToArray());
                }

                return(dtCloned);
            }

            return(workingTable);
        }
Exemplo n.º 5
0
        public FlatFileToDataTablePusher(FlatFileToLoad fileToLoad, FlatFileColumnCollection headers, Func <string, object> hackValuesFunc, bool attemptToResolveNewlinesInRecords, CultureInfo culture)
        {
            _fileToLoad     = fileToLoad;
            _headers        = headers;
            _hackValuesFunc = hackValuesFunc;
            _attemptToResolveNewlinesInRecords = attemptToResolveNewlinesInRecords;
            _culture = culture ?? CultureInfo.CurrentCulture;

            typeDeciderFactory = new TypeDeciderFactory(_culture);
        }
Exemplo n.º 6
0
        public FlatFileToDataTablePusher(FlatFileToLoad fileToLoad, FlatFileColumnCollection headers, Func <string, object> hackValuesFunc, bool attemptToResolveNewlinesInRecords, CultureInfo culture, string explicitDateTimeFormat)
        {
            _fileToLoad     = fileToLoad;
            _headers        = headers;
            _hackValuesFunc = hackValuesFunc;
            _attemptToResolveNewlinesInRecords = attemptToResolveNewlinesInRecords;
            _culture = culture ?? CultureInfo.CurrentCulture;
            _explicitDateTimeFormat = explicitDateTimeFormat;
            typeDeciderFactory      = new TypeDeciderFactory(_culture);

            if (!string.IsNullOrWhiteSpace(explicitDateTimeFormat))
            {
                typeDeciderFactory.Settings.ExplicitDateFormats = new [] { explicitDateTimeFormat }
            }
            ;
        }
Exemplo n.º 7
0
        public void Guess_TF_Factory()
        {
            var candidate = "T";

            //default is true
            Assert.IsTrue(GuessSettingsFactory.Defaults.CharCanBeBoolean);

            var factory    = new TypeDeciderFactory(CultureInfo.CurrentCulture);
            var deciderOld = factory.Create(typeof(bool));

            //T = True
            Assert.IsTrue(deciderOld.IsAcceptableAsType(candidate, null));
            Assert.IsTrue(deciderOld.IsAcceptableAsType("1", null));

            factory.Settings.CharCanBeBoolean = false;
            var deciderNew = factory.Create(typeof(bool));

            Assert.IsFalse(deciderOld == deciderNew, "Factory Create created a reference to the same old instance! not a fresh one");
            Assert.IsTrue(deciderOld.Settings.CharCanBeBoolean);
            Assert.IsFalse(deciderNew.Settings.CharCanBeBoolean);

            Assert.IsFalse(deciderNew.IsAcceptableAsType(candidate, null));
            Assert.IsTrue(deciderNew.IsAcceptableAsType("1", null)); //setting does not affect 1/0
        }
Exemplo n.º 8
0
 public ParseStringsUpdater(CultureInfo culture)
 {
     _factory = new(culture);
 }