Example #1
0
        public void ExampleUsage()
        {
            var guesser = new Guesser();

            guesser.AdjustToCompensateForValue("-12.211");
            var guess = guesser.Guess;

            Assert.AreEqual(typeof(decimal), guess.CSharpType);
            Assert.AreEqual(2, guess.Size.NumbersBeforeDecimalPlace);
            Assert.AreEqual(3, guess.Size.NumbersAfterDecimalPlace);
            Assert.AreEqual(7, guess.Width);


            guesser = new Guesser();
            guesser.AdjustToCompensateForValue("1,000");
            guesser.AdjustToCompensateForValue("0.001");
            guess = guesser.Guess;

            Assert.AreEqual(typeof(decimal), guess.CSharpType);
            Assert.AreEqual(4, guess.Size.NumbersBeforeDecimalPlace);
            Assert.AreEqual(3, guess.Size.NumbersAfterDecimalPlace);
            Assert.AreEqual(8, guess.Width);//?


            var someStrings = new [] { "13:11:59", "9AM" };

            guesser = new Guesser();
            guesser.AdjustToCompensateForValues(someStrings);

            var parsed = someStrings.Select(guesser.Parse).ToArray();

            Assert.AreEqual(new TimeSpan(13, 11, 59), parsed[0]);
            Assert.AreEqual(new TimeSpan(9, 0, 0), parsed[1]);
        }
        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);
        }
Example #3
0
        public void Test_ManyString_IsType(string culture, string[] guessFor, Type expectedGuess, int expectedStringLength, int expectedBefore, int expectedAfter)
        {
            var cultureInfo = new CultureInfo(culture);
            var guesser     = new Guesser()
            {
                Culture = cultureInfo
            };

            guesser.AdjustToCompensateForValues(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");
        }
Example #4
0
        public DiscoveredTable CreateTable(CreateTableArgs args)
        {
            var typeDictionary = new Dictionary <string, Guesser>(StringComparer.CurrentCultureIgnoreCase);

            List <DatabaseColumnRequest> columns        = new List <DatabaseColumnRequest>();
            List <DatabaseColumnRequest> customRequests = args.ExplicitColumnDefinitions != null
                ? args.ExplicitColumnDefinitions.ToList()
                : new List <DatabaseColumnRequest>();

            if (args.DataTable != null)
            {
                ThrowIfObjectColumns(args.DataTable);

                //If we have a data table from which to create the table from
                foreach (DataColumn column in args.DataTable.Columns)
                {
                    //do we have an explicit overriding column definition?
                    DatabaseColumnRequest overriding = customRequests.SingleOrDefault(c => c.ColumnName.Equals(column.ColumnName, StringComparison.CurrentCultureIgnoreCase));

                    //yes
                    if (overriding != null)
                    {
                        columns.Add(overriding);
                        customRequests.Remove(overriding);

                        //Type requested is a proper FAnsi type (e.g. string, at least 5 long)
                        var request = overriding.TypeRequested;

                        if (request == null)
                        {
                            if (!string.IsNullOrWhiteSpace(overriding.ExplicitDbType))
                            {
                                //Type is for an explicit SQL Type e.g. varchar(5)

                                //Translate the sql type to a FAnsi type definition
                                var tt = args.Database.Server.GetQuerySyntaxHelper().TypeTranslater;

                                request = tt.GetDataTypeRequestForSQLDBType(overriding.ExplicitDbType);
                            }
                            else
                            {
                                throw new Exception(string.Format(FAnsiStrings.DiscoveredDatabaseHelper_CreateTable_DatabaseColumnRequestMustHaveEitherTypeRequestedOrExplicitDbType, column));
                            }
                        }

                        var guesser = GetGuesser(request);
                        CopySettings(guesser, args);
                        typeDictionary.Add(overriding.ColumnName, guesser);
                    }
                    else
                    {
                        //no, work out the column definition using a guesser
                        Guesser guesser = GetGuesser(column);
                        guesser.Culture = args.Culture;

                        CopySettings(guesser, args);

                        guesser.AdjustToCompensateForValues(column);

                        //if DoNotRetype is set on the column adjust the requested CSharpType to be the original type
                        if (column.GetDoNotReType())
                        {
                            guesser.Guess.CSharpType = column.DataType;
                        }

                        typeDictionary.Add(column.ColumnName, guesser);

                        columns.Add(new DatabaseColumnRequest(column.ColumnName, guesser.Guess, column.AllowDBNull)
                        {
                            IsPrimaryKey = args.DataTable.PrimaryKey.Contains(column)
                        });
                    }
                }
            }
            else
            {
                //If no DataTable is provided just use the explicitly requested columns
                columns = customRequests;
            }

            if (args.Adjuster != null)
            {
                args.Adjuster.AdjustColumns(columns);
            }

            //Get the table creation SQL
            string bodySql = GetCreateTableSql(args.Database, args.TableName, columns.ToArray(), args.ForeignKeyPairs, args.CascadeDelete, args.Schema);

            //connect to the server and send it
            var server = args.Database.Server;

            using (var con = server.GetConnection())
            {
                con.Open();

                ExecuteBatchNonQuery(bodySql, con);
            }

            //Get reference to the newly created table
            var tbl = args.Database.ExpectTable(args.TableName, args.Schema);

            //unless we are being asked to create it empty then upload the DataTable to it
            if (args.DataTable != null && !args.CreateEmpty)
            {
                using (var bulk = tbl.BeginBulkInsert(args.Culture))
                {
                    bulk.DateTimeDecider.Settings.ExplicitDateFormats = args.GuessSettings.ExplicitDateFormats;
                    bulk.Upload(args.DataTable);
                }
            }


            args.OnTableCreated(typeDictionary);

            return(tbl);
        }