Chyba v cache SQLite při použití tagu
- cronos
- Člen | 6
Ahoj,
na webu si ukládám do cache SQLite seo adresy. Mám pro to následující kód
Model
public function getUriCache() {
$journal = new SQLiteJournal($this->tempDir);
$storage = new Nette\Caching\Storages\FileStorage($this->tempDir, $journal);
return new Cache($storage, 'pagesUri');
}
public function cacheUri() {
$data = $this->getUriCache()->load('pagesUri');
if ($data === NULL) {
$articles = $this->findAll()->fetchPairs('id', 'seo_url');
$this->getUriCache()->save('pagesUri', $articles, array(
Cache::EXPIRE => '+ 20 minutes',
Cache::TAGS => ['pagesUri'],
));
}
}
public function invalidateUriCache() {
$this->getUriCache()->clean(array(
Cache::TAGS => array('pagesUri'),
));
}
Cachování funguje, ale až od chvíle, kdy zakomentuji
public function cacheUri() {
$data = $this->getUriCache()->load('pagesUri');
if ($data === NULL) {
$articles = $this->findAll()->fetchPairs('id', 'seo_url');
$this->getUriCache()->save('pagesUri', $articles, array(
Cache::EXPIRE => '+ 20 minutes',
//Cache::TAGS => ['pagesUri'],
));
}
}
Pokud tam definovaný tag mám, vrací mi to chybu
SQLSTATE[HY000] [14] unable to open database file
Neví někdo, čím by to mohlo být?
Editoval cronos (9. 3. 2017 10:53)
- h4kuna
- Backer | 740
Není náhodou problém v tom že to máš více instancí SQLiteJournal a FileStorage? Protože getUriCache() ti vlastně pokaždé tvoří nový objekty SQLiteJournal, FileStorage i Cache. Nepoužil jsi vzor Dependency Injection. Tzn jen to přepiš do neonu a injektini si Storage přes konstuktor.
Editoval h4kuna (9. 3. 2017 14:54)
- cronos
- Člen | 6
Zklusil jsem to, ale když registruji do config.neon službu
SQLiteJournal: \Nette\Caching\Storages\SQLiteJournal("%tempDir%")
Dostanu chybu
Service ‚cache.storage‘: Multiple services of type Nette\Caching\Storages\IJournal found: cache.journal, SQLiteJournal. If you want to overwrite service cache.journal, give it proper name.
Editoval cronos (9. 3. 2017 15:21)
- David Matějka
- Moderator | 6445
nette registruje journal i cache storage automaticky. predej si pres DI Nette\Caching\IStorage
- h4kuna
- Backer | 740
Musíš mu nastavit v autowired: no a pak si to předat ručně
myStorage: Storage(@SQLiteJournal)
- Trida(@myStorage)
EDIT
Jaj jsem to spletl, jak to máš v první příspěvku, musíš vyrobit journal, tomu nastavit autowired: no, potom vyrobit storage, který předáš journal a onu storage si předáš do své třídy.
Editoval h4kuna (10. 3. 2017 7:52)
- cronos
- Člen | 6
Už jsem to rozchodil, díky za rady.
Nakonec stačilo jen toto, config.neon se obešel bez úprav.
public $tempDir;
public $cache;
public $fileStorage;
public function __construct(
$tempDir = NULL,
\Nette\Database\Context $database,
Cache $cache,
Nette\Caching\IStorage $fileStorage) {
parent::__construct($database);
$this->tempDir = $tempDir;
$this->cache = $cache;
$this->fileStorage = $fileStorage;
}
public function getUriCache() {
return new Cache($this->fileStorage, 'pagesUri');
}
- h4kuna
- Backer | 740
Je to takové neučesané. Tady je pár typů:
- parametry s vychozí hodnotou se nadávají první, když se objeví nepovinný parametr v konstruktoru, tak zauvažuj zda by nebyl lepší setter
- tempDir zauvažuj zda potřebuješ, protože jsi to měl jen pro Storage
- cache asi nepotřebuješ předávat přes konstruktor
- cache není potřeba pokaždé vyrábět novou instanci
- nemusíš si držet Storage jako vlastnost objektu
- vlastnosti objektu nastavuj private a až ti to nebude vyhovovat tak to změníš
Výsledek:
class Foo
{
/** @var Nette\Caching\IStorage */
private $cache;
public function __construct(Nette\Database\Context $context, Nette\Caching\IStorage $fileStorage)
{
parent::__construct($context);
$this->cache = new Cache($fileStorage, 'pagesUri');
}
}
Editoval h4kuna (10. 3. 2017 8:00)