diff --git a/src/Patterns/Node.php b/src/Patterns/Node.php index 1c1bd4b..81541f0 100644 --- a/src/Patterns/Node.php +++ b/src/Patterns/Node.php @@ -12,6 +12,7 @@ use WikibaseSolutions\CypherDSL\Expressions\Label; use WikibaseSolutions\CypherDSL\Expressions\Literals\Map; +use function WikibaseSolutions\CypherDSL\node; use WikibaseSolutions\CypherDSL\Traits\PatternTraits\PropertyPatternTrait; use WikibaseSolutions\CypherDSL\Utils\NameUtils; @@ -77,6 +78,17 @@ public function getLabels(): array return $this->labels; } + /** + * Create a new node with the same variable as this node. Useful for using nodes + * inside a CREATE clause that were previously matched on in a MATCH clause. + * + * @see https://github.com/neo4j-php/php-cypher-dsl/issues/96 + */ + public function variable(): self + { + return node()->withVariable($this->getVariable()); + } + /** * Returns a label with the variable in this node. * diff --git a/tests/end-to-end/ExamplesTest.php b/tests/end-to-end/ExamplesTest.php index 00292ee..beec937 100644 --- a/tests/end-to-end/ExamplesTest.php +++ b/tests/end-to-end/ExamplesTest.php @@ -227,6 +227,21 @@ public function testMatchClauseExample1(): void $this->assertStringMatchesFormat("MATCH (%s) RETURN %s", $query); } + public function testCreateReuseVariable(): void + { + $charlie = node("Person")->withProperties(["name" => "Charlie Sheen"]); + $oliver = node("Person")->withProperties(["name" => "Oliver Stone"]); + + $wallStreet = node("Movie")->withProperties(["title" => "Wall Street"]); + + $query = query() + ->match([$charlie, $oliver]) + ->create($charlie->variable()->relationshipTo($wallStreet, type: "ACTED_IN", properties: ["role" => "Bud Fox"])->relationshipFrom($oliver->variable())) + ->build(); + + $this->assertStringMatchesFormat("MATCH (%s:Person {name: 'Charlie Sheen'}), (%s:Person {name: 'Oliver Stone'}) CREATE (%s)-[:ACTED_IN {role: 'Bud Fox'}]->(:Movie {title: 'Wall Street'})<--(%s)", $query); + } + public function testMatchClauseExample2(): void { $movie = node("Movie"); diff --git a/tests/unit/Patterns/NodeTest.php b/tests/unit/Patterns/NodeTest.php index f9b6548..c249236 100644 --- a/tests/unit/Patterns/NodeTest.php +++ b/tests/unit/Patterns/NodeTest.php @@ -325,4 +325,36 @@ public function testLabeledMultipleLabels(): void $this->assertEquals(new Label($node->getVariable(), 'German', 'Swedish'), $labeled); } + + public function testVariableNewNode(): void + { + $node = new Node(); + $variable = $node->variable(); + + $this->assertMatchesRegularExpression('/^\(var\w{8}\)$/', $variable->toQuery()); + } + + public function testVariableNodeWithProperties(): void + { + $node = new Node(); + $node->withProperties(['a' => 1, 'b' => 2, 'c' => 3]); + + $this->assertStringMatchesFormat('({a: 1, b: 2, c: 3})', $node->toQuery()); + + $variable = $node->variable(); + + $this->assertMatchesRegularExpression('/^\(var\w{8}\)$/', $variable->toQuery()); + } + + public function testVariableNodeWithExistingVariable(): void + { + $node = new Node(); + $node->withVariable('foo'); + + $this->assertSame('(foo)', $node->toQuery()); + + $variable = $node->variable(); + + $this->assertSame('(foo)', $variable->toQuery()); + } }