From bb79bb2956797d9510970864ce05c777d4146fb2 Mon Sep 17 00:00:00 2001 From: Stefan Armbruster Date: Sun, 7 Jul 2024 13:39:59 +0200 Subject: [PATCH] fix: bolt layer cannot deal with EmptyPath Returning an EmptyPath from a stored procedure works on java level, but bolt throws some strange exceptions. In case of an EmptyPath instead a empty result (aka no line) is returned. Refs: #8 --- .../java/atag/chains/ChainsProcedure.java | 3 +- src/main/java/atag/util/EmptyPath.java | 56 ------------------- .../java/atag/chains/ChainsProcedureTest.java | 45 ++++++++------- 3 files changed, 23 insertions(+), 81 deletions(-) delete mode 100644 src/main/java/atag/util/EmptyPath.java diff --git a/src/main/java/atag/chains/ChainsProcedure.java b/src/main/java/atag/chains/ChainsProcedure.java index ee35058..dca751d 100644 --- a/src/main/java/atag/chains/ChainsProcedure.java +++ b/src/main/java/atag/chains/ChainsProcedure.java @@ -1,6 +1,5 @@ package atag.chains; -import atag.util.EmptyPath; import atag.util.ResultTypes; import org.neo4j.graphalgo.impl.util.PathImpl; import org.neo4j.graphdb.*; @@ -192,7 +191,7 @@ public Stream update( } currentNode.createRelationshipTo(afterNode, relationshipType); } - return asPathResult(builder == null ? new EmptyPath() : builder.build()); + return builder == null ? Stream.empty() : asPathResult(builder.build()); } private Node findNodeOrThrow(Label textLabel, String uuidProperty, String uuidText) { diff --git a/src/main/java/atag/util/EmptyPath.java b/src/main/java/atag/util/EmptyPath.java deleted file mode 100644 index d14677f..0000000 --- a/src/main/java/atag/util/EmptyPath.java +++ /dev/null @@ -1,56 +0,0 @@ -package atag.util; - -import org.neo4j.graphdb.Entity; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.Path; -import org.neo4j.graphdb.Relationship; -import org.neo4j.internal.helpers.collection.Iterables; - -import java.util.Iterator; - -public class EmptyPath implements Path { - @Override - public Node startNode() { - return null; - } - - @Override - public Node endNode() { - return null; - } - - @Override - public Relationship lastRelationship() { - return null; - } - - @Override - public Iterable relationships() { - return Iterables.empty(); - } - - @Override - public Iterable reverseRelationships() { - return Iterables.empty(); - } - - @Override - public Iterable nodes() { - return Iterables.empty(); - } - - @Override - public Iterable reverseNodes() { - return Iterables.empty(); - } - - @Override - public int length() { - return 0; - } - - @Override - public Iterator iterator() { - return Iterables.empty().iterator(); - } -} diff --git a/src/test/java/atag/chains/ChainsProcedureTest.java b/src/test/java/atag/chains/ChainsProcedureTest.java index 8cd4b29..7bbf9dd 100644 --- a/src/test/java/atag/chains/ChainsProcedureTest.java +++ b/src/test/java/atag/chains/ChainsProcedureTest.java @@ -29,7 +29,7 @@ public class ChainsProcedureTest { @RegisterExtension static Neo4jExtension neo4j = Neo4jExtension.builder() - .withDisabledServer() + //.withDisabledServer() .withProcedure(ChainsProcedure.class) /*.withFixture(db -> { try { @@ -92,20 +92,26 @@ private static void validatePathLength(GraphDatabaseService db, String query, Ma db.executeTransactionally(query, params, result -> { - Path path = (Path) Iterators.single(result).get("path"); - if (logger.isLoggable(Level.INFO)) { - StringBuilder sb = new StringBuilder(); - for (Node node: path.nodes()) { - sb.append("(").append(node.getProperty("uuid")).append(")"); - if (!node.equals(path.endNode())) { - sb.append("->"); - } + Map singleResult = Iterators.singleOrNull(result); + if (singleResult == null) { + assertEquals(expectedPathLength, 0); + return false; + } else { + Path path = (Path) singleResult.get("path"); + if (logger.isLoggable(Level.INFO)) { + StringBuilder sb = new StringBuilder(); + for (Node node: path.nodes()) { + sb.append("(").append(node.getProperty("uuid")).append(")"); + if (!node.equals(path.endNode())) { + sb.append("->"); + } + } + logger.info("path is %s".formatted(sb.toString())); } - logger.info("path is %s".formatted(sb.toString())); + assertEquals(expectedPathLength, path.length(), "failed path length assertion for %s".formatted(query)); + assertion.accept(path); } - assertEquals(expectedPathLength, path.length(), "failed path length assertion for %s".formatted(query)); - assertion.accept(path); return true; }); } @@ -200,7 +206,7 @@ public void testTokenChain(String text, int expected, GraphDatabaseService db) { public static Stream testChainUpdate() { return Stream.of( - Arguments.of("removal of unbounded chain", 0, null, null, Collections.emptyList(), 0, 0, 0, null), + Arguments.of("removal of unbounded chain", 0, "", "", Collections.emptyList(), 0, 0, 0, null), Arguments.of("removal of unbounded chain", 1, null, null, Collections.emptyList(), 0, 0, 0, null), Arguments.of("removal of unbounded chain", 10, null, null, Collections.emptyList(), 0, 0, 0, null), Arguments.of("removal of bounded chain", 10, "0", "9", Collections.emptyList(), 0, 2, 2, null), @@ -223,8 +229,8 @@ public static Stream testChainUpdate() { @ParameterizedTest(name = "{index}: {0} with fixture length {1}, boundaries ({2}, {3}") @MethodSource public void testChainUpdate(String name, int fixtureLength, String uuidBefore, String uuidAfter, List> characterList, - int expectedLength, int expectedQueryLength, int expectedNumberOfTokens, Class exceptedException, - GraphDatabaseService db) { + int expectedLength, int expectedQueryLength, int expectedNumberOfTokens, Class exceptedException, + GraphDatabaseService db) { String uuidText = "text"; Map params = Map.of( "uuidText", uuidText, @@ -250,14 +256,6 @@ public void testChainUpdate(String name, int fixtureLength, String uuidBefore, S try { // cut - db.executeTransactionally(""" - CALL atag.chains.update("text", $uuidBefore, $uuidAfter, $characterList, $config) YIELD path - RETURN path - """, params); - if (exceptedException !=null) { - fail("expected a exception but did not get one."); - } - validatePathLength(db, """ CALL atag.chains.update("text", $uuidBefore, $uuidAfter, $characterList, $config) YIELD path RETURN path @@ -282,4 +280,5 @@ WHERE NOT (x)-[:NEXT_TOKEN]->() } } } + }