Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
sqlite3.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 namespace phpbb\db\driver;
015
016 /**
017 * SQLite3 Database Abstraction Layer
018 * Minimum Requirement: 3.6.15+
019 */
020 class sqlite3 extends \phpbb\db\driver\driver
021 {
022 /**
023 * @var string Stores errors during connection setup in case the driver is not available
024 */
025 protected $connect_error = '';
026
027 /**
028 * @var \SQLite3 The SQLite3 database object to operate against
029 */
030 protected $dbo = null;
031
032 /**
033 * {@inheritDoc}
034 */
035 public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
036 {
037 $this->persistency = false;
038 $this->user = $sqluser;
039 $this->server = $sqlserver . (($port) ? ':' . $port : '');
040 $this->dbname = $database;
041
042 if (!class_exists('SQLite3', false))
043 {
044 $this->connect_error = 'SQLite3 not found, is the extension installed?';
045 return $this->sql_error('');
046 }
047
048 try
049 {
050 $this->dbo = new \SQLite3($this->server, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
051 $this->dbo->busyTimeout(60000);
052 $this->db_connect_id = true;
053 }
054 catch (\Exception $e)
055 {
056 $this->connect_error = $e->getMessage();
057 return array('message' => $this->connect_error);
058 }
059
060 return true;
061 }
062
063 /**
064 * {@inheritDoc}
065 */
066 public function sql_server_info($raw = false, $use_cache = true)
067 {
068 global $cache;
069
070 if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false)
071 {
072 $version = \SQLite3::version();
073
074 $this->sql_server_version = $version['versionString'];
075
076 if (!empty($cache) && $use_cache)
077 {
078 $cache->put('sqlite_version', $this->sql_server_version);
079 }
080 }
081
082 return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version;
083 }
084
085 /**
086 * SQL Transaction
087 *
088 * @param string $status Should be one of the following strings:
089 * begin, commit, rollback
090 * @return bool Success/failure of the transaction query
091 */
092 protected function _sql_transaction($status = 'begin')
093 {
094 switch ($status)
095 {
096 case 'begin':
097 return $this->dbo->exec('BEGIN IMMEDIATE');
098 break;
099
100 case 'commit':
101 return $this->dbo->exec('COMMIT');
102 break;
103
104 case 'rollback':
105 return @$this->dbo->exec('ROLLBACK');
106 break;
107 }
108
109 return true;
110 }
111
112 /**
113 * {@inheritDoc}
114 */
115 public function sql_query($query = '', $cache_ttl = 0)
116 {
117 if ($query != '')
118 {
119 global $cache;
120
121 // EXPLAIN only in extra debug mode
122 if (defined('DEBUG'))
123 {
124 $this->sql_report('start', $query);
125 }
126 else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
127 {
128 $this->curtime = microtime(true);
129 }
130
131 $this->last_query_text = $query;
132 $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
133 $this->sql_add_num_queries($this->query_result);
134
135 if ($this->query_result === false)
136 {
137 if ($this->transaction === true && strpos($query, 'INSERT') === 0)
138 {
139 $query = preg_replace('/^INSERT INTO/', 'INSERT OR ROLLBACK INTO', $query);
140 }
141
142 if (($this->query_result = @$this->dbo->query($query)) === false)
143 {
144 // Try to recover a lost database connection
145 if ($this->dbo && !@$this->dbo->lastErrorMsg())
146 {
147 if ($this->sql_connect($this->server, $this->user, '', $this->dbname))
148 {
149 $this->query_result = @$this->dbo->query($query);
150 }
151 }
152
153 if ($this->query_result === false)
154 {
155 $this->sql_error($query);
156 }
157 }
158
159 if (defined('DEBUG'))
160 {
161 $this->sql_report('stop', $query);
162 }
163 else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
164 {
165 $this->sql_time += microtime(true) - $this->curtime;
166 }
167
168 if (!$this->query_result)
169 {
170 return false;
171 }
172
173 if ($cache && $cache_ttl)
174 {
175 $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
176 }
177 }
178 else if (defined('DEBUG'))
179 {
180 $this->sql_report('fromcache', $query);
181 }
182 }
183 else
184 {
185 return false;
186 }
187
188 return $this->query_result;
189 }
190
191 /**
192 * Build LIMIT query
193 *
194 * @param string $query The SQL query to execute
195 * @param int $total The number of rows to select
196 * @param int $offset
197 * @param int $cache_ttl Either 0 to avoid caching or
198 * the time in seconds which the result shall be kept in cache
199 * @return mixed Buffered, seekable result handle, false on error
200 */
201 protected function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
202 {
203 $this->query_result = false;
204
205 // if $total is set to 0 we do not want to limit the number of rows
206 if ($total == 0)
207 {
208 $total = -1;
209 }
210
211 $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
212
213 return $this->sql_query($query, $cache_ttl);
214 }
215
216 /**
217 * {@inheritDoc}
218 */
219 public function sql_affectedrows()
220 {
221 return ($this->db_connect_id) ? $this->dbo->changes() : false;
222 }
223
224 /**
225 * {@inheritDoc}
226 */
227 public function sql_fetchrow($query_id = false)
228 {
229 global $cache;
230
231 if ($query_id === false)
232 {
233 /** @var \SQLite3Result $query_id */
234 $query_id = $this->query_result;
235 }
236
237 if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
238 {
239 return $cache->sql_fetchrow($query_id);
240 }
241
242 return is_object($query_id) ? @$query_id->fetchArray(SQLITE3_ASSOC) : false;
243 }
244
245 /**
246 * {@inheritDoc}
247 */
248 public function sql_nextid()
249 {
250 return ($this->db_connect_id) ? $this->dbo->lastInsertRowID() : false;
251 }
252
253 /**
254 * {@inheritDoc}
255 */
256 public function sql_freeresult($query_id = false)
257 {
258 global $cache;
259
260 if ($query_id === false)
261 {
262 $query_id = $this->query_result;
263 }
264
265 if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
266 {
267 return $cache->sql_freeresult($query_id);
268 }
269
270 if ($query_id)
271 {
272 return @$query_id->finalize();
273 }
274 }
275
276 /**
277 * {@inheritDoc}
278 */
279 public function sql_escape($msg)
280 {
281 return \SQLite3::escapeString($msg);
282 }
283
284 /**
285 * {@inheritDoc}
286 *
287 * For SQLite an underscore is an unknown character.
288 */
289 public function sql_like_expression($expression)
290 {
291 // Unlike LIKE, GLOB is unfortunately case sensitive.
292 // We only catch * and ? here, not the character map possible on file globbing.
293 $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
294
295 $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
296 $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
297
298 return 'GLOB \'' . $this->sql_escape($expression) . '\'';
299 }
300
301 /**
302 * {@inheritDoc}
303 *
304 * For SQLite an underscore is an unknown character.
305 */
306 public function sql_not_like_expression($expression)
307 {
308 // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive
309 // We only catch * and ? here, not the character map possible on file globbing.
310 $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
311
312 $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
313 $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
314
315 return 'NOT GLOB \'' . $this->sql_escape($expression) . '\'';
316 }
317
318 /**
319 * return sql error array
320 *
321 * @return array
322 */
323 protected function _sql_error()
324 {
325 if (class_exists('SQLite3', false) && isset($this->dbo))
326 {
327 $error = array(
328 'message' => $this->dbo->lastErrorMsg(),
329 'code' => $this->dbo->lastErrorCode(),
330 );
331 }
332 else
333 {
334 $error = array(
335 'message' => $this->connect_error,
336 'code' => '',
337 );
338 }
339
340 return $error;
341 }
342
343 /**
344 * Build db-specific query data
345 *
346 * @param string $stage Available stages: FROM, WHERE
347 * @param mixed $data A string containing the CROSS JOIN query or an array of WHERE clauses
348 *
349 * @return string The db-specific query fragment
350 */
351 protected function _sql_custom_build($stage, $data)
352 {
353 return $data;
354 }
355
356 /**
357 * Close sql connection
358 *
359 * @return bool False if failure
360 */
361 protected function _sql_close()
362 {
363 return $this->dbo->close();
364 }
365
366 /**
367 * Build db-specific report
368 *
369 * @param string $mode Available modes: display, start, stop,
370 * add_select_row, fromcache, record_fromcache
371 * @param string $query The Query that should be explained
372 * @return mixed Either a full HTML page, boolean or null
373 */
374 protected function _sql_report($mode, $query = '')
375 {
376 switch ($mode)
377 {
378 case 'start':
379
380 $explain_query = $query;
381 if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
382 {
383 $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
384 }
385 else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
386 {
387 $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
388 }
389
390 if (preg_match('/^SELECT/', $explain_query))
391 {
392 $html_table = false;
393
394 if ($result = $this->dbo->query("EXPLAIN QUERY PLAN $explain_query"))
395 {
396 while ($row = $result->fetchArray(SQLITE3_ASSOC))
397 {
398 $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
399 }
400 }
401
402 if ($html_table)
403 {
404 $this->html_hold .= '</table>';
405 }
406 }
407
408 break;
409
410 case 'fromcache':
411 $endtime = explode(' ', microtime());
412 $endtime = $endtime[0] + $endtime[1];
413
414 $result = $this->dbo->query($query);
415 if ($result)
416 {
417 while ($void = $result->fetchArray(SQLITE3_ASSOC))
418 {
419 // Take the time spent on parsing rows into account
420 }
421 }
422
423 $splittime = explode(' ', microtime());
424 $splittime = $splittime[0] + $splittime[1];
425
426 $this->sql_report('record_fromcache', $query, $endtime, $splittime);
427
428 break;
429 }
430 }
431 }
432