Skip to content

Commit

Permalink
[G9u7OAg9] Ignore check for optimizations if the format is CSV (#542)
Browse files Browse the repository at this point in the history
  • Loading branch information
gem-neo4j authored Dec 5, 2023
1 parent e9cd167 commit 0479857
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 14 deletions.
10 changes: 8 additions & 2 deletions common/src/main/java/apoc/export/util/ExportConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ public boolean isMultipleRelationshipsWithType() {
}

public ExportConfig(Map<String, Object> config) {
this(config, ExportFormat.CYPHER_SHELL);
}

public ExportConfig(Map<String, Object> config, ExportFormat exportFormat) {
super(config);
config = config != null ? config : Collections.emptyMap();
this.saveIndexNames = toBoolean(config.getOrDefault("saveIndexNames", false));
Expand All @@ -138,7 +142,7 @@ public ExportConfig(Map<String, Object> config) {
this.nodesOfRelationships = toBoolean(config.get("nodesOfRelationships"));
this.bulkImport = toBoolean(config.get("bulkImport"));
this.separateHeader = toBoolean(config.get("separateHeader"));
this.format = ExportFormat.fromString((String) config.getOrDefault("format", "cypher-shell"));
this.format = ExportFormat.fromString((String) config.getOrDefault("format", exportFormat.getFormat()));
this.cypherFormat = CypherFormat.fromString((String) config.getOrDefault("cypherFormat", "create"));
this.config = config;
this.streamStatements = toBoolean(config.get("streamStatements")) || toBoolean(config.get("stream"));
Expand Down Expand Up @@ -169,7 +173,9 @@ private void validate() {
"`useOptimizations: 'UNWIND_BATCH_PARAMS'` can be used only in combination with `format: 'CYPHER_SHELL' but got [format:`"
+ this.format + "]");
}
if (!OptimizationType.NONE.equals(this.optimizationType) && this.unwindBatchSize > this.batchSize) {
// CSV doesn't use optimization type
if (!OptimizationType.NONE.equals(this.optimizationType) && this.unwindBatchSize > this.batchSize
&& !ExportFormat.CSV.equals(this.format)) {
throw new RuntimeException("`unwindBatchSize` must be <= `batchSize`, but got [unwindBatchSize:"
+ unwindBatchSize + ", batchSize:" + batchSize + "]");
}
Expand Down
7 changes: 6 additions & 1 deletion common/src/main/java/apoc/export/util/ExportFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public enum ExportFormat {

GEPHI("gephi", "", "", "", ""),

TINKERPOP("tinkerpop", "", "", "", "");
TINKERPOP("tinkerpop", "", "", "", ""),

CSV("csv", "", "", "", "");

private final String format;

Expand All @@ -54,6 +56,9 @@ public enum ExportFormat {
this.indexAwait = indexAwait;
}

public String getFormat() {
return format;
}
public static final ExportFormat fromString(String format) {
if (format != null && !format.isEmpty()) {
for (ExportFormat exportFormat : ExportFormat.values()) {
Expand Down
9 changes: 5 additions & 4 deletions core/src/main/java/apoc/export/csv/ExportCSV.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import apoc.export.cypher.ExportFileManager;
import apoc.export.cypher.FileManagerFactory;
import apoc.export.util.ExportConfig;
import apoc.export.util.ExportFormat;
import apoc.export.util.ExportUtils;
import apoc.export.util.NodesAndRelsSubGraph;
import apoc.export.util.ProgressReporter;
Expand Down Expand Up @@ -75,7 +76,7 @@ public ExportCSV() {}
@Description("Exports the full database to the provided CSV file.")
public Stream<ProgressInfo> all(@Name("file") String fileName, @Name("config") Map<String, Object> config) {
String source = String.format("database: nodes(%d), rels(%d)", Util.nodeCount(tx), Util.relCount(tx));
return exportCsv(fileName, source, new DatabaseSubGraph(tx), new ExportConfig(config));
return exportCsv(fileName, source, new DatabaseSubGraph(tx), new ExportConfig(config, ExportFormat.CSV));
}

@NotThreadSafe
Expand All @@ -86,7 +87,7 @@ public Stream<ProgressInfo> data(
@Name("rels") List<Relationship> rels,
@Name("file") String fileName,
@Name("config") Map<String, Object> config) {
ExportConfig exportConfig = new ExportConfig(config);
ExportConfig exportConfig = new ExportConfig(config, ExportFormat.CSV);
preventBulkImport(exportConfig);
String source = String.format("data: nodes(%d), rels(%d)", nodes.size(), rels.size());
return exportCsv(fileName, source, new NodesAndRelsSubGraph(tx, nodes, rels), exportConfig);
Expand All @@ -102,15 +103,15 @@ public Stream<ProgressInfo> graph(
Collection<Node> nodes = (Collection<Node>) graph.get("nodes");
Collection<Relationship> rels = (Collection<Relationship>) graph.get("relationships");
String source = String.format("graph: nodes(%d), rels(%d)", nodes.size(), rels.size());
return exportCsv(fileName, source, new NodesAndRelsSubGraph(tx, nodes, rels), new ExportConfig(config));
return exportCsv(fileName, source, new NodesAndRelsSubGraph(tx, nodes, rels), new ExportConfig(config, ExportFormat.CSV));
}

@NotThreadSafe
@Procedure("apoc.export.csv.query")
@Description("Exports the results from running the given Cypher query to the provided CSV file.")
public Stream<ProgressInfo> query(
@Name("query") String query, @Name("file") String fileName, @Name("config") Map<String, Object> config) {
ExportConfig exportConfig = new ExportConfig(config);
ExportConfig exportConfig = new ExportConfig(config, ExportFormat.CSV);
preventBulkImport(exportConfig);
Map<String, Object> params = config == null
? Collections.emptyMap()
Expand Down
14 changes: 7 additions & 7 deletions core/src/test/java/apoc/export/csv/ExportCsvTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -486,15 +486,15 @@ private void assertCsvCommon(String fileName, Map<String, Object> r) {
@Test
public void testExportAllCsvStreaming() {
String statement =
"CALL apoc.export.csv.all(null,{stream:true,batchSize:2,useOptimizations:{unwindBatchSize:2}})";
"CALL apoc.export.csv.all(null,{stream:true,batchSize:2})";
assertExportStreaming(statement, NONE);
}

@Test
public void testExportAllCsvStreamingCompressed() {
final CompressionAlgo algo = GZIP;
String statement = "CALL apoc.export.csv.all(null, {compression: '" + algo.name()
+ "',stream:true,batchSize:2,useOptimizations:{unwindBatchSize:2}})";
+ "',stream:true,batchSize:2})";
assertExportStreaming(statement, algo);
}

Expand Down Expand Up @@ -550,7 +550,7 @@ public void testCypherCsvStreaming() {
StringBuilder sb = new StringBuilder();
testResult(
db,
"CALL apoc.export.csv.query($query,null,{stream:true,batchSize:2, useOptimizations:{unwindBatchSize:2}})",
"CALL apoc.export.csv.query($query,null,{stream:true,batchSize:2})",
map("query", query),
getAndCheckStreamingMetadataQueryMatchUsers(sb));
assertEquals(EXPECTED_QUERY, sb.toString());
Expand All @@ -562,7 +562,7 @@ public void testCypherCsvStreamingWithoutQuotes() {
StringBuilder sb = new StringBuilder();
testResult(
db,
"CALL apoc.export.csv.query($query,null,{quotes: false, stream:true,batchSize:2, useOptimizations:{unwindBatchSize:2}})",
"CALL apoc.export.csv.query($query,null,{quotes: false, stream:true,batchSize:2})",
map("query", query),
getAndCheckStreamingMetadataQueryMatchUsers(sb));

Expand Down Expand Up @@ -600,7 +600,7 @@ public void testCypherCsvStreamingWithAlwaysQuotes() {
StringBuilder sb = new StringBuilder();
testResult(
db,
"CALL apoc.export.csv.query($query,null,{quotes: 'always', stream:true,batchSize:2, useOptimizations:{unwindBatchSize:2}})",
"CALL apoc.export.csv.query($query,null,{quotes: 'always', stream:true,batchSize:2})",
map("query", query),
getAndCheckStreamingMetadataQueryMatchAddress(sb));

Expand All @@ -613,7 +613,7 @@ public void testCypherCsvStreamingWithNeededQuotes() {
StringBuilder sb = new StringBuilder();
testResult(
db,
"CALL apoc.export.csv.query($query,null,{quotes: 'ifNeeded', stream:true,batchSize:2, useOptimizations:{unwindBatchSize:2}})",
"CALL apoc.export.csv.query($query,null,{quotes: 'ifNeeded', stream:true,batchSize:2})",
map("query", query),
getAndCheckStreamingMetadataQueryMatchAddress(sb));

Expand All @@ -626,7 +626,7 @@ public void testCypherCsvStreamingWithNoneQuotes() {
StringBuilder sb = new StringBuilder();
testResult(
db,
"CALL apoc.export.csv.query($query,null,{quotes: 'none', stream:true,batchSize:2, useOptimizations:{unwindBatchSize:2}})",
"CALL apoc.export.csv.query($query,null,{quotes: 'none', stream:true,batchSize:2})",
map("query", query),
getAndCheckStreamingMetadataQueryMatchAddress(sb));

Expand Down

0 comments on commit 0479857

Please sign in to comment.