[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |