File tree Expand file tree Collapse file tree 4 files changed +149
-0
lines changed Expand file tree Collapse file tree 4 files changed +149
-0
lines changed Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace WikibaseSolutions \CypherDSL \Clauses ;
4+
5+ use WikibaseSolutions \CypherDSL \Query ;
6+
7+ /**
8+ * This class represents a CALL clause.
9+ *
10+ * @see https://neo4j.com/docs/cypher-manual/current/clauses/call-subquery/
11+ */
12+ class CallClause extends Clause
13+ {
14+ /**
15+ * @var Query The query to call.
16+ */
17+ private Query $ subQuery ;
18+
19+ /**
20+ * @param Query $subQuery The query to call.
21+ */
22+ public function __construct (Query $ subQuery )
23+ {
24+ $ this ->subQuery = $ subQuery ;
25+ }
26+
27+ /**
28+ * Returns the query that is being called.
29+ *
30+ * @return Query
31+ */
32+ public function getSubQuery (): Query
33+ {
34+ return $ this ->subQuery ;
35+ }
36+
37+ public function toQuery (): string
38+ {
39+ $ subQuery = trim ($ this ->subQuery ->toQuery ());
40+
41+ if ($ subQuery === '' ) {
42+ return '' ;
43+ }
44+
45+ return sprintf ('CALL { %s } ' , $ subQuery );
46+ }
47+
48+ /**
49+ * @inheritDoc
50+ */
51+ protected function getSubject (): string
52+ {
53+ return '{ ' . $ this ->subQuery ->toQuery () . ' } ' ;
54+ }
55+
56+ /**
57+ * @inheritDoc
58+ */
59+ protected function getClause (): string
60+ {
61+ return 'CALL ' ;
62+ }
63+ }
Original file line number Diff line number Diff line change 2121
2222namespace WikibaseSolutions \CypherDSL ;
2323
24+ use Closure ;
25+ use Prophecy \Call \Call ;
26+ use WikibaseSolutions \CypherDSL \Clauses \CallClause ;
2427use WikibaseSolutions \CypherDSL \Clauses \CallProcedureClause ;
2528use WikibaseSolutions \CypherDSL \Clauses \Clause ;
2629use WikibaseSolutions \CypherDSL \Clauses \CreateClause ;
@@ -666,6 +669,29 @@ public function union($queryOrCallable, bool $all = false): self
666669 return $ this ;
667670 }
668671
672+ /**
673+ * Creates a CALL sub query clause.
674+ *
675+ * @param callable(Query)|Query $decoratorOrClause The callable decorating the pattern, or the actual CALL clause.
676+ *
677+ * @return Query
678+ *
679+ * @see https://neo4j.com/docs/cypher-manual/current/clauses/call-subquery/
680+ */
681+ public function call ($ decoratorOrClause ): self
682+ {
683+ if (is_callable ($ decoratorOrClause )) {
684+ $ subQuery = self ::new ();
685+ $ decoratorOrClause ($ subQuery );
686+ } else {
687+ $ subQuery = $ decoratorOrClause ;
688+ }
689+
690+ $ this ->clauses [] = new CallClause ($ subQuery );
691+
692+ return $ this ;
693+ }
694+
669695 /**
670696 * Add a clause to the query.
671697 *
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace WikibaseSolutions \CypherDSL \Tests \Unit \Clauses ;
4+
5+ use PHPUnit \Framework \TestCase ;
6+ use WikibaseSolutions \CypherDSL \Clauses \CallClause ;
7+ use WikibaseSolutions \CypherDSL \Query ;
8+
9+ class CallClauseTest extends TestCase
10+ {
11+ public function testCallClauseEmpty (): void
12+ {
13+ $ query = Query::new ();
14+
15+ $ clause = new CallClause ($ query );
16+
17+ $ this ->assertEquals ('' , $ clause ->toQuery ());
18+ $ this ->assertEquals (Query::new (), $ clause ->getSubQuery ());
19+ }
20+
21+ public function testCallClauseFilled (): void
22+ {
23+ $ query = Query::new ()->match (Query::node ('X ' )->named ('x ' ))->returning (Query::rawExpression ('* ' ));
24+
25+ $ clause = new CallClause ($ query );
26+
27+ $ this ->assertEquals ('CALL { MATCH (x:X) RETURN * } ' , $ clause ->toQuery ());
28+ $ this ->assertEquals ($ query , $ clause ->getSubQuery ());
29+ }
30+ }
Original file line number Diff line number Diff line change @@ -1108,6 +1108,36 @@ public function testAutomaticIdentifierGeneration(): void
11081108 $ this ->assertInstanceOf (Variable::class, $ node ->getName ());
11091109 }
11101110
1111+ public function testCallCallable (): void
1112+ {
1113+ $ node = Query::node ('X ' )->named ('y ' );
1114+ $ query = Query::new ()->match ($ node )
1115+ ->call (function (Query $ subQuery ) use ($ node ) {
1116+ $ subQuery ->with ($ node ->getVariable ())
1117+ ->where ($ node ->property ('z ' )->equals (Query::literal ('foo ' ), false ))
1118+ ->returning ($ node ->property ('z ' )->alias ('foo ' ));
1119+ })
1120+ ->returning (Query::variable ('foo ' ));
1121+
1122+ $ this ->assertEquals ("MATCH (y:X) CALL { WITH y WHERE y.z = 'foo' RETURN y.z AS foo } RETURN foo " , $ query ->toQuery ());
1123+ }
1124+
1125+ public function testCallClause (): void {
1126+
1127+ $ node = Query::node ('X ' )->named ('y ' );
1128+
1129+ $ sub = Query::new ()->with ($ node ->getVariable ())
1130+ ->where ($ node ->property ('z ' )->equals (Query::literal ('foo ' ), false ))
1131+ ->returning ($ node ->property ('z ' )->alias ('foo ' ));
1132+
1133+ $ query = Query::new ()
1134+ ->match ($ node )
1135+ ->call ($ sub )
1136+ ->returning (Query::variable ('foo ' ));
1137+
1138+ $ this ->assertEquals ("MATCH (y:X) CALL { WITH y WHERE y.z = 'foo' RETURN y.z AS foo } RETURN foo " , $ query ->toQuery ());
1139+ }
1140+
11111141 public function provideLiteralData (): array
11121142 {
11131143 return [
You can’t perform that action at this time.
0 commit comments