Skip to content

Commit 5a62778

Browse files
committed
Merge branch 'main' of github.com:neo4j-php/neo4j-php-client into kitlabs-cn-main
2 parents 3049148 + f8748af commit 5a62778

File tree

3 files changed

+57
-27
lines changed

3 files changed

+57
-27
lines changed

src/Types/AbstractCypherSequence.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -446,15 +446,16 @@ public function current(): mixed
446446

447447
public function valid(): bool
448448
{
449-
return $this->currentPosition < $this->generatorPosition || $this->getGenerator()->valid();
449+
return $this->currentPosition < $this->generatorPosition || array_key_exists($this->currentPosition, $this->keyCache) || $this->getGenerator()->valid();
450450
}
451451

452452
public function rewind(): void
453453
{
454-
$this->currentPosition = max(
455-
$this->currentPosition - $this->cacheLimit - 1,
456-
0
457-
);
454+
if ($this->currentPosition > $this->cacheLimit) {
455+
throw new BadMethodCallException('Cannot rewind cursor: limit exceeded. In order to increase the amount of prefetched (and consequently cached) rows, increase the fetch limit in the session configuration.');
456+
}
457+
458+
$this->currentPosition = 0;
458459
}
459460

460461
public function next(): void
@@ -489,7 +490,7 @@ public function key(): mixed
489490
*/
490491
protected function cacheKey()
491492
{
492-
return $this->keyCache[$this->currentPosition % max($this->cacheLimit - 1, 1)];
493+
return $this->keyCache[$this->currentPosition % max($this->cacheLimit, 1)];
493494
}
494495

495496
/**
@@ -519,9 +520,9 @@ private function setupCache(): void
519520
{
520521
$generator = $this->getGenerator();
521522

522-
if (count($this->cache) % $this->cacheLimit === 0) {
523-
$this->cache = [];
524-
$this->keyCache = [];
523+
if (count($this->cache) !== 0 && count($this->cache) % ($this->cacheLimit + 1) === 0) {
524+
$this->cache = [array_key_last($this->cache) => $this->cache[array_key_last($this->cache)]];
525+
$this->keyCache = [$this->keyCache[array_key_last($this->keyCache)]];
525526
}
526527

527528
if ($this->cache === [] && $generator->valid()) {

src/Types/ArrayList.php

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
namespace Laudis\Neo4j\Types;
1515

1616
use AppendIterator;
17-
18-
use function array_values;
19-
2017
use ArrayIterator;
2118
use Generator;
2219

@@ -45,22 +42,18 @@ class ArrayList extends AbstractCypherSequence
4542
public function __construct($iterable = [])
4643
{
4744
if (is_array($iterable)) {
48-
/** @var array<array-key, TValue> $iterable */
49-
$this->keyCache = count($iterable) === 0 ? [] : range(0, count($iterable) - 1);
50-
$this->cache = array_values($iterable);
51-
$this->generator = new ArrayIterator([]);
52-
$this->generatorPosition = count($this->keyCache);
53-
} else {
54-
$this->generator = static function () use ($iterable): Generator {
55-
$i = 0;
56-
/** @var Generator<mixed, TValue> $it */
57-
$it = is_callable($iterable) ? $iterable() : $iterable;
58-
foreach ($it as $value) {
59-
yield $i => $value;
60-
++$i;
61-
}
62-
};
45+
$iterable = new ArrayIterator($iterable);
6346
}
47+
48+
$this->generator = static function () use ($iterable): Generator {
49+
$i = 0;
50+
/** @var Generator<mixed, TValue> $it */
51+
$it = is_callable($iterable) ? $iterable() : $iterable;
52+
foreach ($it as $value) {
53+
yield $i => $value;
54+
++$i;
55+
}
56+
};
6457
}
6558

6659
/**

tests/Unit/CypherListTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,42 @@ public function testSlice(): void
459459
self::assertEquals(array_sum(range(5, 7)), $sumAfter);
460460
}
461461

462+
public function testRewindValid(): void
463+
{
464+
$list = $this->list->withCacheLimit(4);
465+
466+
$x = iterator_to_array($list);
467+
$y = iterator_to_array($list);
468+
469+
$this->assertEquals(['A', 'B', 'C'], $x);
470+
$this->assertEquals(['A', 'B', 'C'], $y);
471+
}
472+
473+
public function testRewindValidExact(): void
474+
{
475+
$list = $this->list->withCacheLimit(3);
476+
477+
$x = iterator_to_array($list);
478+
$y = iterator_to_array($list);
479+
480+
$this->assertEquals(['A', 'B', 'C'], $x);
481+
$this->assertEquals(['A', 'B', 'C'], $y);
482+
}
483+
484+
public function testRewindInValid(): void
485+
{
486+
$list = $this->list->withCacheLimit(2);
487+
488+
$x = iterator_to_array($list);
489+
490+
$this->assertEquals(['A', 'B', 'C'], $x);
491+
492+
$this->expectException(BadMethodCallException::class);
493+
$this->expectExceptionMessage('Cannot rewind cursor: limit exceeded. In order to increase the amount of prefetched (and consequently cached) rows, increase the fetch limit in the session configuration.');
494+
495+
iterator_to_array($list);
496+
}
497+
462498
/**
463499
* @return Generator<int, int>
464500
*/

0 commit comments

Comments
 (0)