Skip to content

Commit 81c10f9

Browse files
committed
setup summarized result formatter for a smooth transition
1 parent 3cdf16e commit 81c10f9

File tree

9 files changed

+127
-139
lines changed

9 files changed

+127
-139
lines changed

src/Databags/SummarizedResult.php

Lines changed: 16 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,40 @@
1313

1414
namespace Laudis\Neo4j\Databags;
1515

16-
use ArrayAccess;
17-
use BadMethodCallException;
18-
use Generator;
19-
use function is_iterable;
20-
use IteratorAggregate;
21-
use JsonSerializable;
22-
use function sprintf;
16+
use Laudis\Neo4j\Types\CypherList;
2317

2418
/**
2519
* A result containing the values and the summary.
2620
*
27-
* @template T
21+
* @template TValue
2822
*
29-
* @psalm-immutable
23+
* @extends CypherList<TValue>
3024
*
31-
* @implements ArrayAccess<string, ResultSummary|T>
25+
* @psalm-immutable
3226
*/
33-
final class SummarizedResult implements JsonSerializable, ArrayAccess, IteratorAggregate
27+
final class SummarizedResult extends CypherList
3428
{
3529
private ResultSummary $summary;
36-
/** @var T */
37-
private $result;
3830

3931
/**
40-
* @param T $result
32+
* @param iterable<mixed, TValue> $iterable
4133
*/
42-
public function __construct($result, ResultSummary $summary)
34+
public function __construct(ResultSummary $summary, iterable $iterable = [])
4335
{
36+
parent::__construct($iterable);
4437
$this->summary = $summary;
45-
$this->result = $result;
4638
}
4739

4840
/**
49-
* Returns the actual result.
41+
* @template Value
42+
*
43+
* @param iterable<mixed, Value> $iterable
5044
*
51-
* @return T
45+
* @return static<Value>
5246
*/
53-
public function getResult()
47+
protected function withIterable(iterable $iterable): SummarizedResult
5448
{
55-
return $this->result;
49+
return new self($this->summary, $iterable);
5650
}
5751

5852
/**
@@ -63,44 +57,14 @@ public function getSummary(): ResultSummary
6357
return $this->summary;
6458
}
6559

66-
public function getIterator(): Generator
67-
{
68-
if (is_iterable($this->result)) {
69-
yield from $this->result;
70-
} else {
71-
yield 'summary' => $this->summary;
72-
yield 'result' => $this->result;
73-
}
74-
}
75-
7660
/**
77-
* @return array{summary: ResultSummary, result: T}
61+
* @return array{summary: ResultSummary, result: mixed}
7862
*/
7963
public function jsonSerialize(): array
8064
{
8165
return [
8266
'summary' => $this->summary,
83-
'result' => $this->result,
67+
'result' => parent::jsonSerialize(),
8468
];
8569
}
86-
87-
public function offsetExists($offset)
88-
{
89-
return array_key_exists($offset, $this->jsonSerialize());
90-
}
91-
92-
public function offsetGet($offset)
93-
{
94-
return $this->jsonSerialize()[$offset];
95-
}
96-
97-
public function offsetSet($offset, $value)
98-
{
99-
throw new BadMethodCallException(sprintf('%s is immutable', __CLASS__));
100-
}
101-
102-
public function offsetUnset($offset)
103-
{
104-
throw new BadMethodCallException(sprintf('%s is immutable', __CLASS__));
105-
}
10670
}

src/Formatter/OGMFormatter.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
* @see https://neo4j.com/docs/driver-manual/current/cypher-workflow/#driver-type-mapping
3636
*
3737
* @psalm-type OGMTypes = string|int|float|bool|null|\Laudis\Neo4j\Types\Date|\Laudis\Neo4j\Types\DateTime|\Laudis\Neo4j\Types\Duration|\Laudis\Neo4j\Types\LocalDateTime|\Laudis\Neo4j\Types\LocalTime|\Laudis\Neo4j\Types\Time|\Laudis\Neo4j\Types\CypherList|\Laudis\Neo4j\Types\CypherMap|\Laudis\Neo4j\Types\Node|\Laudis\Neo4j\Types\Relationship|\Laudis\Neo4j\Types\Path|\Laudis\Neo4j\Types\Cartesian3DPoint|\Laudis\Neo4j\Types\CartesianPoint|\Laudis\Neo4j\Types\WGS84Point|\Laudis\Neo4j\Types\WGS843DPoint
38-
* @implements FormatterInterface<CypherList<CypherMap<OGMTypes>>>
3938
*
4039
* @psalm-type OGMResults = CypherList<CypherMap<OGMTypes>>
4140
*
@@ -48,6 +47,8 @@
4847
*
4948
* @psalm-import-type BoltMeta from \Laudis\Neo4j\Contracts\FormatterInterface
5049
*
50+
* @implements FormatterInterface<CypherList<CypherMap<OGMTypes>>>
51+
*
5152
* @psalm-immutable
5253
*/
5354
final class OGMFormatter implements FormatterInterface
@@ -97,9 +98,6 @@ public function formatBoltResult(array $meta, array $results, ConnectionInterfac
9798
return new CypherList($tbr);
9899
}
99100

100-
/**
101-
* @throws Exception
102-
*/
103101
public function formatHttpResult(ResponseInterface $response, array $body, ConnectionInterface $connection, float $resultsAvailableAfter, float $resultsConsumedAfter, iterable $statements): CypherList
104102
{
105103
/** @var list<CypherList<CypherMap<OGMTypes>>> $tbr */

src/Formatter/SummarizedResultFormatter.php

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,72 +24,48 @@
2424
use Laudis\Neo4j\Databags\SummaryCounters;
2525
use Laudis\Neo4j\Enum\QueryTypeEnum;
2626
use Laudis\Neo4j\Types\CypherList;
27+
use Laudis\Neo4j\Types\CypherMap;
2728
use Psr\Http\Message\RequestInterface;
2829
use Psr\Http\Message\ResponseInterface;
2930
use UnexpectedValueException;
3031

3132
/**
3233
* Decorates the result of the provided format with an extensive summary.
3334
*
34-
* @template T
35-
*
3635
* @psalm-import-type CypherResponseSet from \Laudis\Neo4j\Contracts\FormatterInterface
3736
* @psalm-import-type CypherResponse from \Laudis\Neo4j\Contracts\FormatterInterface
3837
* @psalm-import-type BoltCypherStats from \Laudis\Neo4j\Contracts\FormatterInterface
3938
* @psalm-import-type OGMResults from \Laudis\Neo4j\Formatter\OGMFormatter
39+
* @psalm-import-type OGMTypes from \Laudis\Neo4j\Formatter\OGMFormatter
4040
*
41-
* @implements FormatterInterface<SummarizedResult<T>>
41+
* @implements FormatterInterface<SummarizedResult<CypherMap<OGMTypes>>>
4242
*
4343
* @psalm-immutable
4444
*/
4545
final class SummarizedResultFormatter implements FormatterInterface
4646
{
47-
/** @var FormatterInterface<T> */
48-
private FormatterInterface $formatter;
47+
private OGMFormatter $formatter;
4948

5049
/**
51-
* Creates a new instance of itself by decorating an OGMFormatter.
52-
*
53-
* @return self<OGMResults>
54-
*
5550
* @pure
5651
*/
5752
public static function create(): self
5853
{
59-
return self::createWithFormatter(OGMFormatter::create());
54+
return new self(OGMFormatter::create());
6055
}
6156

62-
/**
63-
* @template U
64-
*
65-
* Creates a new summarized result formatter by decorating the given formatter.
66-
*
67-
* @param FormatterInterface<U> $formatter
68-
*
69-
* @return self<U>
70-
*
71-
* @pure
72-
*/
73-
public static function createWithFormatter(FormatterInterface $formatter): self
74-
{
75-
return new self($formatter);
76-
}
77-
78-
/**
79-
* @param FormatterInterface<T> $formatter
80-
*/
81-
public function __construct(FormatterInterface $formatter)
57+
public function __construct(OGMFormatter $formatter)
8258
{
8359
$this->formatter = $formatter;
8460
}
8561

8662
/**
87-
* @param CypherResponse $response
88-
* @param T $results
63+
* @param CypherResponse $response
64+
* @param CypherList<CypherMap<OGMTypes>> $results
8965
*
90-
* @return SummarizedResult<T>
66+
* @return SummarizedResult<CypherMap<OGMTypes>>
9167
*/
92-
public function formatHttpStats(array $response, ConnectionInterface $connection, Statement $statement, float $resultAvailableAfter, float $resultConsumedAfter, $results): SummarizedResult
68+
public function formatHttpStats(array $response, ConnectionInterface $connection, Statement $statement, float $resultAvailableAfter, float $resultConsumedAfter, CypherList $results): SummarizedResult
9369
{
9470
if (!isset($response['stats'])) {
9571
throw new UnexpectedValueException('No stats found in the response set');
@@ -129,7 +105,7 @@ public function formatHttpStats(array $response, ConnectionInterface $connection
129105
)
130106
);
131107

132-
return new SummarizedResult($results, $summary);
108+
return new SummarizedResult($summary, $results->toArray());
133109
}
134110

135111
/**
@@ -196,12 +172,12 @@ public function formatBoltResult(array $meta, array $results, ConnectionInterfac
196172
);
197173
$formattedResult = $this->formatter->formatBoltResult($meta, $results, $connection, $resultAvailableAfter, $resultConsumedAfter, $statement);
198174

199-
return new SummarizedResult($formattedResult, $summary);
175+
return new SummarizedResult($summary, $formattedResult->toArray());
200176
}
201177

202178
public function formatHttpResult(ResponseInterface $response, array $body, ConnectionInterface $connection, float $resultsAvailableAfter, float $resultsConsumedAfter, iterable $statements): CypherList
203179
{
204-
/** @var list<SummarizedResult<T>> */
180+
/** @var list<SummarizedResult<CypherMap<OGMTypes>>> */
205181
$tbr = [];
206182

207183
$toDecorate = $this->formatter->formatHttpResult($response, $body, $connection, $resultsAvailableAfter, $resultsConsumedAfter, $statements);

src/Types/AbstractCypherSequence.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,20 @@
2929
* @extends AbstractCypherObject<TKey, TValue>
3030
*
3131
* @psalm-immutable
32-
*
33-
* @psalm-suppress UnsafeInstantiation
3432
*/
3533
abstract class AbstractCypherSequence extends AbstractCypherObject implements Countable
3634
{
3735
/** @var array<TKey, TValue> */
3836
protected array $sequence = [];
3937

4038
/**
41-
* @param iterable<TKey, TValue> $iterable
39+
* @template Value
40+
*
41+
* @param iterable<Value> $iterable
42+
*
43+
* @return static<Value, array-key>
4244
*/
43-
abstract public function __construct(iterable $iterable);
45+
abstract protected function withIterable(iterable $iterable): AbstractCypherSequence;
4446

4547
final public function count(): int
4648
{
@@ -57,7 +59,7 @@ final public function copy(): self
5759
// Make sure the sequence is actually copied by reassigning it.
5860
$map = $this->sequence;
5961

60-
return new static($map);
62+
return $this->withIterable($map);
6163
}
6264

6365
/**
@@ -124,7 +126,7 @@ final public function filter(callable $callback): self
124126
}
125127
}
126128

127-
return new static($tbr);
129+
return $this->withIterable($tbr);
128130
}
129131

130132
/**
@@ -144,7 +146,7 @@ final public function map(callable $callback): self
144146
$tbr[$key] = $callback($value, $key);
145147
}
146148

147-
return new static($tbr);
149+
return $this->withIterable($tbr);
148150
}
149151

150152
/**

src/Types/ArrayList.php

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,13 @@
3232
* @extends AbstractCypherSequence<TValue, int>
3333
*
3434
* @psalm-immutable
35-
*
36-
* @psalm-suppress UnsafeGenericInstantiation
3735
*/
3836
class ArrayList extends AbstractCypherSequence
3937
{
4038
/**
4139
* @param iterable<mixed, TValue> $iterable
4240
*/
43-
final public function __construct(iterable $iterable = [])
41+
public function __construct(iterable $iterable = [])
4442
{
4543
if ($iterable instanceof self) {
4644
/** @psalm-suppress InvalidPropertyAssignmentValue */
@@ -53,6 +51,19 @@ final public function __construct(iterable $iterable = [])
5351
}
5452
}
5553

54+
/**
55+
* @template Value
56+
*
57+
* @param iterable<mixed, Value> $iterable
58+
*
59+
* @return static<Value>
60+
*/
61+
protected function withIterable(iterable $iterable): ArrayList
62+
{
63+
/** @psalm-suppress UnsafeInstantiation */
64+
return new static($iterable);
65+
}
66+
5667
/**
5768
* Returns the first element in the sequence.
5869
*
@@ -94,23 +105,23 @@ public function merge($values): ArrayList
94105
$tbr[] = $value;
95106
}
96107

97-
return new static($tbr);
108+
return $this->withIterable($tbr);
98109
}
99110

100111
/**
101112
* @return static<TValue>
102113
*/
103114
public function reversed(): ArrayList
104115
{
105-
return new static(array_reverse($this->sequence));
116+
return $this->withIterable(array_reverse($this->sequence));
106117
}
107118

108119
/**
109120
* @return static<TValue>
110121
*/
111122
public function slice(int $offset, int $length = null): ArrayList
112123
{
113-
return new static(array_slice($this->sequence, $offset, $length));
124+
return $this->withIterable(array_slice($this->sequence, $offset, $length));
114125
}
115126

116127
/**
@@ -128,7 +139,7 @@ public function sorted(callable $comparator = null): ArrayList
128139
usort($tbr, $comparator);
129140
}
130141

131-
return new static($tbr);
142+
return $this->withIterable($tbr);
132143
}
133144

134145
/**
@@ -251,13 +262,12 @@ public function getAsArrayList(int $key): ArrayList
251262
*
252263
* @param iterable<Value> $iterable
253264
*
254-
* @return static<Value>
265+
* @return self<Value>
255266
*
256267
* @pure
257268
*/
258269
public static function fromIterable(iterable $iterable): ArrayList
259270
{
260-
/** @psalm-suppress UnsafeGenericInstantiation */
261-
return new static($iterable);
271+
return new self($iterable);
262272
}
263273
}

0 commit comments

Comments
 (0)