Skip to content

Commit

Permalink
[Gc8EZpDO] Add element id as an option to functions using nodes/rels …
Browse files Browse the repository at this point in the history
…with type ANY
  • Loading branch information
gem-neo4j committed Sep 28, 2023
1 parent a36b11e commit 2bc733e
Show file tree
Hide file tree
Showing 10 changed files with 327 additions and 97 deletions.
6 changes: 3 additions & 3 deletions common/src/main/java/apoc/get/Get.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@
import apoc.result.NodeResult;
import apoc.result.RelationshipResult;
import apoc.util.Util;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.procedure.Name;

import java.util.stream.Stream;

public class Get {

public Transaction tx;
public InternalTransaction tx;

public Get(Transaction tx) {
public Get(InternalTransaction tx) {
this.tx = tx;
}

Expand Down
22 changes: 12 additions & 10 deletions common/src/main/java/apoc/util/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,24 +170,26 @@ public static Stream<Object> stream(Object values) {
return ConvertUtils.convertToList(values).stream();
}

public static Stream<Node> nodeStream(Transaction tx, Object ids) {
public static Stream<Node> nodeStream(InternalTransaction tx, Object ids) {
return stream(ids).map(id -> node(tx, id));
}

public static Node node(Transaction tx, Object id) {
if (id instanceof Node) return rebind(tx, (Node)id);
if (id instanceof Number) return tx.getNodeById(((Number)id).longValue());
throw new RuntimeException("Can't convert "+id.getClass()+" to a Node");
public static Node node(InternalTransaction tx, Object id) {
if (id instanceof Node node) return rebind(tx, node);
if (id instanceof Number nodeId) return tx.getNodeByElementId(tx.elementIdMapper().nodeElementId(nodeId.longValue()));
if (id instanceof String elementId) return tx.getNodeByElementId(elementId);
throw new RuntimeException("Can't convert " + id.getClass() + " to a Node");
}

public static Stream<Relationship> relsStream(Transaction tx, Object ids) {
public static Stream<Relationship> relsStream(InternalTransaction tx, Object ids) {
return stream(ids).map(id -> relationship(tx, id));
}

public static Relationship relationship(Transaction tx, Object id) {
if (id instanceof Relationship) return rebind(tx, (Relationship)id);
if (id instanceof Number) return tx.getRelationshipById(((Number)id).longValue());
throw new RuntimeException("Can't convert "+id.getClass()+" to a Relationship");
public static Relationship relationship(InternalTransaction tx, Object id) {
if (id instanceof Relationship rel) return rebind(tx, rel);
if (id instanceof Number relId) return tx.getRelationshipByElementId(tx.elementIdMapper().relationshipElementId(relId.longValue()));
if (id instanceof String elementId) return tx.getRelationshipByElementId(elementId);
throw new RuntimeException("Can't convert " + id.getClass() + " to a Relationship");
}

public static <T> T retryInTx(Log log, GraphDatabaseService db, Function<Transaction, T> function, long retry, long maxRetries, Consumer<Long> callbackForRetry) {
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/apoc/algo/Cover.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.procedure.Context;
import org.neo4j.procedure.Description;
import org.neo4j.procedure.Name;
Expand All @@ -44,7 +45,7 @@ public class Cover {
@Procedure("apoc.algo.cover")
@Description("Returns all relationships between a given set of nodes.")
public Stream<RelationshipResult> cover(@Name("nodes") Object nodes) {
Set<Node> nodeSet = Util.nodeStream(tx, nodes).collect(Collectors.toSet());
Set<Node> nodeSet = Util.nodeStream((InternalTransaction) tx, nodes).collect(Collectors.toSet());
return coverNodes(nodeSet).map(RelationshipResult::new);
}

Expand Down
19 changes: 10 additions & 9 deletions core/src/main/java/apoc/create/Create.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import apoc.util.collection.Iterables;
import apoc.uuid.UuidUtil;
import org.neo4j.graphdb.*;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.procedure.*;

import java.util.HashMap;
Expand Down Expand Up @@ -53,7 +54,7 @@ public Stream<NodeResult> node(@Name("labels") List<String> labelNames, @Name("p
@Description("Adds the given labels to the given nodes.")
public Stream<NodeResult> addLabels(@Name("nodes") Object nodes, @Name("labels") List<String> labelNames) {
Label[] labels = Util.labels(labelNames);
return new Get(tx).nodes(nodes).map((r) -> {
return new Get((InternalTransaction) tx).nodes(nodes).map((r) -> {
Node node = r.node;
for (Label label : labels) {
node.addLabel(label);
Expand All @@ -65,7 +66,7 @@ public Stream<NodeResult> addLabels(@Name("nodes") Object nodes, @Name("labels")
@Procedure(name = "apoc.create.setProperty", mode = Mode.WRITE)
@Description("Sets the given property to the given node(s).")
public Stream<NodeResult> setProperty(@Name("nodes") Object nodes, @Name("key") String key, @Name("value") Object value) {
return new Get(tx).nodes(nodes).map((r) -> {
return new Get((InternalTransaction) tx).nodes(nodes).map((r) -> {
setProperty(r.node, key,toPropertyValue(value));
return r;
});
Expand All @@ -74,7 +75,7 @@ public Stream<NodeResult> setProperty(@Name("nodes") Object nodes, @Name("key")
@Procedure(name = "apoc.create.setRelProperty", mode = Mode.WRITE)
@Description("Sets the given property on the relationship(s).")
public Stream<RelationshipResult> setRelProperty(@Name("rels") Object rels, @Name("key") String key, @Name("value") Object value) {
return new Get(tx).rels(rels).map((r) -> {
return new Get((InternalTransaction) tx).rels(rels).map((r) -> {
setProperty(r.rel,key,toPropertyValue(value));
return r;
});
Expand All @@ -83,7 +84,7 @@ public Stream<RelationshipResult> setRelProperty(@Name("rels") Object rels, @Nam
@Procedure(name = "apoc.create.setProperties", mode = Mode.WRITE)
@Description("Sets the given properties to the given node(s).")
public Stream<NodeResult> setProperties(@Name("nodes") Object nodes, @Name("keys") List<String> keys, @Name("values") List<Object> values) {
return new Get(tx).nodes(nodes).map((r) -> {
return new Get((InternalTransaction) tx).nodes(nodes).map((r) -> {
setProperties(r.node, Util.mapFromLists(keys,values));
return r;
});
Expand All @@ -92,7 +93,7 @@ public Stream<NodeResult> setProperties(@Name("nodes") Object nodes, @Name("keys
@Procedure(name = "apoc.create.removeProperties", mode = Mode.WRITE)
@Description("Removes the given properties from the given node(s).")
public Stream<NodeResult> removeProperties(@Name("nodes") Object nodes, @Name("keys") List<String> keys) {
return new Get(tx).nodes(nodes).map((r) -> {
return new Get((InternalTransaction) tx).nodes(nodes).map((r) -> {
keys.forEach( r.node::removeProperty );
return r;
});
Expand All @@ -101,7 +102,7 @@ public Stream<NodeResult> removeProperties(@Name("nodes") Object nodes, @Name("k
@Procedure(name = "apoc.create.setRelProperties", mode = Mode.WRITE)
@Description("Sets the given properties on the relationship(s).")
public Stream<RelationshipResult> setRelProperties(@Name("rels") Object rels, @Name("keys") List<String> keys, @Name("values") List<Object> values) {
return new Get(tx).rels(rels).map((r) -> {
return new Get((InternalTransaction) tx).rels(rels).map((r) -> {
setProperties(r.rel, Util.mapFromLists(keys,values));
return r;
});
Expand All @@ -110,7 +111,7 @@ public Stream<RelationshipResult> setRelProperties(@Name("rels") Object rels, @N
@Procedure(name = "apoc.create.removeRelProperties", mode = Mode.WRITE)
@Description("Removes the given properties from the given relationship(s).")
public Stream<RelationshipResult> removeRelProperties(@Name("rels") Object rels, @Name("keys") List<String> keys) {
return new Get(tx).rels(rels).map((r) -> {
return new Get((InternalTransaction) tx).rels(rels).map((r) -> {
keys.forEach( r.rel::removeProperty);
return r;
});
Expand All @@ -120,7 +121,7 @@ public Stream<RelationshipResult> removeRelProperties(@Name("rels") Object rels,
@Description("Sets the given labels to the given node(s). Non-matching labels are removed from the nodes.")
public Stream<NodeResult> setLabels(@Name("nodes") Object nodes, @Name("labels") List<String> labelNames) {
Label[] labels = Util.labels(labelNames);
return new Get(tx).nodes(nodes).map((r) -> {
return new Get((InternalTransaction) tx).nodes(nodes).map((r) -> {
Node node = r.node;
for (Label label : node.getLabels()) {
if (labelNames.contains(label.name())) continue;
Expand All @@ -138,7 +139,7 @@ public Stream<NodeResult> setLabels(@Name("nodes") Object nodes, @Name("labels")
@Description("Removes the given labels from the given node(s).")
public Stream<NodeResult> removeLabels(@Name("nodes") Object nodes, @Name("labels") List<String> labelNames) {
Label[] labels = Util.labels(labelNames);
return new Get(tx).nodes(nodes).map((r) -> {
return new Get((InternalTransaction) tx).nodes(nodes).map((r) -> {
Node node = r.node;
for (Label label : labels) {
node.removeLabel(label);
Expand Down
10 changes: 5 additions & 5 deletions core/src/main/java/apoc/nodes/Nodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,13 @@ public void link(@Name("nodes") List<Node> nodes, @Name("type") String type, @Na
@Procedure("apoc.nodes.get")
@Description("Returns all nodes with the given ids.")
public Stream<NodeResult> get(@Name("nodes") Object ids) {
return Util.nodeStream(tx, ids).map(NodeResult::new);
return Util.nodeStream((InternalTransaction) tx, ids).map(NodeResult::new);
}

@Procedure(name = "apoc.nodes.delete", mode = Mode.WRITE)
@Description("Deletes all nodes with the given ids.")
public Stream<LongResult> delete(@Name("nodes") Object ids, @Name("batchSize") long batchSize) {
Iterator<Node> it = Util.nodeStream(tx, ids).iterator();
Iterator<Node> it = Util.nodeStream((InternalTransaction) tx, ids).iterator();
long count = 0;
while (it.hasNext()) {
final List<Node> batch = Util.take(it, (int)batchSize);
Expand All @@ -189,7 +189,7 @@ public Stream<LongResult> delete(@Name("nodes") Object ids, @Name("batchSize") l
@Procedure("apoc.nodes.rels")
@Description("Returns all relationships with the given ids.")
public Stream<RelationshipResult> rels(@Name("rels") Object ids) {
return Util.relsStream(tx, ids).map(RelationshipResult::new);
return Util.relsStream((InternalTransaction) tx, ids).map(RelationshipResult::new);
}

@UserFunction("apoc.node.relationship.exists")
Expand Down Expand Up @@ -520,7 +520,7 @@ public List<String> relationshipTypes(@Name("node") Node node, @Name(value = "re
@Description("Returns a list of distinct relationship types from the given list of nodes.")
public List<Map<String, Object>> nodesRelationshipTypes(@Name("nodes") Object ids, @Name(value = "types",defaultValue = "") String types) {
if (ids == null) return null;
return Util.nodeStream(tx, ids)
return Util.nodeStream((InternalTransaction) tx, ids)
.map(node -> {
final List<String> relationshipTypes = relationshipTypes(node, types);
if (relationshipTypes == null) {
Expand Down Expand Up @@ -551,7 +551,7 @@ public Map<String,Boolean> relationshipExists(@Name("node") Node node, @Name(val
@Description("Returns a boolean based on whether or not the given nodes have the given relationships.")
public List<Map<String, Object>> nodesRelationshipExists(@Name("nodes") Object ids, @Name(value = "types", defaultValue = "") String types) {
if (ids == null) return null;
return Util.nodeStream(tx, ids)
return Util.nodeStream((InternalTransaction) tx, ids)
.map(node -> {
final Map<String, Boolean> existsMap = relationshipExists(node, types);
if (existsMap == null) {
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/apoc/refactor/GraphRefactoring.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.commons.collections4.IterableUtils;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.schema.ConstraintType;
import org.neo4j.kernel.impl.coreapi.InternalTransaction;
import org.neo4j.logging.Log;
import org.neo4j.procedure.*;

Expand Down Expand Up @@ -89,7 +90,7 @@ private Stream<NodeRefactorResult> doCloneNodes(@Name("nodes") List<Node> nodes,
@Description("Expands the given relationships into intermediate nodes.\n" +
"The intermediate nodes are connected by the given 'OUT' and 'IN' types.")
public Stream<NodeRefactorResult> extractNode(@Name("rels") Object rels, @Name("labels") List<String> labels, @Name("outType") String outType, @Name("inType") String inType) {
return Util.relsStream(tx, rels).map((rel) -> {
return Util.relsStream((InternalTransaction) tx, rels).map((rel) -> {
NodeRefactorResult result = new NodeRefactorResult(rel.getId());
try {
Node copy = withTransactionAndRebind(db, tx, transaction -> {
Expand All @@ -109,7 +110,7 @@ public Stream<NodeRefactorResult> extractNode(@Name("rels") Object rels, @Name("
@Procedure(name = "apoc.refactor.collapseNode", mode = Mode.WRITE)
@Description("Collapses the given node and replaces it with a relationship of the given type.")
public Stream<RelationshipRefactorResult> collapseNode(@Name("nodes") Object nodes, @Name("relType") String type) {
return Util.nodeStream(tx, nodes).map((node) -> {
return Util.nodeStream((InternalTransaction) tx, nodes).map((node) -> {
RelationshipRefactorResult result = new RelationshipRefactorResult(node.getId());
try {
Iterable<Relationship> outRels = node.getRelationships(Direction.OUTGOING);
Expand Down
Loading

0 comments on commit 2bc733e

Please sign in to comment.