Skip to content

Commit 6990c49

Browse files
committed
Selection: fixed columns cache in repeated use of same selection
1 parent d8aab0a commit 6990c49

File tree

2 files changed

+45
-19
lines changed

2 files changed

+45
-19
lines changed

src/Database/Table/Selection.php

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ class Selection implements \Iterator, IRowContainer, \ArrayAccess, \Countable
5959
/** @var string */
6060
protected $generalCacheKey;
6161

62-
/** @var array */
63-
protected $generalCacheTraceKey;
64-
6562
/** @var string */
6663
protected $specificCacheKey;
6764

@@ -618,20 +615,20 @@ protected function query($query)
618615
}
619616

620617

621-
protected function emptyResultSet($saveCache = TRUE, $deleteRererencedCache = TRUE)
618+
protected function emptyResultSet($clearCache = TRUE, $deleteRererencedCache = TRUE)
622619
{
623-
if ($this->rows !== NULL && $saveCache) {
620+
if ($this->rows !== NULL && $clearCache) {
624621
$this->saveCacheState();
625622
}
626623

627-
if ($saveCache) {
628-
// null only if missing some column
629-
$this->generalCacheTraceKey = NULL;
624+
if ($clearCache) {
625+
// not null in case of missing some column
626+
$this->previousAccessedColumns = NULL;
627+
$this->generalCacheKey = NULL;
630628
}
631629

632630
$this->rows = NULL;
633631
$this->specificCacheKey = NULL;
634-
$this->generalCacheKey = NULL;
635632
$this->refCache['referencingPrototype'] = [];
636633
if ($deleteRererencedCache) {
637634
$this->refCache['referenced'] = [];
@@ -687,15 +684,12 @@ protected function getGeneralCacheKey()
687684
}
688685

689686
$key = [__CLASS__, $this->name, $this->sqlBuilder->getConditions()];
690-
if (!$this->generalCacheTraceKey) {
691-
$trace = [];
692-
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $item) {
693-
$trace[] = isset($item['file'], $item['line']) ? $item['file'] . $item['line'] : NULL;
694-
};
695-
$this->generalCacheTraceKey = $trace;
696-
}
687+
$trace = [];
688+
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $item) {
689+
$trace[] = isset($item['file'], $item['line']) ? $item['file'] . $item['line'] : NULL;
690+
};
697691

698-
$key[] = $this->generalCacheTraceKey;
692+
$key[] = $trace;
699693
return $this->generalCacheKey = md5(serialize($key));
700694
}
701695

@@ -735,8 +729,6 @@ public function accessColumn($key, $selectColumn = TRUE)
735729
}
736730

737731
if ($selectColumn && $this->previousAccessedColumns && ($key === NULL || !isset($this->previousAccessedColumns[$key])) && !$this->sqlBuilder->getSelect()) {
738-
$this->previousAccessedColumns = [];
739-
740732
if ($this->sqlBuilder->getLimit()) {
741733
$generalCacheKey = $this->generalCacheKey;
742734
$sqlBuilder = $this->sqlBuilder;
@@ -753,10 +745,12 @@ public function accessColumn($key, $selectColumn = TRUE)
753745
$this->wherePrimary($primaryValues);
754746

755747
$this->generalCacheKey = $generalCacheKey;
748+
$this->previousAccessedColumns = [];
756749
$this->execute();
757750
$this->sqlBuilder = $sqlBuilder;
758751
} else {
759752
$this->emptyResultSet(FALSE);
753+
$this->previousAccessedColumns = [];
760754
$this->execute();
761755
}
762756

tests/Database/Table/Table.cache.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,35 @@ test(function () use ($context) { // Test saving the union of needed cols, the s
185185
['id', 'author_id', 'translator_id', 'title'],
186186
], $cols);
187187
});
188+
189+
190+
test(function () use ($context) { // Test multiple use of same selection
191+
$sql = [];
192+
$context->getConnection()->onQuery[] = function($_, $result) use (& $sql) {
193+
$sql[] = $result->getQueryString();
194+
};
195+
196+
for ($i = 0; $i < 3; $i += 1) {
197+
$bookSelection = $context->table('book');
198+
count($bookSelection);
199+
200+
foreach ($bookSelection->where('author_id = ?', 11) as $book) {
201+
$book->title;
202+
if ($i>=1) {
203+
$book->translator_id;
204+
}
205+
}
206+
$bookSelection->__destruct();
207+
}
208+
209+
Assert::same([
210+
reformat('SELECT * FROM [book]'), //First round
211+
reformat('SELECT * FROM [book] WHERE ([author_id] = 11)'),
212+
reformat('SELECT [id] FROM [book]'), //Second round
213+
reformat('SELECT [id], [title] FROM [book] WHERE ([author_id] = 11)'),
214+
reformat('SELECT * FROM [book] WHERE ([author_id] = 11)'), //Missing translator_id
215+
reformat('SELECT [id] FROM [book]'), //Third round
216+
reformat('SELECT [id], [title], [translator_id] FROM [book] WHERE ([author_id] = 11)'),
217+
218+
], $sql);
219+
});

0 commit comments

Comments
 (0)