-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEntityGraph.php
234 lines (204 loc) · 5.02 KB
/
EntityGraph.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
<?php
namespace Darya\ORM;
use RuntimeException;
use UnexpectedValueException;
/**
* Darya's entity graph.
*
* Maintains relationships between mapped entity types.
*
* TODO: Should this simply be entity definitions (not entity maps) and their relationships?
* TODO: Use a graph implementation with entity definitions nodes and relationship edges?
*
* @author Chris Andrew <[email protected]>
*/
class EntityGraph
{
/**
* Entity names.
*
* @var string[]
*/
protected $entities = [];
/**
* Entity maps.
*
* Keyed by entity name.
*
* @var EntityMap[]
*/
protected $entityMaps = [];
/**
* Entity relationships.
*
* Keyed by entity name.
*
* @var Relationship[][]
*/
protected $relationships = [];
/**
* Create a new entity graph.
*
* @param EntityMap[] $entityMaps Entity maps.
* @param Relationship[] $relationships Entity relationships.
*/
public function __construct(array $entityMaps = [], array $relationships = [])
{
$this->addEntityMaps($entityMaps);
$this->addRelationships($relationships);
}
/**
* Check whether the graph has an entity.
*
* @param string $entityName
* @return bool
*/
public function hasEntity(string $entityName): bool
{
return in_array($entityName, $this->entities);
}
/**
* Check whether the graph has a relationship.
*
* @param string $entityName
* @param string $relationshipName
* @return bool
*/
public function hasRelationship(string $entityName, string $relationshipName): bool
{
return isset($this->relationships[$entityName][$relationshipName]);
}
/**
* Get the map of an entity.
*
* @param string $entityName
* @return EntityMap
*/
public function getEntityMap(string $entityName): EntityMap
{
if (!$this->hasEntity($entityName)) {
throw new RuntimeException("Entity '$entityName' not found");
}
return $this->entityMaps[$entityName];
}
/**
* Get all entity maps in the graph.
*
* @return EntityMap[]
*/
public function getEntityMaps(): array
{
return $this->entityMaps;
}
/**
* Get a relationship of an entity.
*
* @param string $entityName The entity name.
* @param string $relationshipName The relationship name.
* @return Relationship
* @throws RuntimeException
*/
public function getRelationship(string $entityName, string $relationshipName): Relationship
{
if (!$this->hasEntity($entityName)) {
throw new RuntimeException("Entity '$entityName' not found");
}
if (!$this->hasRelationship($entityName, $relationshipName)) {
throw new RuntimeException("Relationship '$relationshipName' not found for entity '$entityName'");
}
return $this->relationships[$entityName][$relationshipName];
}
/**
* Get all the relationships of an entity.
*
* Optionally selects relationships by name.
*
* @param string $entityName The entity name.
* @param array|null $relationshipNames Optional names of the relationships to load.
* @return Relationship[]
* @throws RuntimeException If the entity name is not found
*/
public function getRelationships($entityName, ?array $relationshipNames = null): array
{
if (!$this->hasEntity($entityName)) {
throw new RuntimeException("Entity '$entityName' not found");
}
$relationships = $this->relationships[$entityName];
if ($relationshipNames !== null) {
$relationships = array_intersect_key($relationships, array_flip($relationshipNames));
}
return $relationships ?? [];
}
/**
* Add an entity and its map to the graph.
*
* @param EntityMap $entityMap
*/
public function addEntityMap(EntityMap $entityMap)
{
$entityName = $entityMap->getName();
$this->addEntity($entityName);
$this->entityMaps[$entityName] = $entityMap;
}
/**
* Add many entities and their maps to the graph.
*
* @param EntityMap[] $entityMaps
*/
public function addEntityMaps(array $entityMaps)
{
foreach ($entityMaps as $map) {
$this->addEntityMap($map);
}
}
/**
* Add a relationship to the graph.
*
* @param Relationship $relationship
*/
public function addRelationship(Relationship $relationship)
{
$entityName = $relationship->getParentMap()->getName();
$this->addEntity($entityName);
$this->relationships[$entityName][$relationship->getName()] = $relationship;
}
/**
* Add many relationships to the graph.
*
* @param Relationship[] $relationships
*/
public function addRelationships(array $relationships)
{
foreach ($relationships as $relationship) {
$this->addRelationship($relationship);
}
}
/**
* Add an entity to the graph.
*
* @param string $name Entity name.
*/
protected function addEntity(string $name)
{
if (!in_array($name, $this->entities)) {
$this->entities[] = $name;
}
if (!isset($this->entityMaps[$name])) {
$this->entityMaps[$name] = null;
}
if (!isset($this->relationships[$name])) {
$this->relationships[$name] = [];
}
}
/**
* Add many entities to the graph.
*
* @param string[] $entities
*/
protected function addEntities(array $entities)
{
foreach ($entities as $name) {
$this->addEntity($name);
}
}
}