Make CSVPrinter.print(Object) GC-free.
diff --git a/src/main/java/org/apache/commons/csv/CSVFormat.java b/src/main/java/org/apache/commons/csv/CSVFormat.java
index 88b6da33..ea22885a 100644
--- a/src/main/java/org/apache/commons/csv/CSVFormat.java
+++ b/src/main/java/org/apache/commons/csv/CSVFormat.java
@@ -20,6 +20,7 @@ package org.apache.commons.csv;
import static org.apache.commons.csv.Constants.BACKSLASH;
import static org.apache.commons.csv.Constants.COMMA;
import static org.apache.commons.csv.Constants.COMMENT;
+import static org.apache.commons.csv.Constants.EMPTY;
import static org.apache.commons.csv.Constants.CR;
import static org.apache.commons.csv.Constants.CRLF;
import static org.apache.commons.csv.Constants.DOUBLE_QUOTE_CHAR;
@@ -190,6 +191,17 @@ public final class CSVFormat implements Serializable {
*/
MySQL(CSVFormat.MYSQL),
+ /**
+ * @see CSVFormat#POSTGRESQL_CSV
+ * @since 1.5
+ */
+ PostgreSQLCsv(CSVFormat.POSTGRESQL_CSV),
+
+ /**
+ * @see CSVFormat#POSTGRESQL_CSV
+ */
+ PostgreSQLText(CSVFormat.POSTGRESQL_TEXT),
+
/**
* @see CSVFormat#RFC4180
*/
@@ -367,6 +379,80 @@ public final class CSVFormat implements Serializable {
.withQuoteMode(QuoteMode.ALL_NON_NULL);
// @formatter:off
+ /**
+ * Default PostgreSQL CSV format used by the {@code COPY} operation.
+ *
+ *
+ * This is a comma-delimited format with a LF character as the line separator. Values are double quoted and special
+ * characters are escaped with {@code '"'}. The default NULL string is {@code ""}.
+ *
+ *
+ *
+ * Settings are:
+ *
+ *
+ * - withDelimiter(',')
+ * - withQuote('"')
+ * - withRecordSeparator('\n')
+ * - withIgnoreEmptyLines(false)
+ * - withEscape('\\')
+ * - withNullString("")
+ * - withQuoteMode(QuoteMode.ALL_NON_NULL)
+ *
+ *
+ * @see Predefined#MySQL
+ * @see http://dev.mysql.com/doc/refman/5.1/en/load
+ * -data.html
+ * @since 1.5
+ */
+ // @formatter:off
+ public static final CSVFormat POSTGRESQL_CSV = DEFAULT
+ .withDelimiter(COMMA)
+ .withEscape(DOUBLE_QUOTE_CHAR)
+ .withIgnoreEmptyLines(false)
+ .withQuote(DOUBLE_QUOTE_CHAR)
+ .withRecordSeparator(LF)
+ .withNullString(EMPTY)
+ .withQuoteMode(QuoteMode.ALL_NON_NULL);
+ // @formatter:off
+
+ /**
+ * Default PostgreSQL text format used by the {@code COPY} operation.
+ *
+ *
+ * This is a tab-delimited format with a LF character as the line separator. Values are double quoted and special
+ * characters are escaped with {@code '"'}. The default NULL string is {@code "\\N"}.
+ *
+ *
+ *
+ * Settings are:
+ *
+ *
+ * - withDelimiter('\t')
+ * - withQuote('"')
+ * - withRecordSeparator('\n')
+ * - withIgnoreEmptyLines(false)
+ * - withEscape('\\')
+ * - withNullString("\\N")
+ * - withQuoteMode(QuoteMode.ALL_NON_NULL)
+ *
+ *
+ * @see Predefined#MySQL
+ * @see http://dev.mysql.com/doc/refman/5.1/en/load
+ * -data.html
+ * @since 1.5
+ */
+ // @formatter:off
+ public static final CSVFormat POSTGRESQL_TEXT = DEFAULT
+ .withDelimiter(TAB)
+ .withEscape(DOUBLE_QUOTE_CHAR)
+ .withIgnoreEmptyLines(false)
+ .withQuote(DOUBLE_QUOTE_CHAR)
+ .withRecordSeparator(LF)
+ .withNullString("\\N")
+ .withQuoteMode(QuoteMode.ALL_NON_NULL);
+ // @formatter:off
+
/**
* Comma separated format as defined by RFC 4180.
*
diff --git a/src/test/java/org/apache/commons/csv/CSVFormatPredefinedTest.java b/src/test/java/org/apache/commons/csv/CSVFormatPredefinedTest.java
index 1340534a..e4492ff2 100644
--- a/src/test/java/org/apache/commons/csv/CSVFormatPredefinedTest.java
+++ b/src/test/java/org/apache/commons/csv/CSVFormatPredefinedTest.java
@@ -1,57 +1,67 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.csv;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Tests {@link CSVFormat.Predefined}.
- */
-public class CSVFormatPredefinedTest {
-
- private void test(final CSVFormat format, final String enumName) {
- Assert.assertEquals(format, CSVFormat.Predefined.valueOf(enumName).getFormat());
- Assert.assertEquals(format, CSVFormat.valueOf(enumName));
- }
-
- @Test
- public void testDefault() {
- test(CSVFormat.DEFAULT, "Default");
- }
-
- @Test
- public void testExcel() {
- test(CSVFormat.EXCEL, "Excel");
- }
-
- @Test
- public void testMySQL() {
- test(CSVFormat.MYSQL, "MySQL");
- }
-
- @Test
- public void testRFC4180() {
- test(CSVFormat.RFC4180, "RFC4180");
- }
-
- @Test
- public void testTDF() {
- test(CSVFormat.TDF, "TDF");
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.csv;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests {@link CSVFormat.Predefined}.
+ */
+public class CSVFormatPredefinedTest {
+
+ private void test(final CSVFormat format, final String enumName) {
+ Assert.assertEquals(format, CSVFormat.Predefined.valueOf(enumName).getFormat());
+ Assert.assertEquals(format, CSVFormat.valueOf(enumName));
+ }
+
+ @Test
+ public void testDefault() {
+ test(CSVFormat.DEFAULT, "Default");
+ }
+
+ @Test
+ public void testExcel() {
+ test(CSVFormat.EXCEL, "Excel");
+ }
+
+ @Test
+ public void testMySQL() {
+ test(CSVFormat.MYSQL, "MySQL");
+ }
+
+ @Test
+ public void testPostgreSqlCsv() {
+ test(CSVFormat.POSTGRESQL_CSV, "PostgreSQLCsv");
+ }
+
+ @Test
+ public void testPostgreSqlText() {
+ test(CSVFormat.POSTGRESQL_TEXT, "PostgreSQLText");
+ }
+
+ @Test
+ public void testRFC4180() {
+ test(CSVFormat.RFC4180, "RFC4180");
+ }
+
+ @Test
+ public void testTDF() {
+ test(CSVFormat.TDF, "TDF");
+ }
+}
diff --git a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
index 3ee2438f..a74ed250 100644
--- a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
+++ b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
@@ -713,11 +713,227 @@ public class CSVPrinterTest {
assertArrayEquals(expectNulls(s, format), record0);
}
+ @Test
+ @Ignore
+ public void testPostgreSqlCsvNullOutput() throws IOException {
+ Object[] s = new String[] { "NULL", null };
+ CSVFormat format = CSVFormat.POSTGRESQL_CSV.withQuote(DQUOTE_CHAR).withNullString("NULL").withQuoteMode(QuoteMode.ALL_NON_NULL);
+ StringWriter writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ String expected = "\"NULL\",NULL\n";
+ assertEquals(expected, writer.toString());
+ String[] record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(new Object[2], record0);
+
+ s = new String[] { "\\N", null };
+ format = CSVFormat.POSTGRESQL_CSV.withNullString("\\N");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\N\t\\N\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\\N", "A" };
+ format = CSVFormat.POSTGRESQL_CSV.withNullString("\\N");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\N\tA\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\n", "A" };
+ format = CSVFormat.POSTGRESQL_CSV.withNullString("\\N");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\n\tA\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "", null };
+ format = CSVFormat.POSTGRESQL_CSV.withNullString("NULL");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\tNULL\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "", null };
+ format = CSVFormat.POSTGRESQL_CSV;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\t\\N\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\\N", "", "\u000e,\\\r" };
+ format = CSVFormat.POSTGRESQL_CSV;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\N\t\t\u000e,\\\\\\r\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "NULL", "\\\r" };
+ format = CSVFormat.POSTGRESQL_CSV;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "NULL\t\\\\\\r\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\\\r" };
+ format = CSVFormat.POSTGRESQL_CSV;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\\\r\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+ }
+
+ @Test
+ @Ignore
+ public void testPostgreSqlCsvTextOutput() throws IOException {
+ Object[] s = new String[] { "NULL", null };
+ CSVFormat format = CSVFormat.POSTGRESQL_TEXT.withQuote(DQUOTE_CHAR).withNullString("NULL").withQuoteMode(QuoteMode.ALL_NON_NULL);
+ StringWriter writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ String expected = "\"NULL\"\tNULL\n";
+ assertEquals(expected, writer.toString());
+ String[] record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(new Object[2], record0);
+
+ s = new String[] { "\\N", null };
+ format = CSVFormat.POSTGRESQL_TEXT.withNullString("\\N");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\N\t\\N\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\\N", "A" };
+ format = CSVFormat.POSTGRESQL_TEXT.withNullString("\\N");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\N\tA\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\n", "A" };
+ format = CSVFormat.POSTGRESQL_TEXT.withNullString("\\N");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\n\tA\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "", null };
+ format = CSVFormat.POSTGRESQL_TEXT.withNullString("NULL");
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\tNULL\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "", null };
+ format = CSVFormat.POSTGRESQL_TEXT;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\t\\N\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\\N", "", "\u000e,\\\r" };
+ format = CSVFormat.POSTGRESQL_TEXT;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\N\t\t\u000e,\\\\\\r\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "NULL", "\\\r" };
+ format = CSVFormat.POSTGRESQL_TEXT;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "NULL\t\\\\\\r\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+
+ s = new String[] { "\\\r" };
+ format = CSVFormat.POSTGRESQL_TEXT;
+ writer = new StringWriter();
+ try (final CSVPrinter printer = new CSVPrinter(writer, format)) {
+ printer.printRecord(s);
+ }
+ expected = "\\\\\\r\n";
+ assertEquals(expected, writer.toString());
+ record0 = toFirstRecordValues(expected, format);
+ assertArrayEquals(expectNulls(s, format), record0);
+ }
+
@Test
public void testMySqlNullStringDefault() {
assertEquals("\\N", CSVFormat.MYSQL.getNullString());
}
+ @Test
+ public void testPostgreSQLNullStringDefaultCsv() {
+ assertEquals("", CSVFormat.POSTGRESQL_CSV.getNullString());
+ }
+
+ @Test
+ public void testPostgreSQLNullStringDefaultText() {
+ assertEquals("\\N", CSVFormat.POSTGRESQL_TEXT.getNullString());
+ }
+
@Test(expected = IllegalArgumentException.class)
public void testNewCsvPrinterAppendableNullFormat() throws Exception {
try (final CSVPrinter printer = new CSVPrinter(new StringWriter(), null)) {
@@ -948,6 +1164,18 @@ public class CSVPrinterTest {
doRandom(CSVFormat.MYSQL, ITERATIONS_FOR_RANDOM_TEST);
}
+ @Test
+ @Ignore
+ public void testRandomPostgreSqlCsv() throws Exception {
+ doRandom(CSVFormat.POSTGRESQL_CSV, ITERATIONS_FOR_RANDOM_TEST);
+ }
+
+ @Test
+ @Ignore
+ public void testRandomPostgreSqlText() throws Exception {
+ doRandom(CSVFormat.POSTGRESQL_TEXT, ITERATIONS_FOR_RANDOM_TEST);
+ }
+
@Test
public void testRandomRfc4180() throws Exception {
doRandom(CSVFormat.RFC4180, ITERATIONS_FOR_RANDOM_TEST);