%PDF- %PDF-
Direktori : /www/varak.net/losik.varak.net/vendor/nette/caching/src/Caching/Storages/ |
Current File : /www/varak.net/losik.varak.net/vendor/nette/caching/src/Caching/Storages/SQLiteJournal.php |
<?php /** * This file is part of the Nette Framework (https://nette.org) * Copyright (c) 2004 David Grudl (https://davidgrudl.com) */ declare(strict_types=1); namespace Nette\Caching\Storages; use Nette; use Nette\Caching\Cache; /** * SQLite based journal. */ class SQLiteJournal implements Journal { use Nette\SmartObject; /** @string */ private $path; /** @var \PDO */ private $pdo; public function __construct(string $path) { if (!extension_loaded('pdo_sqlite')) { throw new Nette\NotSupportedException('SQLiteJournal requires PHP extension pdo_sqlite which is not loaded.'); } $this->path = $path; } private function open(): void { if ($this->path !== ':memory:' && !is_file($this->path)) { touch($this->path); // ensures ordinary file permissions } $this->pdo = new \PDO('sqlite:' . $this->path); $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $this->pdo->exec(' PRAGMA foreign_keys = OFF; PRAGMA journal_mode = WAL; CREATE TABLE IF NOT EXISTS tags ( key BLOB NOT NULL, tag BLOB NOT NULL ); CREATE TABLE IF NOT EXISTS priorities ( key BLOB NOT NULL, priority INT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_tags_tag ON tags(tag); CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_key_tag ON tags(key, tag); CREATE UNIQUE INDEX IF NOT EXISTS idx_priorities_key ON priorities(key); CREATE INDEX IF NOT EXISTS idx_priorities_priority ON priorities(priority); PRAGMA synchronous = NORMAL; '); } public function write(string $key, array $dependencies): void { if (!$this->pdo) { $this->open(); } $this->pdo->exec('BEGIN'); if (!empty($dependencies[Cache::Tags])) { $this->pdo->prepare('DELETE FROM tags WHERE key = ?')->execute([$key]); foreach ($dependencies[Cache::Tags] as $tag) { $arr[] = $key; $arr[] = $tag; } $this->pdo->prepare('INSERT INTO tags (key, tag) SELECT ?, ?' . str_repeat('UNION SELECT ?, ?', count($arr) / 2 - 1)) ->execute($arr); } if (!empty($dependencies[Cache::Priority])) { $this->pdo->prepare('REPLACE INTO priorities (key, priority) VALUES (?, ?)') ->execute([$key, (int) $dependencies[Cache::Priority]]); } $this->pdo->exec('COMMIT'); } public function clean(array $conditions): ?array { if (!$this->pdo) { $this->open(); } if (!empty($conditions[Cache::All])) { $this->pdo->exec(' BEGIN; DELETE FROM tags; DELETE FROM priorities; COMMIT; '); return null; } $unions = $args = []; if (!empty($conditions[Cache::Tags])) { $tags = (array) $conditions[Cache::Tags]; $unions[] = 'SELECT DISTINCT key FROM tags WHERE tag IN (?' . str_repeat(', ?', count($tags) - 1) . ')'; $args = $tags; } if (!empty($conditions[Cache::Priority])) { $unions[] = 'SELECT DISTINCT key FROM priorities WHERE priority <= ?'; $args[] = (int) $conditions[Cache::Priority]; } if (empty($unions)) { return []; } $unionSql = implode(' UNION ', $unions); $this->pdo->exec('BEGIN IMMEDIATE'); $stmt = $this->pdo->prepare($unionSql); $stmt->execute($args); $keys = $stmt->fetchAll(\PDO::FETCH_COLUMN, 0); if (empty($keys)) { $this->pdo->exec('COMMIT'); return []; } $this->pdo->prepare("DELETE FROM tags WHERE key IN ($unionSql)")->execute($args); $this->pdo->prepare("DELETE FROM priorities WHERE key IN ($unionSql)")->execute($args); $this->pdo->exec('COMMIT'); return $keys; } }