Skip to content

Commit

Permalink
[d4rLFQqM] Align all export modes with quoting consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
gem-neo4j committed Oct 8, 2024
1 parent 3d84446 commit 7397b42
Show file tree
Hide file tree
Showing 4 changed files with 319 additions and 26 deletions.
9 changes: 5 additions & 4 deletions core/src/main/java/apoc/export/csv/CsvFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ private void writeNodesBulkImport(
String prop = s.split(":")[0];
return prop.isEmpty()
? String.valueOf(getNodeId(tx, n.getElementId()))
: FormatUtils.toString(n.getProperty(prop, ""));
: FormatUtils.toString(
n.getProperty(prop, null), config.shouldDifferentiateNulls());
})
.collect(Collectors.toList());
})
Expand Down Expand Up @@ -316,12 +317,12 @@ private void writeRow(
if (config.isSeparateHeader()) {
try (PrintWriter pwHeader = writer.getPrintWriter("header." + name)) {
CSVWriter csvWriterHeader = getCsvWriter(pwHeader, config);
csvWriterHeader.writeNext(headerNode.toArray(new String[headerNode.size()]), false);
csvWriterHeader.writeNext(headerNode.toArray(new String[headerNode.size()]), applyQuotesToAll);
}
} else {
csvWriter.writeNext(headerNode.toArray(new String[headerNode.size()]), false);
csvWriter.writeNext(headerNode.toArray(new String[headerNode.size()]), applyQuotesToAll);
}
rows.forEach(row -> csvWriter.writeNext(row.toArray(new String[row.size()]), false));
rows.forEach(row -> csvWriter.writeNext(row.toArray(new String[row.size()]), applyQuotesToAll));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
10 changes: 6 additions & 4 deletions core/src/main/java/apoc/export/csv/ExportCSV.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ public Stream<ExportProgressInfo> all(
{
stream = false :: BOOLEAN,
batchSize = 20000 :: INTEGER,
bulkImport = true :: BOOLEAN,
bulkImport = false :: BOOLEAN,
timeoutSeconds = 100 :: INTEGER,
compression = 'None' :: STRING,
charset = 'UTF_8' :: STRING,
quotes = 'always' :: ['always', 'none', 'ifNeeded'],
differentiateNulls = false :: BOOLEAN,
sampling = false :: BOOLEAN,
samplingConfig :: MAP
Expand All @@ -113,10 +114,10 @@ public Stream<ExportProgressInfo> data(
{
stream = false :: BOOLEAN,
batchSize = 20000 :: INTEGER,
bulkImport = true :: BOOLEAN,
timeoutSeconds = 100 :: INTEGER,
compression = 'None' :: STRING,
charset = 'UTF_8' :: STRING,
quotes = 'always' :: ['always', 'none', 'ifNeeded'],
differentiateNulls = false :: BOOLEAN,
sampling = false :: BOOLEAN,
samplingConfig :: MAP
Expand All @@ -143,10 +144,11 @@ public Stream<ExportProgressInfo> graph(
{
stream = false :: BOOLEAN,
batchSize = 20000 :: INTEGER,
bulkImport = true :: BOOLEAN,
bulkImport = false :: BOOLEAN,
timeoutSeconds = 100 :: INTEGER,
compression = 'None' :: STRING,
charset = 'UTF_8' :: STRING,
quotes = 'always' :: ['always', 'none', 'ifNeeded'],
differentiateNulls = false :: BOOLEAN,
sampling = false :: BOOLEAN,
samplingConfig :: MAP
Expand Down Expand Up @@ -177,10 +179,10 @@ public Stream<ExportProgressInfo> query(
{
stream = false :: BOOLEAN,
batchSize = 20000 :: INTEGER,
bulkImport = true :: BOOLEAN,
timeoutSeconds = 100 :: INTEGER,
compression = 'None':: STRING,
charset = 'UTF_8' :: STRING,
quotes = 'always' :: ['always', 'none', 'ifNeeded'],
differentiateNulls = false :: BOOLEAN,
sampling = false :: BOOLEAN,
samplingConfig :: MAP
Expand Down
39 changes: 21 additions & 18 deletions core/src/test/java/apoc/export/csv/ExportCsvNeo4jAdminTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,45 +51,46 @@
public class ExportCsvNeo4jAdminTest {

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_HEADER_TYPES_NODE = String.format(
":ID;born_2D:point;born_3D:point;localtime:localtime;time:time;dateTime:datetime;localDateTime:localdatetime;date:date;duration:duration;:LABEL%n");
"\":ID\";\"born_2D:point\";\"born_3D:point\";\"localtime:localtime\";\"time:time\";\"dateTime:datetime\";\"localDateTime:localdatetime\";\"date:date\";\"duration:duration\";\":LABEL\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_TYPES_NODE = String.format(
"6;\"{\"\"crs\"\":\"\"cartesian\"\",\"\"x\"\":2.3,\"\"y\"\":4.5,\"\"z\"\":null}\";\"{\"\"crs\"\":\"\"wgs-84-3d\"\",\"\"latitude\"\":12.78,\"\"longitude\"\":56.7,\"\"height\"\":100.0}\";12:50:35.556;12:50:35.556+01:00;2018-10-30T12:50:35.556+01:00;2018-10-30T19:32:24;2018-10-30;P5M1DT12H;Types%n");
"\"6\";\"{\"\"crs\"\":\"\"cartesian\"\",\"\"x\"\":2.3,\"\"y\"\":4.5,\"\"z\"\":null}\";\"{\"\"crs\"\":\"\"wgs-84-3d\"\",\"\"latitude\"\":12.78,\"\"longitude\"\":56.7,\"\"height\"\":100.0}\";\"12:50:35.556\";\"12:50:35.556+01:00\";\"2018-10-30T12:50:35.556+01:00\";\"2018-10-30T19:32:24\";\"2018-10-30\";\"P5M1DT12H\";\"Types\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_HEADER_NODE_ADDRESS =
String.format(":ID;name;street;:LABEL%n");
String.format("\":ID\";\"name\";\"street\";\":LABEL\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_HEADER_NODE_ADDRESS1 =
String.format(":ID;street;name;city;:LABEL%n");
String.format("\":ID\";\"street\";\"name\";\"city\";\":LABEL\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_HEADER_NODE_USER =
String.format(":ID;name;age:long;:LABEL%n");
String.format("\":ID\";\"name\";\"age:long\";\":LABEL\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_HEADER_NODE_USER1 =
String.format(":ID;name;age:long;male:boolean;kids;:LABEL%n");
String.format("\":ID\";\"name\";\"age:long\";\"male:boolean\";\"kids\";\":LABEL\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_HEADER_RELATIONSHIP_KNOWS =
String.format(":START_ID;:END_ID;:TYPE%n");
String.format("\":START_ID\";\":END_ID\";\":TYPE\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_HEADER_RELATIONSHIP_NEXT_DELIVERY =
String.format(":START_ID;:END_ID;:TYPE%n");
String.format("\":START_ID\";\":END_ID\";\":TYPE\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_NODE_ADDRESS =
String.format("4;Bar Sport;;Address%n" + "5;;via Benni;Address%n");
String.format("\"4\";\"Bar Sport\";\"\";\"Address\"%n" + "\"5\";\"\";\"via Benni\";\"Address\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_NODE_ADDRESS1 =
String.format("3;Via Garibaldi, 7;Andrea;Milano;\"Address1;Address\"%n");
String.format("\"3\";\"Via Garibaldi, 7\";\"Andrea\";\"Milano\";\"Address1;Address\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_NODE_USER =
String.format("1;bar;42;User%n" + "2;;12;User%n");
String.format("\"1\";\"bar\";\"42\";\"User\"%n" + "\"2\";\"\";\"12\";\"User\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_NODE_USER1 =
String.format("0;\"foo \"\"the\"\" bar\";42;true;\"[\"\"a\"\",\"\"b\"\",\"\"c\"\"]\";\"User1;User\"%n");
private static final String EXPECTED_NEO4J_ADMIN_IMPORT_NODE_USER1 = String.format(
"\"0\";\"foo \"\"the\"\" bar\";\"42\";\"true\";\"[\"\"a\"\",\"\"b\"\",\"\"c\"\"]\";\"User1;User\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_RELATIONSHIP_KNOWS = String.format("0;1;KNOWS%n");
private static final String EXPECTED_NEO4J_ADMIN_IMPORT_RELATIONSHIP_KNOWS =
String.format("\"0\";\"1\";\"KNOWS\"%n");

private static final String EXPECTED_NEO4J_ADMIN_IMPORT_RELATIONSHIP_NEXT_DELIVERY =
String.format("3;4;NEXT_DELIVERY%n");
String.format("\"3\";\"4\";\"NEXT_DELIVERY\"%n");

private static final String GZIP_EXT = ".foo";

Expand Down Expand Up @@ -412,11 +413,13 @@ public void testExportCypherWithIdField() {

String file = dir.getParent() + File.separator;
String expectedNodesLarus = String.format(
":ID,id:long,name,:LABEL%n" + "%s,1,Andrea,User;Larus%n", map.get("sourceId"));
"\":ID\",\"id:long\",\"name\",\":LABEL\"%n" + "\"%s\",\"1\",\"Andrea\",\"User;Larus\"%n",
map.get("sourceId"));
String expectedNodesNeo4j = String.format(
":ID,id:long,name,:LABEL%n" + "%s,2,Michael,User;Neo4j%n", map.get("targetId"));
"\":ID\",\"id:long\",\"name\",\":LABEL\"%n" + "\"%s\",\"2\",\"Michael\",\"User;Neo4j\"%n",
map.get("targetId"));
String expectedRelsNeo4j = String.format(
":START_ID,:END_ID,:TYPE,id:long%n" + "%s,%s,KNOWS,10%n",
"\":START_ID\",\":END_ID\",\":TYPE\",\"id:long\"%n" + "\"%s\",\"%s\",\"KNOWS\",\"10\"%n",
map.get("sourceId"), map.get("targetId"));

assertFileEquals(file, expectedNodesLarus, fileName + ".nodes.User.Larus.csv");
Expand Down
Loading

0 comments on commit 7397b42

Please sign in to comment.