Skip to content

Commit 4ab3499

Browse files
committed
[lYfZxdRz] Migrate procedures and functions from Core to Cypher 25
1 parent 4f0586f commit 4ab3499

22 files changed

+2766
-5
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[submodule "apoc-core"]
22
path = apoc-core
33
url = https://github.com/neo4j/apoc
4-
branch = 5.24
4+
branch = 5.25

build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ downloadLicenses {
1414

1515
allprojects {
1616
group = 'org.neo4j.procedure'
17-
version = '5.24.0'
17+
version = '5.26.0'
1818
archivesBaseName = 'apoc'
1919
description = """neo4j-apoc-procedures"""
2020
}
@@ -71,8 +71,8 @@ subprojects {
7171
// neo4jDockerImage system property is used in TestContainerUtil
7272
systemProperties 'user.language' : 'en' ,
7373
'user.country' : 'US',
74-
'neo4jDockerImage' : System.getProperty("NEO4JVERSION") ? 'neo4j:' + System.getProperty("NEO4JVERSION") + '-enterprise-debian' : 'neo4j:5.24.1-enterprise',
75-
'neo4jCommunityDockerImage': System.getProperty("NEO4JVERSION") ? 'neo4j:' + System.getProperty("NEO4JVERSION") + '-debian' : 'neo4j:5.24.1',
74+
'neo4jDockerImage' : System.getProperty("NEO4JVERSION") ? 'neo4j:' + System.getProperty("NEO4JVERSION") + '-enterprise-debian' : 'neo4j:5.26.0-enterprise',
75+
'neo4jCommunityDockerImage': System.getProperty("NEO4JVERSION") ? 'neo4j:' + System.getProperty("NEO4JVERSION") + '-debian' : 'neo4j:5.26.0',
7676
'coreDir': 'apoc-core/core',
7777
'testDockerBundle': false
7878

@@ -131,7 +131,7 @@ subprojects {
131131

132132
ext {
133133
// NB: due to version.json generation by parsing this file, the next line must not have any if/then/else logic
134-
neo4jVersion = "5.24.1"
134+
neo4jVersion = "5.26.0"
135135
// instead we apply the override logic here
136136
neo4jVersionEffective = project.hasProperty("neo4jVersionOverride") ? project.getProperty("neo4jVersionOverride") : neo4jVersion
137137
testContainersVersion = '1.18.3'
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package apoc.export.arrow;
20+
21+
import apoc.util.Util;
22+
23+
import java.util.Collections;
24+
import java.util.Map;
25+
26+
public class ArrowConfig {
27+
28+
private final int batchSize;
29+
30+
private final Map<String, Object> config;
31+
32+
public ArrowConfig(Map<String, Object> config) {
33+
this.config = config == null ? Collections.emptyMap() : config;
34+
this.batchSize = Util.toInteger(this.config.getOrDefault("batchSize", 2000));
35+
}
36+
37+
public int getBatchSize() {
38+
return batchSize;
39+
}
40+
41+
public Map<String, Object> getConfig() {
42+
return config;
43+
}
44+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package apoc.export.arrow;
20+
21+
import org.apache.arrow.vector.types.Types;
22+
import org.apache.arrow.vector.types.pojo.Field;
23+
import org.apache.arrow.vector.types.pojo.FieldType;
24+
25+
import java.util.List;
26+
27+
public class ArrowUtils {
28+
29+
private ArrowUtils() {}
30+
31+
public static Field FIELD_ID = new Field("<id>", FieldType.nullable(Types.MinorType.BIGINT.getType()), null);
32+
public static Field FIELD_LABELS = new Field(
33+
"labels",
34+
FieldType.nullable(Types.MinorType.LIST.getType()),
35+
List.of(new Field("$data$", FieldType.nullable(Types.MinorType.VARCHAR.getType()), null)));
36+
public static Field FIELD_SOURCE_ID =
37+
new Field("<source.id>", FieldType.nullable(Types.MinorType.BIGINT.getType()), null);
38+
public static Field FIELD_TARGET_ID =
39+
new Field("<target.id>", FieldType.nullable(Types.MinorType.BIGINT.getType()), null);
40+
public static Field FIELD_TYPE = new Field("<type>", FieldType.nullable(Types.MinorType.VARCHAR.getType()), null);
41+
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package apoc.export.arrow;
20+
21+
import apoc.Pools;
22+
import apoc.export.util.NodesAndRelsSubGraph;
23+
import apoc.result.ByteArrayResult;
24+
import apoc.result.ExportProgressInfo;
25+
import apoc.result.VirtualGraph;
26+
import org.neo4j.cypher.export.DatabaseSubGraph;
27+
import org.neo4j.cypher.export.SubGraph;
28+
import org.neo4j.graphdb.GraphDatabaseService;
29+
import org.neo4j.graphdb.Node;
30+
import org.neo4j.graphdb.Relationship;
31+
import org.neo4j.graphdb.Result;
32+
import org.neo4j.graphdb.Transaction;
33+
import org.neo4j.kernel.api.QueryLanguage;
34+
import org.neo4j.kernel.api.procedure.QueryLanguageScope;
35+
import org.neo4j.logging.Log;
36+
import org.neo4j.procedure.Context;
37+
import org.neo4j.procedure.Description;
38+
import org.neo4j.procedure.Name;
39+
import org.neo4j.procedure.NotThreadSafe;
40+
import org.neo4j.procedure.Procedure;
41+
import org.neo4j.procedure.TerminationGuard;
42+
43+
import java.util.Collection;
44+
import java.util.Collections;
45+
import java.util.Map;
46+
import java.util.stream.Stream;
47+
48+
public class ExportArrow {
49+
50+
@Context
51+
public Transaction tx;
52+
53+
@Context
54+
public GraphDatabaseService db;
55+
56+
@Context
57+
public Pools pools;
58+
59+
@Context
60+
public Log logger;
61+
62+
@Context
63+
public TerminationGuard terminationGuard;
64+
65+
@NotThreadSafe
66+
@Procedure(name = "apoc.export.arrow.stream.all", deprecatedBy = "This procedure is being moved to APOC Extended.")
67+
@Deprecated
68+
@QueryLanguageScope(scope = {QueryLanguage.CYPHER_25})
69+
@Description("Exports the full database as an arrow byte array.")
70+
public Stream<ByteArrayResult> all(
71+
@Name(value = "config", defaultValue = "{}", description = "{ batchSize = 2000 :: INTEGER }")
72+
Map<String, Object> config) {
73+
return new ExportArrowService(db, pools, terminationGuard, logger)
74+
.stream(new DatabaseSubGraph(tx), new ArrowConfig(config));
75+
}
76+
77+
@NotThreadSafe
78+
@Procedure(
79+
name = "apoc.export.arrow.stream.graph",
80+
deprecatedBy = "This procedure is being moved to APOC Extended.")
81+
@Deprecated
82+
@QueryLanguageScope(scope = {QueryLanguage.CYPHER_25})
83+
@Description("Exports the given graph as an arrow byte array.")
84+
public Stream<ByteArrayResult> graph(
85+
@Name(value = "graph", description = "The graph to export.") Object graph,
86+
@Name(value = "config", defaultValue = "{}", description = "{ batchSize = 2000 :: INTEGER }")
87+
Map<String, Object> config) {
88+
final SubGraph subGraph;
89+
if (graph instanceof Map) {
90+
Map<String, Object> mGraph = (Map<String, Object>) graph;
91+
if (!mGraph.containsKey("nodes")) {
92+
throw new IllegalArgumentException(
93+
"Graph Map must contains `nodes` field and `relationships` optionally");
94+
}
95+
subGraph = new NodesAndRelsSubGraph(
96+
tx, (Collection<Node>) mGraph.get("nodes"), (Collection<Relationship>) mGraph.get("relationships"));
97+
} else if (graph instanceof VirtualGraph) {
98+
VirtualGraph vGraph = (VirtualGraph) graph;
99+
subGraph = new NodesAndRelsSubGraph(tx, vGraph.nodes(), vGraph.relationships());
100+
} else {
101+
throw new IllegalArgumentException("Supported inputs are VirtualGraph, Map");
102+
}
103+
return new ExportArrowService(db, pools, terminationGuard, logger).stream(subGraph, new ArrowConfig(config));
104+
}
105+
106+
@NotThreadSafe
107+
@Procedure(
108+
name = "apoc.export.arrow.stream.query",
109+
deprecatedBy = "This procedure is being moved to APOC Extended.")
110+
@Deprecated
111+
@QueryLanguageScope(scope = {QueryLanguage.CYPHER_25})
112+
@Description("Exports the given Cypher query as an arrow byte array.")
113+
public Stream<ByteArrayResult> query(
114+
@Name(value = "query", description = "The query used to collect the data for export.") String query,
115+
@Name(value = "config", defaultValue = "{}", description = "{ batchSize = 2000 :: INTEGER }")
116+
Map<String, Object> config) {
117+
Map<String, Object> params = config == null
118+
? Collections.emptyMap()
119+
: (Map<String, Object>) config.getOrDefault("params", Collections.emptyMap());
120+
Result result = tx.execute(query, params);
121+
return new ExportArrowService(db, pools, terminationGuard, logger).stream(result, new ArrowConfig(config));
122+
}
123+
124+
@NotThreadSafe
125+
@Procedure(name = "apoc.export.arrow.all", deprecatedBy = "This procedure is being moved to APOC Extended.")
126+
@Deprecated
127+
@QueryLanguageScope(scope = {QueryLanguage.CYPHER_25})
128+
@Description("Exports the full database as an arrow file.")
129+
public Stream<ExportProgressInfo> all(
130+
@Name(value = "file", description = "The name of the file to export the data to.") String fileName,
131+
@Name(value = "config", defaultValue = "{}", description = "{ batchSize = 2000 :: INTEGER }")
132+
Map<String, Object> config) {
133+
return new ExportArrowService(db, pools, terminationGuard, logger)
134+
.file(fileName, new DatabaseSubGraph(tx), new ArrowConfig(config));
135+
}
136+
137+
@NotThreadSafe
138+
@Procedure(name = "apoc.export.arrow.graph", deprecatedBy = "This procedure is being moved to APOC Extended.")
139+
@Deprecated
140+
@QueryLanguageScope(scope = {QueryLanguage.CYPHER_25})
141+
@Description("Exports the given graph as an arrow file.")
142+
public Stream<ExportProgressInfo> graph(
143+
@Name(value = "file", description = "The name of the file to export the data to.") String fileName,
144+
@Name(value = "graph", description = "The graph to export.") Object graph,
145+
@Name(value = "config", defaultValue = "{}", description = "{ batchSize = 2000 :: INTEGER }")
146+
Map<String, Object> config) {
147+
final SubGraph subGraph;
148+
if (graph instanceof Map) {
149+
Map<String, Object> mGraph = (Map<String, Object>) graph;
150+
if (!mGraph.containsKey("nodes")) {
151+
throw new IllegalArgumentException(
152+
"Graph Map must contains `nodes` field and `relationships` optionally");
153+
}
154+
subGraph = new NodesAndRelsSubGraph(
155+
tx, (Collection<Node>) mGraph.get("nodes"), (Collection<Relationship>) mGraph.get("relationships"));
156+
} else if (graph instanceof VirtualGraph) {
157+
VirtualGraph vGraph = (VirtualGraph) graph;
158+
subGraph = new NodesAndRelsSubGraph(tx, vGraph.nodes(), vGraph.relationships());
159+
} else {
160+
throw new IllegalArgumentException("Supported inputs are VirtualGraph, Map");
161+
}
162+
return new ExportArrowService(db, pools, terminationGuard, logger)
163+
.file(fileName, subGraph, new ArrowConfig(config));
164+
}
165+
166+
@NotThreadSafe
167+
@Procedure(name = "apoc.export.arrow.query", deprecatedBy = "This procedure is being moved to APOC Extended.")
168+
@Deprecated
169+
@QueryLanguageScope(scope = {QueryLanguage.CYPHER_25})
170+
@Description("Exports the results from the given Cypher query as an arrow file.")
171+
public Stream<ExportProgressInfo> query(
172+
@Name(value = "file", description = "The name of the file to which the data will be exported.")
173+
String fileName,
174+
@Name(value = "query", description = "The query to use to collect the data for export.") String query,
175+
@Name(value = "config", defaultValue = "{}", description = "{ batchSize = 2000 :: INTEGER }")
176+
Map<String, Object> config) {
177+
Map<String, Object> params = config == null
178+
? Collections.emptyMap()
179+
: (Map<String, Object>) config.getOrDefault("params", Collections.emptyMap());
180+
Result result = tx.execute(query, params);
181+
return new ExportArrowService(db, pools, terminationGuard, logger)
182+
.file(fileName, result, new ArrowConfig(config));
183+
}
184+
}

0 commit comments

Comments
 (0)