public void DateTimeTypeDecider_ExplicitDateTimeFormat(string value, string format, int yy, int mm, int dd) { var decider = new DateTimeTypeDecider(CultureInfo.InvariantCulture); Assert.IsFalse(decider.IsAcceptableAsType(value, new DatabaseTypeRequest(typeof(DateTime), null, null))); decider.Settings.ExplicitDateFormats = new [] { format }; Assert.IsTrue(decider.IsAcceptableAsType(value, new DatabaseTypeRequest(typeof(DateTime), null, null))); Assert.AreEqual(new DateTime(yy, mm, dd), decider.Parse(value)); var g = new Guesser(); g.AdjustToCompensateForValue(value); Assert.IsTrue(g.Guess.CSharpType == typeof(Int32) || g.Guess.CSharpType == typeof(string) /*0 prefixed numbers are usually treated as strings*/); var g2 = new Guesser(); g2.Settings.ExplicitDateFormats = new string[] { format }; g2.AdjustToCompensateForValue(value); Assert.AreEqual(typeof(DateTime), g2.Guess.CSharpType); }
public int PushCurrentLine(CsvReader reader, FlatFileLine lineToPush, DataTable dt, IDataLoadEventListener listener, FlatFileEventHandlers eventHandlers) { //skip the blank lines if (lineToPush.Cells.Length == 0 || lineToPush.Cells.All(h => h.IsBasicallyNull())) { return(0); } int headerCount = _headers.CountNotNull; //if the number of not empty headers doesn't match the headers in the data table if (dt.Columns.Count != headerCount) { if (!_haveComplainedAboutColumnMismatch) { listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "Flat file '" + _fileToLoad.File.Name + "' line number '" + reader.Context.RawRow + "' had " + headerCount + " columns while the destination DataTable had " + dt.Columns.Count + " columns. This message apperas only once per file")); _haveComplainedAboutColumnMismatch = true; } } Dictionary <string, object> rowValues = new Dictionary <string, object>(); if (lineToPush.Cells.Length < headerCount) { if (!DealWithTooFewCellsOnCurrentLine(reader, lineToPush, listener, eventHandlers)) { return(0); } } bool haveIncremented_bufferOverrunsWhereColumnValueWasBlank = false; for (int i = 0; i < lineToPush.Cells.Length; i++) { //about to do a buffer overrun if (i >= _headers.Length) { if (lineToPush[i].IsBasicallyNull()) { if (!haveIncremented_bufferOverrunsWhereColumnValueWasBlank) { _bufferOverrunsWhereColumnValueWasBlank++; haveIncremented_bufferOverrunsWhereColumnValueWasBlank = true; } continue; //do not bother buffer overruning with null whitespace stuff } else { string errorMessage = string.Format("Column mismatch on line {0} of file '{1}', it has too many columns (expected {2} columns but line had {3})", reader.Context.RawRow, dt.TableName, _headers.Length, lineToPush.Cells.Length); if (_bufferOverrunsWhereColumnValueWasBlank > 0) { errorMessage += " ( " + _bufferOverrunsWhereColumnValueWasBlank + " Previously lines also suffered from buffer overruns but the overrunning values were empty so we had ignored them up until now)"; } listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, errorMessage)); eventHandlers.BadDataFound(lineToPush); break; } } //if we are ignoring this header if (_headers.IgnoreColumnsList.Contains(_headers[i])) { continue; } //its an empty header, dont bother populating it if (_headers[i].IsBasicallyNull()) { if (!lineToPush[i].IsBasicallyNull()) { throw new FileLoadException("The header at index " + i + " in flat file '" + dt.TableName + "' had no name but there was a value in the data column (on Line number " + reader.Context.RawRow + ")"); } else { continue; } } //sometimes flat files have ,NULL,NULL,"bob" in instead of ,,"bob" if (lineToPush[i].IsBasicallyNull()) { rowValues.Add(_headers[i], DBNull.Value); } else { object hackedValue = _hackValuesFunc(lineToPush[i]); if (hackedValue is string) { hackedValue = ((string)hackedValue).Trim(); } try { //if we are trying to load a boolean value out of the flat file into the strongly typed C# data type if (dt.Columns[_headers[i]].DataType == typeof(Boolean)) { bool boolean; int integer; if (hackedValue is string) { if (Boolean.TryParse((string)hackedValue, out boolean)) //could be the text "true" { hackedValue = boolean; } else if (int.TryParse((string)hackedValue, out integer)) //could be the number string "1" or "0" { hackedValue = integer; } //else god knows what it is as a datatype, hopefully Convert.ChangeType will handle it } else if (int.TryParse(hackedValue.ToString(), out integer)) //could be the number 1 or 0 or something else that ToStrings into a legit value { hackedValue = integer; } } //if it is a datetime if (dt.Columns[_headers[i]].DataType == typeof(DateTime) && hackedValue is string) { hackedValue = _dateTimeParser.Parse((string)hackedValue); } //make it an int because apparently C# is too stupid to convert "1" into a bool but is smart enough to turn 1 into a bool.... seriously?!!? rowValues.Add(_headers[i], Convert.ChangeType(hackedValue, dt.Columns[_headers[i]].DataType)); //convert to correct datatype (datatype was setup in SetupTypes) } catch (Exception e) { throw new FileLoadException("Error reading file '" + dt.TableName + "'. Problem loading value " + lineToPush[i] + " into data table (on Line number " + reader.Context.RawRow + ") the header we were trying to populate was " + _headers[i] + " and was of datatype " + dt.Columns[_headers[i]].DataType, e); } } } if (!BadLines.Contains(reader.Context.RawRow)) { DataRow currentRow = dt.Rows.Add(); foreach (KeyValuePair <string, object> kvp in rowValues) { currentRow[kvp.Key] = kvp.Value; } return(1); } return(0); }