Skip to content

Commit 0e8960b

Browse files
committed
Selection: iterator skips missing rows after refetch
1 parent 6990c49 commit 0e8960b

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

src/Database/Table/ActiveRow.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ public function accessColumn($key, $selectColumn = TRUE)
323323
{
324324
if ($this->table->accessColumn($key, $selectColumn) && !$this->dataRefreshed) {
325325
if (!isset($this->table[$this->getSignature()])) {
326-
throw new Nette\InvalidStateException('Database refetch failed; row does not exist!');
326+
throw new Nette\InvalidStateException("Database refetch failed; row with signature '{$this->getSignature()}' does not exist!");
327327
}
328328
$this->data = $this->table[$this->getSignature()]->data;
329329
$this->dataRefreshed = TRUE;

src/Database/Table/Selection.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,9 @@ public function key()
10121012

10131013
public function next()
10141014
{
1015-
next($this->keys);
1015+
do {
1016+
next($this->keys);
1017+
} while (($key = current($this->keys)) !== FALSE && !isset($this->data[$key]));
10161018
}
10171019

10181020

tests/Database/Table/bugs/deleteCacheBug.phpt

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ test(function () use ($context) {
2121
$book->delete();
2222
Assert::exception(function () use ($book) {
2323
$book->toArray();
24-
}, Nette\InvalidStateException::class, 'Database refetch failed; row does not exist!');
24+
}, Nette\InvalidStateException::class, "Database refetch failed; row with signature '1' does not exist!");
2525
}
2626

2727
$booksSelection->__destruct();
@@ -42,13 +42,35 @@ test(function () use ($context) {
4242

4343
Assert::exception(function () use ($book) {
4444
$book->toArray();
45-
}, Nette\InvalidStateException::class, 'Database refetch failed; row does not exist!');
45+
}, Nette\InvalidStateException::class, "Database refetch failed; row with signature '2' does not exist!");
4646
}
4747

4848
$booksSelection->__destruct();
4949
}
5050
});
5151

52+
test(function () use ($context) {
53+
$books = [];
54+
for ($i=0; $i<2; $i++) {
55+
$booksSelection = $context->table('book')->where('id IN ?', [3,4]);
56+
foreach ($booksSelection as $book) {
57+
$books[] = $book->id;
58+
59+
if ($i === 1) {
60+
$context->query('DELETE FROM book WHERE id = 4'); //After refetch second row is skipped
61+
$book->title; // cause refetch
62+
}
63+
64+
$booksSelection->__destruct();
65+
}
66+
}
67+
Assert::same([
68+
3,
69+
4,
70+
3,
71+
], $books);
72+
});
73+
5274
test(function () use ($context) {
5375

5476
for ($i=0; $i<2; $i++) {
@@ -60,7 +82,7 @@ test(function () use ($context) {
6082
$context->query('DELETE FROM book WHERE id = 3');
6183
Assert::exception(function () use ($book) {
6284
$book->title;
63-
}, Nette\InvalidStateException::class, 'Database refetch failed; row does not exist!');
85+
}, Nette\InvalidStateException::class, "Database refetch failed; row with signature '3' does not exist!");
6486
}
6587

6688
$booksSelection->__destruct();

0 commit comments

Comments
 (0)