1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19:
20: class SqliteJournal extends Object implements ICacheJournal
21: {
22:
23: private $database;
24:
25:
26:
27: 28: 29: 30:
31: public static function isAvailable()
32: {
33: return extension_loaded('sqlite'); 34: }
35:
36:
37:
38: public function __construct($file)
39: {
40: if (!self::isAvailable()) {
41: throw new NotSupportedException("SQLite or SQLite3 extension is required for storing tags and priorities.");
42: }
43:
44: $this->database = extension_loaded('sqlite') ? new SQLiteMimic($file) : new SQLite3($file);
45: @$this->database->exec( 46: 'CREATE TABLE cache (entry VARCHAR NOT NULL, priority INTEGER, tag VARCHAR); '
47: . 'CREATE INDEX IDX_ENTRY ON cache (entry); '
48: . 'CREATE INDEX IDX_PRI ON cache (priority); '
49: . 'CREATE INDEX IDX_TAG ON cache (tag);'
50: );
51: }
52:
53:
54:
55: 56: 57: 58: 59: 60:
61: public function write($key, array $dependencies)
62: {
63: $entry = $this->database->escapeString($key);
64: $query = '';
65: if (!empty($dependencies[Cache::TAGS])) {
66: foreach ((array) $dependencies[Cache::TAGS] as $tag) {
67: $query .= "INSERT INTO cache (entry, tag) VALUES ('$entry', '" . $this->database->escapeString($tag) . "'); ";
68: }
69: }
70: if (!empty($dependencies[Cache::PRIORITY])) {
71: $query .= "INSERT INTO cache (entry, priority) VALUES ('$entry', '" . ((int) $dependencies[Cache::PRIORITY]) . "'); ";
72: }
73:
74: if (!$this->database->exec("BEGIN; DELETE FROM cache WHERE entry = '$entry'; $query COMMIT;")) {
75: $this->database->exec('ROLLBACK');
76: return FALSE;
77: }
78:
79: return TRUE;
80: }
81:
82:
83:
84: 85: 86: 87: 88:
89: public function clean(array $conditions)
90: {
91: if (!empty($conditions[Cache::ALL])) {
92: $this->database->exec('DELETE FROM CACHE;');
93: return;
94: }
95:
96: $query = array();
97: if (!empty($conditions[Cache::TAGS])) {
98: $tags = array();
99: foreach ((array) $conditions[Cache::TAGS] as $tag) {
100: $tags[] = "'" . $this->database->escapeString($tag) . "'";
101: }
102: $query[] = 'tag IN(' . implode(', ', $tags) . ')';
103: }
104:
105: if (isset($conditions[Cache::PRIORITY])) {
106: $query[] = 'priority <= ' . ((int) $conditions[Cache::PRIORITY]);
107: }
108:
109: $entries = array();
110: if (!empty($query)) {
111: $query = implode(' OR ', $query);
112: $result = $this->database->query("SELECT entry FROM cache WHERE $query");
113: if ($result instanceof SQLiteResult) {
114: while ($entry = $result->fetchSingle()) $entries[] = $entry;
115: } else {
116: while ($entry = $result->fetchArray(SQLITE3_NUM)) $entries[] = $entry[0];
117: }
118: $this->database->exec("DELETE FROM cache WHERE $query");
119: }
120: return $entries;
121: }
122:
123: }
124:
125:
126:
127: if (class_exists('SQLiteDatabase')) {
128: 129: 130: 131: 132: 133:
134: class SQLiteMimic extends SQLiteDatabase
135: {
136:
137: function exec($sql)
138: {
139: return $this->queryExec($sql);
140: }
141:
142: function escapeString($s)
143: {
144: return sqlite_escape_string($s);
145: }
146:
147: }
148: }
149: