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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

sqlite3.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 9.56 KiB


 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