Chyba v cache SQLite při použití tagu

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

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

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

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

nette registruje journal i cache storage automaticky. predej si pres DI Nette\Caching\IStorage

h4kuna
Backer | 740
+
0
-

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

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

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)