public void EscapeForCsv_ReturnsField() { // leave field without special characters var expected = "field"; var source = "field"; var actual = GreenplumCsvEscaper.EscapeField(source); Assert.AreEqual(expected, actual); // replace new lines expected = "fiel\\015\\012d"; source = "fiel\r\nd"; actual = GreenplumCsvEscaper.EscapeField(source); Assert.AreEqual(expected, actual); // replace new lines expected = "\\\\roppantjoteszt"; source = "\\roppantjoteszt"; actual = GreenplumCsvEscaper.EscapeField(source); Assert.AreEqual(expected, actual); // replace new lines expected = "\\\\vertical\\013"; source = "\\vertical\v"; actual = GreenplumCsvEscaper.EscapeField(source); Assert.AreEqual(expected, actual); }
/// <summary> /// Writes a single line of a datatable into a csv file /// </summary> /// <param name="csvWriter"></param> /// <param name="columnCount"></param> /// <param name="row"></param> /// <returns></returns> private static int WriteCsvLine(CsvWriter csvWriter, int columnCount, DataRow row) { var rowByteCount = 0; for (var i = 0; i < columnCount; i++) { object fieldValue; if (row[i] != null && !row.IsNull(i)) { if (row[i].GetType() == typeof(DateTime)) { // In order to have milliseconds instead of only seconds in the string representation // of the timestamp, we need to use a custom ToString() method instead of the // default one. This is a kind-of-ugly workaround. DateTime timestamp = (DateTime)row[i]; fieldValue = timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); } else if (row[i].GetType() == typeof(string)) { // strings need to escaped for postgres-specific characters fieldValue = GreenplumCsvEscaper.EscapeField(row[i].ToString()); } else { // otherwise let CsvWriter convert it fieldValue = row[i]; } } else { // Nulls are escaped as \N fieldValue = @"\N"; } // update the total byte count rowByteCount += fieldValue.ToString().Length; // Write the current field csvWriter.WriteField(fieldValue); } // output the record csvWriter.NextRecord(); // return the new byte count return(rowByteCount); }