From c0643b7ee3b759ff398e5351564044c4c6a60744 Mon Sep 17 00:00:00 2001 From: William Gorder Date: Mon, 23 Feb 2015 10:35:37 -0500 Subject: [PATCH] Add support for ON MATCH and ON CREATE Added support for ON MATCH and ON CREATE which can follow a merge clause. Added some supporting test cases. --- .../java/org/neo4j/cypherdsl/CypherQuery.java | 67 +++++++++++++++++++ .../org/neo4j/cypherdsl/grammar/OnCreate.java | 13 ++++ .../org/neo4j/cypherdsl/grammar/OnMatch.java | 13 ++++ .../neo4j/cypherdsl/grammar/UpdateNext.java | 2 +- .../query/clause/OnCreateClause.java | 31 +++++++++ .../cypherdsl/query/clause/OnMatchClause.java | 30 +++++++++ .../neo4j/cypherdsl/CypherReferenceTest.java | 37 ++++++++++ 7 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/neo4j/cypherdsl/grammar/OnCreate.java create mode 100644 src/main/java/org/neo4j/cypherdsl/grammar/OnMatch.java create mode 100644 src/main/java/org/neo4j/cypherdsl/query/clause/OnCreateClause.java create mode 100644 src/main/java/org/neo4j/cypherdsl/query/clause/OnMatchClause.java diff --git a/src/main/java/org/neo4j/cypherdsl/CypherQuery.java b/src/main/java/org/neo4j/cypherdsl/CypherQuery.java index 9ae0f6751b..057610f567 100644 --- a/src/main/java/org/neo4j/cypherdsl/CypherQuery.java +++ b/src/main/java/org/neo4j/cypherdsl/CypherQuery.java @@ -1922,6 +1922,73 @@ public UpdateNext set( Iterable setProperties ) return this; } + + // On Create ------------------------------------------------------ + @Override + public UpdateNext onCreate(SetProperty... setProperties) { + Clause clause = query.lastClause(Clause.class); + if (clause instanceof MergeClause || clause instanceof OnMatchClause) + { + query.add(new OnCreateClause(Arrays.asList(setProperties))); + } + else + { + throw new IllegalArgumentException("ON CREATE must follow a MERGE or ON MATCH Clause"); + } + + + return this; + } + + @Override + public UpdateNext onCreate(Iterable setProperties) { + Clause clause = query.lastClause(Clause.class); + if (clause instanceof MergeClause || clause instanceof OnMatchClause) + { + query.add( new OnCreateClause( setProperties ) ); + } + else + { + throw new IllegalArgumentException("ON CREATE must follow a MERGE or ON MATCH Clause"); + } + + + return this; + } + + // On Match ------------------------------------------------------ + @Override + public UpdateNext onMatch(SetProperty... setProperties) { + Clause clause = query.lastClause(Clause.class); + if (clause instanceof MergeClause || clause instanceof OnCreateClause) + { + query.add( new OnMatchClause( Arrays.asList( setProperties ) ) ); + } + else + { + throw new IllegalArgumentException("ON MATCH must follow a MERGE or ON CREATE Clause"); + } + + + return this; + } + + @Override + public UpdateNext onMatch(Iterable setProperties) { + Clause clause = query.lastClause(Clause.class); + if (clause instanceof MergeClause || clause instanceof OnCreateClause) + { + query.add( new OnMatchClause( setProperties ) ); + } + else + { + throw new IllegalArgumentException("ON MATCH must follow a MERGE or ON CREATE Clause"); + } + + + return this; + } + // Delete ------------------------------------------------------- @Override public UpdateNext delete( ReferenceExpression... expressions ) diff --git a/src/main/java/org/neo4j/cypherdsl/grammar/OnCreate.java b/src/main/java/org/neo4j/cypherdsl/grammar/OnCreate.java new file mode 100644 index 0000000000..63386ef34e --- /dev/null +++ b/src/main/java/org/neo4j/cypherdsl/grammar/OnCreate.java @@ -0,0 +1,13 @@ +package org.neo4j.cypherdsl.grammar; + +import org.neo4j.cypherdsl.SetProperty; + +/** + * Represents the ON CREATE clause + */ +public interface OnCreate +{ + UpdateNext onCreate( SetProperty... propertyValues ); + + UpdateNext onCreate( Iterable propertyValues ); +} diff --git a/src/main/java/org/neo4j/cypherdsl/grammar/OnMatch.java b/src/main/java/org/neo4j/cypherdsl/grammar/OnMatch.java new file mode 100644 index 0000000000..3d17c4007a --- /dev/null +++ b/src/main/java/org/neo4j/cypherdsl/grammar/OnMatch.java @@ -0,0 +1,13 @@ +package org.neo4j.cypherdsl.grammar; + +import org.neo4j.cypherdsl.SetProperty; + +/** + * Represents the ON MATCH clause + */ +public interface OnMatch +{ + UpdateNext onMatch( SetProperty... propertyValues ); + + UpdateNext onMatch( Iterable propertyValues ); +} diff --git a/src/main/java/org/neo4j/cypherdsl/grammar/UpdateNext.java b/src/main/java/org/neo4j/cypherdsl/grammar/UpdateNext.java index 2d63e5be2a..7481432e22 100644 --- a/src/main/java/org/neo4j/cypherdsl/grammar/UpdateNext.java +++ b/src/main/java/org/neo4j/cypherdsl/grammar/UpdateNext.java @@ -24,6 +24,6 @@ * This specifies what can come after an update clause */ public interface UpdateNext - extends Update, ForEach, With, Return + extends Update, ForEach, With, Return, OnCreate, OnMatch { } diff --git a/src/main/java/org/neo4j/cypherdsl/query/clause/OnCreateClause.java b/src/main/java/org/neo4j/cypherdsl/query/clause/OnCreateClause.java new file mode 100644 index 0000000000..15f50b3ef3 --- /dev/null +++ b/src/main/java/org/neo4j/cypherdsl/query/clause/OnCreateClause.java @@ -0,0 +1,31 @@ +package org.neo4j.cypherdsl.query.clause; + +import org.neo4j.cypherdsl.SetProperty; + +import java.util.ArrayList; + +/** + * ON CREATE clause + */ +public class OnCreateClause + extends Clause +{ + private final ArrayList expressions = new ArrayList(); + + public OnCreateClause( Iterable expressions ) + { + for ( SetProperty expression : expressions ) + { + this.expressions.add( expression ); + } + } + + @Override + public void asString( StringBuilder builder ) + { + String name = " ON CREATE"; + builder.append(name); + clauseAsString( builder, "SET", expressions, "," ); + } +} + diff --git a/src/main/java/org/neo4j/cypherdsl/query/clause/OnMatchClause.java b/src/main/java/org/neo4j/cypherdsl/query/clause/OnMatchClause.java new file mode 100644 index 0000000000..de8a03daf3 --- /dev/null +++ b/src/main/java/org/neo4j/cypherdsl/query/clause/OnMatchClause.java @@ -0,0 +1,30 @@ +package org.neo4j.cypherdsl.query.clause; + +import org.neo4j.cypherdsl.SetProperty; + +import java.util.ArrayList; + +/** + * ON CREATE clause + */ +public class OnMatchClause + extends Clause +{ + private final ArrayList expressions = new ArrayList(); + + public OnMatchClause( Iterable expressions ) + { + for ( SetProperty expression : expressions ) + { + this.expressions.add( expression ); + } + } + + @Override + public void asString( StringBuilder builder ) + { + String name = " ON MATCH"; + builder.append(name); + clauseAsString( builder, "SET", expressions, "," ); + } +} diff --git a/src/test/java/org/neo4j/cypherdsl/CypherReferenceTest.java b/src/test/java/org/neo4j/cypherdsl/CypherReferenceTest.java index 0f45cf35da..4cc59c6ac8 100644 --- a/src/test/java/org/neo4j/cypherdsl/CypherReferenceTest.java +++ b/src/test/java/org/neo4j/cypherdsl/CypherReferenceTest.java @@ -1309,4 +1309,41 @@ public void test_9_7_1_UnionAll() toString() ); } + @Test + public void test_13_2_1_MergeOnCreate() + { + assertQueryEquals(CYPHER + "MERGE (keanu:Person {name:\"Keanu Reeves\"}) " + + "ON CREATE SET keanu.movie=\"Matrix\"", + merge(node(identifier("keanu")).label("Person").values(value("name", "Keanu Reeves"))) + .onCreate(property(identifier("keanu").property("movie"), + literal("Matrix"))).toString()); + } + + @Test + public void test_13_2_1_MergeOnMatch() + { + assertQueryEquals(CYPHER + "MERGE (keanu:Person {name:\"Keanu Reeves\"}) " + + "ON MATCH SET keanu.movie=\"Matrix\"", + merge(node(identifier("keanu")).label("Person").values(value("name", "Keanu Reeves"))) + .onMatch(property(identifier("keanu").property("movie"), + literal("Matrix"))).toString()); + } + + @Test + public void test_13_2_1_MergeOnMatchAndOnCreate() + { + assertQueryEquals(CYPHER + "MERGE (keanu:Person {name:\"Keanu Reeves\"}) " + + "ON CREATE SET keanu.movie=\"Matrix\" " + + "ON MATCH SET keanu.movie=\"Matrix\",keanu.found=true " + + "RETURN keanu", + merge(node(identifier("keanu")).label("Person").values(value("name", "Keanu Reeves"))) + .onCreate(property(identifier("keanu").property("movie"), + literal("Matrix"))) + .onMatch(property(identifier("keanu").property("movie"), + literal("Matrix")), property(identifier("keanu").property("found"), + literal(true))) + .returns(identifier("keanu")) + .toString()); + } + }