[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/installer/ -> SqliteInstaller.php (source)

   1  <?php
   2  /**
   3   * Sqlite-specific installer.
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   * @ingroup Deployment
  22   */
  23  
  24  /**
  25   * Class for setting up the MediaWiki database using SQLLite.
  26   *
  27   * @ingroup Deployment
  28   * @since 1.17
  29   */
  30  class SqliteInstaller extends DatabaseInstaller {
  31      const MINIMUM_VERSION = '3.3.7';
  32  
  33      /**
  34       * @var DatabaseSqlite
  35       */
  36      public $db;
  37  
  38      protected $globalNames = array(
  39          'wgDBname',
  40          'wgSQLiteDataDir',
  41      );
  42  
  43  	public function getName() {
  44          return 'sqlite';
  45      }
  46  
  47  	public function isCompiled() {
  48          return self::checkExtension( 'pdo_sqlite' );
  49      }
  50  
  51      /**
  52       *
  53       * @return Status
  54       */
  55  	public function checkPrerequisites() {
  56          $result = Status::newGood();
  57          // Bail out if SQLite is too old
  58          $db = new DatabaseSqliteStandalone( ':memory:' );
  59          if ( version_compare( $db->getServerVersion(), self::MINIMUM_VERSION, '<' ) ) {
  60              $result->fatal( 'config-outdated-sqlite', $db->getServerVersion(), self::MINIMUM_VERSION );
  61          }
  62          // Check for FTS3 full-text search module
  63          if ( DatabaseSqlite::getFulltextSearchModule() != 'FTS3' ) {
  64              $result->warning( 'config-no-fts3' );
  65          }
  66  
  67          return $result;
  68      }
  69  
  70  	public function getGlobalDefaults() {
  71          if ( isset( $_SERVER['DOCUMENT_ROOT'] ) ) {
  72              $path = str_replace(
  73                  array( '/', '\\' ),
  74                  DIRECTORY_SEPARATOR,
  75                  dirname( $_SERVER['DOCUMENT_ROOT'] ) . '/data'
  76              );
  77  
  78              return array( 'wgSQLiteDataDir' => $path );
  79          } else {
  80              return array();
  81          }
  82      }
  83  
  84  	public function getConnectForm() {
  85          return $this->getTextBox(
  86              'wgSQLiteDataDir',
  87              'config-sqlite-dir', array(),
  88              $this->parent->getHelpBox( 'config-sqlite-dir-help' )
  89          ) .
  90          $this->getTextBox(
  91              'wgDBname',
  92              'config-db-name',
  93              array(),
  94              $this->parent->getHelpBox( 'config-sqlite-name-help' )
  95          );
  96      }
  97  
  98      /**
  99       * Safe wrapper for PHP's realpath() that fails gracefully if it's unable to canonicalize the path.
 100       *
 101       * @param string $path
 102       *
 103       * @return string
 104       */
 105  	private static function realpath( $path ) {
 106          $result = realpath( $path );
 107          if ( !$result ) {
 108              return $path;
 109          }
 110  
 111          return $result;
 112      }
 113  
 114      /**
 115       * @return Status
 116       */
 117  	public function submitConnectForm() {
 118          $this->setVarsFromRequest( array( 'wgSQLiteDataDir', 'wgDBname' ) );
 119  
 120          # Try realpath() if the directory already exists
 121          $dir = self::realpath( $this->getVar( 'wgSQLiteDataDir' ) );
 122          $result = self::dataDirOKmaybeCreate( $dir, true /* create? */ );
 123          if ( $result->isOK() ) {
 124              # Try expanding again in case we've just created it
 125              $dir = self::realpath( $dir );
 126              $this->setVar( 'wgSQLiteDataDir', $dir );
 127          }
 128          # Table prefix is not used on SQLite, keep it empty
 129          $this->setVar( 'wgDBprefix', '' );
 130  
 131          return $result;
 132      }
 133  
 134      /**
 135       * @param string $dir
 136       * @param bool $create
 137       * @return Status
 138       */
 139  	private static function dataDirOKmaybeCreate( $dir, $create = false ) {
 140          if ( !is_dir( $dir ) ) {
 141              if ( !is_writable( dirname( $dir ) ) ) {
 142                  $webserverGroup = Installer::maybeGetWebserverPrimaryGroup();
 143                  if ( $webserverGroup !== null ) {
 144                      return Status::newFatal(
 145                          'config-sqlite-parent-unwritable-group',
 146                          $dir, dirname( $dir ), basename( $dir ),
 147                          $webserverGroup
 148                      );
 149                  } else {
 150                      return Status::newFatal(
 151                          'config-sqlite-parent-unwritable-nogroup',
 152                          $dir, dirname( $dir ), basename( $dir )
 153                      );
 154                  }
 155              }
 156  
 157              # Called early on in the installer, later we just want to sanity check
 158              # if it's still writable
 159              if ( $create ) {
 160                  wfSuppressWarnings();
 161                  $ok = wfMkdirParents( $dir, 0700, __METHOD__ );
 162                  wfRestoreWarnings();
 163                  if ( !$ok ) {
 164                      return Status::newFatal( 'config-sqlite-mkdir-error', $dir );
 165                  }
 166                  # Put a .htaccess file in in case the user didn't take our advice
 167                  file_put_contents( "$dir/.htaccess", "Deny from all\n" );
 168              }
 169          }
 170          if ( !is_writable( $dir ) ) {
 171              return Status::newFatal( 'config-sqlite-dir-unwritable', $dir );
 172          }
 173  
 174          # We haven't blown up yet, fall through
 175          return Status::newGood();
 176      }
 177  
 178      /**
 179       * @return Status
 180       */
 181  	public function openConnection() {
 182          global $wgSQLiteDataDir;
 183  
 184          $status = Status::newGood();
 185          $dir = $this->getVar( 'wgSQLiteDataDir' );
 186          $dbName = $this->getVar( 'wgDBname' );
 187          try {
 188              # @todo FIXME: Need more sensible constructor parameters, e.g. single associative array
 189              # Setting globals kind of sucks
 190              $wgSQLiteDataDir = $dir;
 191              $db = new DatabaseSqlite( false, false, false, $dbName );
 192              $status->value = $db;
 193          } catch ( DBConnectionError $e ) {
 194              $status->fatal( 'config-sqlite-connection-error', $e->getMessage() );
 195          }
 196  
 197          return $status;
 198      }
 199  
 200      /**
 201       * @return bool
 202       */
 203  	public function needsUpgrade() {
 204          $dir = $this->getVar( 'wgSQLiteDataDir' );
 205          $dbName = $this->getVar( 'wgDBname' );
 206          // Don't create the data file yet
 207          if ( !file_exists( DatabaseSqlite::generateFileName( $dir, $dbName ) ) ) {
 208              return false;
 209          }
 210  
 211          // If the data file exists, look inside it
 212          return parent::needsUpgrade();
 213      }
 214  
 215      /**
 216       * @return Status
 217       */
 218  	public function setupDatabase() {
 219          $dir = $this->getVar( 'wgSQLiteDataDir' );
 220  
 221          # Sanity check. We checked this before but maybe someone deleted the
 222          # data dir between then and now
 223          $dir_status = self::dataDirOKmaybeCreate( $dir, false /* create? */ );
 224          if ( !$dir_status->isOK() ) {
 225              return $dir_status;
 226          }
 227  
 228          $db = $this->getVar( 'wgDBname' );
 229          $file = DatabaseSqlite::generateFileName( $dir, $db );
 230          if ( file_exists( $file ) ) {
 231              if ( !is_writable( $file ) ) {
 232                  return Status::newFatal( 'config-sqlite-readonly', $file );
 233              }
 234          } else {
 235              if ( file_put_contents( $file, '' ) === false ) {
 236                  return Status::newFatal( 'config-sqlite-cant-create-db', $file );
 237              }
 238          }
 239          // nuke the unused settings for clarity
 240          $this->setVar( 'wgDBserver', '' );
 241          $this->setVar( 'wgDBuser', '' );
 242          $this->setVar( 'wgDBpassword', '' );
 243          $this->setupSchemaVars();
 244  
 245          return $this->getConnection();
 246      }
 247  
 248      /**
 249       * @return Status
 250       */
 251  	public function createTables() {
 252          $status = parent::createTables();
 253  
 254          return $this->setupSearchIndex( $status );
 255      }
 256  
 257      /**
 258       * @param Status $status
 259       * @return Status
 260       */
 261  	public function setupSearchIndex( &$status ) {
 262          global $IP;
 263  
 264          $module = DatabaseSqlite::getFulltextSearchModule();
 265          $fts3tTable = $this->db->checkForEnabledSearch();
 266          if ( $fts3tTable && !$module ) {
 267              $status->warning( 'config-sqlite-fts3-downgrade' );
 268              $this->db->sourceFile( "$IP/maintenance/sqlite/archives/searchindex-no-fts.sql" );
 269          } elseif ( !$fts3tTable && $module == 'FTS3' ) {
 270              $this->db->sourceFile( "$IP/maintenance/sqlite/archives/searchindex-fts3.sql" );
 271          }
 272  
 273          return $status;
 274      }
 275  
 276      /**
 277       * @return string
 278       */
 279  	public function getLocalSettings() {
 280          $dir = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgSQLiteDataDir' ) );
 281  
 282          return "# SQLite-specific settings
 283  \$wgSQLiteDataDir = \"{$dir}\";";
 284      }
 285  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1