2
2
3
3
namespace WikibaseSolutions \CypherDSL \Patterns ;
4
4
5
+ use WikibaseSolutions \CypherDSL \PropertyMap ;
6
+ use WikibaseSolutions \CypherDSL \Traits \ErrorTrait ;
5
7
use WikibaseSolutions \CypherDSL \Traits \PathTrait ;
8
+ use WikibaseSolutions \CypherDSL \Types \StructuralTypes \NodeType ;
6
9
use WikibaseSolutions \CypherDSL \Types \StructuralTypes \PathType ;
7
- use WikibaseSolutions \CypherDSL \Types \StructuralTypes \StructuralType ;
10
+ use WikibaseSolutions \CypherDSL \Types \StructuralTypes \RelationshipType ;
11
+ use WikibaseSolutions \CypherDSL \Variable ;
12
+ use function is_array ;
8
13
9
14
class Path implements PathType
10
15
{
11
16
use PathTrait;
17
+ use ErrorTrait;
12
18
13
19
/** @var Relationship[] */
14
- private array $ relationships = [];
15
-
16
- public function __construct ()
20
+ private array $ relationships ;
21
+ /** @var Node[] */
22
+ private array $ nodes ;
23
+
24
+ /**
25
+ * @param Node|Node[] $nodes
26
+ * @param Relationship|Relationship[] $relationships
27
+ */
28
+ public function __construct ($ nodes , $ relationships = null )
17
29
{
30
+ self ::assertClassOrType ('relationships ' , [Relationship::class, 'array ' ], $ relationships );
31
+ self ::assertClassOrType ('nodes ' , [Node::class, 'array ' ], $ nodes );
32
+
33
+ $ this ->nodes = is_array ($ nodes ) ? array_values ($ nodes ) : [$ nodes ];
34
+ $ this ->relationships = is_array ($ relationships ) ? array_values ($ relationships ) : [$ relationships ];
18
35
}
19
36
20
37
public function toQuery (): string
21
38
{
39
+ if (count ($ this ->nodes ) === 0 ) {
40
+ return '' ;
41
+ }
42
+
22
43
$ cql = '' ;
23
44
if ($ this ->getVariable () !== null ) {
24
45
$ cql = $ this ->getName ()->toQuery () . ' = ' ;
25
46
}
26
47
27
- foreach ($ this ->relationships as $ relationship ) {
28
- $ cql .= $ relationship ->getLeft ()->toQuery ();
29
- $ cql .= $ relationship ->toRelationshipQuery ();
48
+ foreach ($ this ->relationships as $ i => $ relationship ) {
49
+ if (count ($ this ->nodes ) <= $ i ) {
50
+ break ;
51
+ }
52
+ $ cql .= $ this ->nodes [$ i ]->toQuery ();
53
+ $ cql .= $ relationship ->toQuery ();
30
54
}
31
55
32
- if (isset ($ relationship )) {
33
- $ cql .= $ relationship ->getRight ()->toQuery ();
34
- }
56
+ $ cql .= $ this ->nodes [$ i ?? 0 ]->toQuery ();
35
57
36
58
return $ cql ;
37
59
}
38
60
39
- public function relationshipTo (StructuralType $ pattern ): Path
61
+ /**
62
+ * Returns the nodes in the path in sequential order.
63
+ *
64
+ * @return Node[]
65
+ */
66
+ public function getNodes (): array
40
67
{
41
- $ this ->relationships [] = $ this ->getLatestNode ()->relationshipUni ($ pattern );
68
+ return $ this ->nodes ;
69
+ }
42
70
43
- return $ this ;
71
+ /**
72
+ * Returns the relationships in the path in sequential order.
73
+ *
74
+ * @return Relationship[]
75
+ */
76
+ public function getRelationships (): array
77
+ {
78
+ return $ this ->relationships ;
44
79
}
45
80
46
- public function relationshipFrom ( StructuralType $ pattern ): Path
81
+ public function relationship ( RelationshipType $ relationship , NodeType $ node ): Path
47
82
{
48
- $ this ->relationships [] = $ this ->getLatestNode ()->relationshipUni ($ pattern );
83
+ $ this ->relationships [] = $ relationship ;
84
+ $ this ->nodes [] = $ node ;
49
85
50
86
return $ this ;
51
87
}
52
88
53
- public function relationshipUni ( StructuralType $ pattern ): Path
89
+ public function relationshipTo ( NodeType $ node , $ properties = null , $ name = null ): Path
54
90
{
55
- $ this -> relationships [] = $ this ->getLatestNode ()-> relationshipUni ( $ pattern );
91
+ $ relationship = $ this ->buildRelationship (Relationship:: DIR_RIGHT , $ properties , $ name );
56
92
57
- return $ this ;
93
+ return $ this ->relationship ($ relationship , $ node );
94
+ }
95
+
96
+ public function relationshipFrom (NodeType $ node , $ properties = null , $ name = null ): Path
97
+ {
98
+ $ relationship = $ this ->buildRelationship (Relationship::DIR_LEFT , $ properties , $ name );
99
+
100
+ return $ this ->relationship ($ relationship , $ node );
101
+ }
102
+
103
+ public function relationshipUni (NodeType $ node , $ properties = null , $ name = null ): Path
104
+ {
105
+ $ relationship = $ this ->buildRelationship (Relationship::DIR_UNI , $ properties , $ name );
106
+
107
+ return $ this ->relationship ($ relationship , $ node );
58
108
}
59
109
60
- private function getLatestNode (): StructuralType
110
+ /**
111
+ * @param array $direction
112
+ * @param mixed $properties
113
+ * @param mixed $name
114
+ *
115
+ * @return Relationship
116
+ */
117
+ private function buildRelationship (array $ direction , $ properties , $ name ): Relationship
61
118
{
62
- return $ this ->relationships [count ($ this ->relationships ) - 1 ]->getRight ();
119
+ self ::assertClassOrType ('properties ' , ['array ' , PropertyMap::class, null ], $ properties );
120
+ self ::assertClassOrType ('name ' , ['string ' , Variable::class, null ], $ name );
121
+
122
+ $ relationship = new Relationship ($ direction );
123
+ if ($ properties !== null ) {
124
+ $ relationship ->withProperties ($ properties );
125
+ }
126
+ if ($ name !== null ) {
127
+ $ relationship ->named ($ name );
128
+ }
129
+ return $ relationship ;
63
130
}
64
131
}
0 commit comments