Nette\Database a cahovaný related dotaz?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
redhead
Člen | 1313
+
0
-

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
+
0
-

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
+
0
-

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.