Skip to content

Commit dd031b8

Browse files
committed
fixed psalm typings for OGM
1 parent 2db3d83 commit dd031b8

File tree

3 files changed

+100
-66
lines changed

3 files changed

+100
-66
lines changed

src/Formatter/OGMFormatter.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,10 @@ public function formatHttpResult(ResponseInterface $response, stdClass $body, Co
8787
/** @var list<CypherList<CypherMap<OGMTypes>>> $tbr */
8888
$tbr = [];
8989

90-
foreach ($body->results as $results) {
91-
$tbr[] = $this->httpTranslator->translateResult($results);
90+
/** @var list<stdClass> $results */
91+
$results = $body->results;
92+
foreach ($results as $result) {
93+
$tbr[] = $this->httpTranslator->translateResult($result);
9294
}
9395

9496
return new CypherList($tbr);

src/Formatter/Specialised/HttpOGMTranslator.php

Lines changed: 89 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use Laudis\Neo4j\Types\Path;
3535
use Laudis\Neo4j\Types\Relationship;
3636
use Laudis\Neo4j\Types\Time;
37+
use Laudis\Neo4j\Types\UnboundRelationship;
3738
use Laudis\Neo4j\Types\WGS843DPoint;
3839
use Laudis\Neo4j\Types\WGS84Point;
3940
use RuntimeException;
@@ -45,14 +46,6 @@
4546
/**
4647
* @psalm-immutable
4748
*
48-
* @psalm-type RelationshipArray = array{id: string, type: string, startNode: string, endNode: string, properties: array<string, scalar|null|array<array-key, scalar|null|array>>}
49-
* @psalm-type NodeArray = array{id: string, labels: list<string>, properties: array<string, scalar|null|array}
50-
* @psalm-type Meta = array{id?: int, type: string, deleted?: bool}
51-
* @psalm-type MetaArray = list<Meta|null|list<array{id: int, type: string, deleted: bool}>>
52-
*
53-
* @psalm-type CypherResultDataRow = list<array{row: list<scalar|array|null>, meta: MetaArray, graph: array{nodes: list<NodeArray>, relationships: list<RelationshipArray>}}>
54-
* @psalm-type CypherResult = array{columns: list<string>, data: CypherResultDataRow}
55-
*
5649
* @psalm-import-type OGMResults from \Laudis\Neo4j\Formatter\OGMFormatter
5750
* @psalm-import-type OGMTypes from \Laudis\Neo4j\Formatter\OGMFormatter
5851
*/
@@ -68,17 +61,28 @@ public function translateResult(stdClass $result): CypherList
6861
/** @var list<CypherMap<OGMTypes>> $tbr */
6962
$tbr = [];
7063

64+
/** @var list<string> $columns */
7165
$columns = $result->columns;
72-
foreach ($result->data as $data) {
66+
/** @var list<stdClass> $datas */
67+
$datas = $result->data;
68+
foreach ($datas as $data) {
7369
$meta = HttpMetaInfo::createFromData($data);
7470

75-
$row = array_combine($columns, (array) $data->row);
71+
/** @var list<stdClass> $row */
72+
$row = $data->row;
73+
/** @var array<string, stdClass> $row */
74+
$row = array_combine($columns, $row);
7675
$tbr[] = $this->translateCypherMap($row, $meta)[0];
7776
}
7877

7978
return new CypherList($tbr);
8079
}
8180

81+
/**
82+
* @param array<string, stdClass> $row
83+
*
84+
* @return array{0: CypherMap<OGMTypes>, 1: HttpMetaInfo}
85+
*/
8286
public function translateCypherMap(array $row, HttpMetaInfo $meta): array
8387
{
8488
/** @var array<string, OGMTypes> $record */
@@ -93,9 +97,13 @@ public function translateCypherMap(array $row, HttpMetaInfo $meta): array
9397
}
9498

9599
/**
96-
* @param mixed $value
100+
* @param stdClass|array|scalar|null $value
97101
*
98102
* @return array{0: OGMTypes, 1: HttpMetaInfo}
103+
*
104+
* @psalm-suppress MixedArgumentTypeCoercion
105+
* @psalm-suppress MixedArgument
106+
* @psalm-suppress MixedAssignment
99107
*/
100108
private function translateValue($value, HttpMetaInfo $meta): array
101109
{
@@ -110,7 +118,7 @@ private function translateValue($value, HttpMetaInfo $meta): array
110118
*
111119
* @see OGMFormatterIntegrationTest::testPathMultiple for an example
112120
*/
113-
if (is_array($value[0])) {
121+
if (array_key_exists(0, $value) && is_array($value[0])) {
114122
$tbr = [];
115123
foreach ($value as $path) {
116124
$tbr[] = $this->path($path, $meta->withNestedMeta());
@@ -120,7 +128,7 @@ private function translateValue($value, HttpMetaInfo $meta): array
120128
return [new CypherList($tbr), $meta];
121129
}
122130

123-
$tbr = $this->path((array) $value, $meta->withNestedMeta());
131+
$tbr = $this->path($value, $meta->withNestedMeta());
124132
$meta = $meta->incrementMeta();
125133

126134
return [$tbr, $meta];
@@ -138,12 +146,18 @@ private function translateValue($value, HttpMetaInfo $meta): array
138146

139147
/**
140148
* @return array{0: Cartesian3DPoint|CartesianPoint|CypherList|CypherMap|Node|Relationship|WGS843DPoint|WGS84Point|Path, 1: HttpMetaInfo}
149+
*
150+
* @psalm-suppress MixedArgument
151+
* @psalm-suppress MixedArgumentTypeCoercion
141152
*/
142-
private function translateObject(object $value, HttpMetaInfo $meta): array
153+
private function translateObject(stdClass $value, HttpMetaInfo $meta): array
143154
{
144155
$type = $meta->getCurrentType();
145156
if ($type === 'relationship') {
146-
return $this->relationship($meta->getCurrentRelationship(), $meta);
157+
/** @var stdClass $relationship */
158+
$relationship = $meta->getCurrentRelationship();
159+
160+
return $this->relationship($relationship, $meta);
147161
}
148162

149163
if ($type === 'point') {
@@ -163,24 +177,34 @@ private function translateObject(object $value, HttpMetaInfo $meta): array
163177
return $this->translateCypherMap((array) $value, $meta);
164178
}
165179

166-
private function translateProperties(stdClass $properties): CypherMap
180+
/**
181+
* @param array<string, array|stdClass|scalar|null> $properties
182+
*
183+
* @return CypherMap<OGMTypes>
184+
*/
185+
private function translateProperties(array $properties): CypherMap
167186
{
168187
$tbr = [];
169-
foreach ((array) $properties as $key => $value) {
188+
foreach ($properties as $key => $value) {
170189
if ($value instanceof stdClass) {
171-
$tbr[$key] = new CypherMap((array) $value);
190+
/** @var array<string, array|stdClass|scalar|null> $castedValue */
191+
$castedValue = (array) $value;
192+
$tbr[$key] = $this->translateProperties($castedValue);
172193
} elseif (is_array($value)) {
173-
$tbr[$key] = new CypherList($value);
194+
/** @var array<string, array|stdClass|scalar|null> $value */
195+
$tbr[$key] = new CypherList($this->translateProperties($value)->values());
174196
} else {
175197
$tbr[$key] = $value;
176198
}
177199
}
178-
200+
/** @var CypherMap<OGMTypes> */
179201
return new CypherMap($tbr);
180202
}
181203

182204
/**
183-
* @param RelationshipArray $relationship
205+
* @psalm-suppress MixedArgument
206+
*
207+
* @return array{0: Relationship, 1: HttpMetaInfo}
184208
*/
185209
private function relationship(stdClass $relationship, HttpMetaInfo $meta): array
186210
{
@@ -216,82 +240,84 @@ private function translateCypherList(array $value, HttpMetaInfo $meta): array
216240
}
217241

218242
/**
219-
* @param list<stdClass> $meta
220-
* @param list<NodeArray> $nodes
221-
* @param list<RelationshipArray> $relationship
243+
* @param list<stdClass> $value
222244
*/
223245
private function path(array $value, HttpMetaInfo $meta): Path
224246
{
247+
/** @var list<Node> $nodes */
225248
$nodes = [];
226249
/** @var list<int> $ids */
227250
$ids = [];
251+
/** @var list<UnboundRelationship> $rels */
228252
$rels = [];
229253

230254
foreach ($value as $x) {
231-
$ids[] = $meta->currentMeta()->id;
255+
/** @var stdClass $currentMeta */
256+
$currentMeta = $meta->currentMeta();
257+
/** @var int $id */
258+
$id = $currentMeta->id;
259+
$ids[] = $id;
232260
[$x, $meta] = $this->translateObject($x, $meta);
233261
if ($x instanceof Node) {
234262
$nodes[] = $x;
235-
} else {
236-
$rels[] = $x;
263+
} elseif ($x instanceof Relationship) {
264+
$rels[] = new UnboundRelationship($x->getId(), $x->getType(), $x->getProperties());
237265
}
238266
}
239267

240268
return new Path(new CypherList($nodes), new CypherList($rels), new CypherList($ids));
241269
}
242270

243-
/**
244-
* @param NodeArray $nodes
245-
*/
246-
private function translateNode(array $node): Node
247-
{
248-
return new Node($node['id'], new CypherList($node['labels']), $this->translateProperties($node['properties']));
249-
}
250-
251271
/**
252272
* @return CartesianPoint|Cartesian3DPoint|WGS843DPoint|WGS84Point
253273
*/
254274
private function translatePoint(stdClass $value): PointInterface
255275
{
256-
/** array{type: 'point', coordinates: array{0: float, 1: float, 2?:float}, crs: array{srid: int, type: string, name: 'cartesian'|'cartesian-3d'|'wgs-84'|'wgs-84-3d', properties: array<string, string>}} */
257-
$pointType = $value->crs->name;
258-
if ($pointType === 'cartesian') {
276+
/** @var stdClass $crs */
277+
$crs = $value->crs;
278+
/** @var "cartesian"|"cartesian-3d"|"wgs-84"|"wgs-84-3d" */
279+
$name = $crs->name;
280+
/** @var array{0: float, 1: float, 2:float} $coordinates */
281+
$coordinates = $value->coordinates;
282+
/** @var int $srid */
283+
$srid = $crs->srid;
284+
if ($name === 'cartesian') {
259285
return new CartesianPoint(
260-
$value->coordinates[0],
261-
$value->coordinates[1],
262-
$value->crs->name,
263-
$value->crs->srid
286+
$coordinates[0],
287+
$coordinates[1],
288+
$name,
289+
$srid
264290
);
265291
}
266-
if ($pointType === 'cartesian-3d') {
292+
if ($name === 'cartesian-3d') {
267293
return new Cartesian3DPoint(
268-
$value->coordinates[0],
269-
$value->coordinates[1],
270-
$value->coordinates[2],
271-
$value->crs->name,
272-
$value->crs->srid
294+
$coordinates[0],
295+
$coordinates[1],
296+
$coordinates[2],
297+
$name,
298+
$srid
273299
);
274300
}
275-
if ($pointType === 'wgs-84') {
301+
if ($name === 'wgs-84') {
276302
return new WGS84Point(
277-
$value->coordinates[0],
278-
$value->coordinates[1],
279-
$value->coordinates[0],
280-
$value->coordinates[1],
281-
$value->crs->name,
282-
$value->crs->srid
303+
$coordinates[0],
304+
$coordinates[1],
305+
$coordinates[0],
306+
$coordinates[1],
307+
$name,
308+
$srid
283309
);
284310
}
285311

286312
return new WGS843DPoint(
287-
$value->coordinates[0],
288-
$value->coordinates[1],
289-
$value->coordinates[2],
290-
$value->coordinates[0],
291-
$value->coordinates[1],
292-
$value->coordinates[2],
293-
$value->crs->name,
294-
$value->crs->srid
313+
$coordinates[0],
314+
$coordinates[1],
315+
$coordinates[2],
316+
$coordinates[0],
317+
$coordinates[1],
318+
$coordinates[2],
319+
$name,
320+
$srid
295321
);
296322
}
297323

src/Formatter/SummarizedResultFormatter.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ public function formatHttpStats(stdClass $response, ConnectionInterface $connect
7171
throw new UnexpectedValueException('No stats found in the response set');
7272
}
7373

74+
/**
75+
* @psalm-suppress MixedPropertyFetch
76+
* @psalm-suppress MixedArgument
77+
*/
7478
$counters = new SummaryCounters(
7579
$response->stats->nodes_created ?? 0,
7680
$response->stats->nodes_deleted ?? 0,
@@ -183,7 +187,9 @@ public function formatHttpResult(ResponseInterface $response, stdClass $body, Co
183187
$toDecorate = $this->formatter->formatHttpResult($response, $body, $connection, $resultsAvailableAfter, $resultsConsumedAfter, $statements);
184188
$i = 0;
185189
foreach ($statements as $statement) {
186-
$result = $body->results[$i];
190+
/** @var list<stdClass> $results */
191+
$results = $body->results;
192+
$result = $results[$i];
187193
$tbr[] = $this->formatHttpStats($result, $connection, $statement, $resultsAvailableAfter, $resultsConsumedAfter, $toDecorate->get($i));
188194
++$i;
189195
}

0 commit comments

Comments
 (0)