Nette\Database a cahovaný related dotaz?
- redhead
- Člen | 1313
Možná objevuju Ameriku, ale dělal jsem teď nějaké testy do aplikace a
narazil jsem na nějaké podivné cachování výsledku dotazu přes
related()
a nevím přesně jestli je to bug nebo to jen blbě
používám:
$row = ...
$row->related('table')->where(...)->count(); // == 0
// vložím nový řádek
...->table('table')->insert(array(...)); // zvýší počet == 1
$row->related('table')->where(...)->count(); // stále == 0
Když jsem si lognul dotazy přes onQuery[]
, tak se to druhé
volání related()
nevykoná, tzn. že vrací nějaké nacachované
výsledky (i když obsah tabulky už je jiný).
Když ale udělám novou selection do proměnné $row a pak aplikuju stejný kód s related, tak vrací správně 1 výsledek:
$row = ...
$row->related('table')->where(...)->count(); // == 0
// vložím nový řádek
->table('table')->insert(array(...)); // zvýší počet == 1
$row = ...;
$row->related('table')->where(...)->count(); // tak tady už je == 1
Není to chyba? Proč se to cachuje, když je to naprosto nový dotaz?
- hrach
- Člen | 1838
Dane chovani je spravne.
Predstav si tento usecase, ktery by v pripade necachovani vedl k
O(n)
, místo O(konstantni)
.
$users = $db->table('users');
foreach ($users as $user) {
foreach ($user->related('book') as $book) {
$book->title;
}
}
Takze to k duvodu cachovani. Otazkou je, zda
- nevytvorit api pro smazani cache
- nezkusit neco ve stylu, ze kdyz se provede insert, delete, promaze se cache
- otazka, jestli to brat globalne, nebo jenom pro dany root uzel. Jak spravne rikas, pokud si fetchnes novy row, tak se data taaji znovu → cache je ulozena v rootu danyho volani, zadna staticka cache.
- redhead
- Člen | 1313
No jasně, šmarja! Tohle mi nedošlo.
Narazil jsem na to při používání YetORM.
Když vezmu příklad z testu,
rád bych při zavolání getBooks()
dostal knihy daného autora
z tabulky. Když ale pak změním autorovy knihy a zavolám ze stejné entity
stejnou metodu, nedostanu aktuální knihy. Chtěl jsem se vyhnout vytváření
nové entity (tím i nové $row
).
V tuto chvíli mě to zas tolik nepálí, neboť jsem to chtěl použít v testech (ověřit počáteční podmínku → změna → ověřit výsledek), takže tam si novou entitu udělám (i když je velká škoda, že to nejde, bylo by to o dost hezčí). V aplikaci ale snad nikde tabulku entitě pod rukama neměním.
Je na zvážení, jestli nedat nějakou možnost jak cache mazat.