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); }
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"); }
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); }