MediaWiki
REL1_19
|
00001 <?php 00015 class SqliteInstaller extends DatabaseInstaller { 00016 const MINIMUM_VERSION = '3.3.7'; 00017 00021 public $db; 00022 00023 protected $globalNames = array( 00024 'wgDBname', 00025 'wgSQLiteDataDir', 00026 ); 00027 00028 public function getName() { 00029 return 'sqlite'; 00030 } 00031 00032 public function isCompiled() { 00033 return self::checkExtension( 'pdo_sqlite' ); 00034 } 00035 00040 public function checkPrerequisites() { 00041 $result = Status::newGood(); 00042 // Bail out if SQLite is too old 00043 $db = new DatabaseSqliteStandalone( ':memory:' ); 00044 if ( version_compare( $db->getServerVersion(), self::MINIMUM_VERSION, '<' ) ) { 00045 $result->fatal( 'config-outdated-sqlite', $db->getServerVersion(), self::MINIMUM_VERSION ); 00046 } 00047 // Check for FTS3 full-text search module 00048 if( DatabaseSqlite::getFulltextSearchModule() != 'FTS3' ) { 00049 $result->warning( 'config-no-fts3' ); 00050 } 00051 return $result; 00052 } 00053 00054 public function getGlobalDefaults() { 00055 if ( isset( $_SERVER['DOCUMENT_ROOT'] ) ) { 00056 $path = str_replace( 00057 array( '/', '\\' ), 00058 DIRECTORY_SEPARATOR, 00059 dirname( $_SERVER['DOCUMENT_ROOT'] ) . '/data' 00060 ); 00061 return array( 'wgSQLiteDataDir' => $path ); 00062 } else { 00063 return array(); 00064 } 00065 } 00066 00067 public function getConnectForm() { 00068 return $this->getTextBox( 'wgSQLiteDataDir', 'config-sqlite-dir', array(), $this->parent->getHelpBox( 'config-sqlite-dir-help' ) ) . 00069 $this->getTextBox( 'wgDBname', 'config-db-name', array(), $this->parent->getHelpBox( 'config-sqlite-name-help' ) ); 00070 } 00071 00079 private static function realpath( $path ) { 00080 $result = realpath( $path ); 00081 if ( !$result ) { 00082 return $path; 00083 } 00084 return $result; 00085 } 00086 00090 public function submitConnectForm() { 00091 $this->setVarsFromRequest( array( 'wgSQLiteDataDir', 'wgDBname' ) ); 00092 00093 # Try realpath() if the directory already exists 00094 $dir = self::realpath( $this->getVar( 'wgSQLiteDataDir' ) ); 00095 $result = self::dataDirOKmaybeCreate( $dir, true /* create? */ ); 00096 if ( $result->isOK() ) { 00097 # Try expanding again in case we've just created it 00098 $dir = self::realpath( $dir ); 00099 $this->setVar( 'wgSQLiteDataDir', $dir ); 00100 } 00101 return $result; 00102 } 00103 00109 private static function dataDirOKmaybeCreate( $dir, $create = false ) { 00110 if ( !is_dir( $dir ) ) { 00111 if ( !is_writable( dirname( $dir ) ) ) { 00112 $webserverGroup = Installer::maybeGetWebserverPrimaryGroup(); 00113 if ( $webserverGroup !== null ) { 00114 return Status::newFatal( 'config-sqlite-parent-unwritable-group', $dir, dirname( $dir ), basename( $dir ), $webserverGroup ); 00115 } else { 00116 return Status::newFatal( 'config-sqlite-parent-unwritable-nogroup', $dir, dirname( $dir ), basename( $dir ) ); 00117 } 00118 } 00119 00120 # Called early on in the installer, later we just want to sanity check 00121 # if it's still writable 00122 if ( $create ) { 00123 wfSuppressWarnings(); 00124 $ok = wfMkdirParents( $dir, 0700, __METHOD__ ); 00125 wfRestoreWarnings(); 00126 if ( !$ok ) { 00127 return Status::newFatal( 'config-sqlite-mkdir-error', $dir ); 00128 } 00129 # Put a .htaccess file in in case the user didn't take our advice 00130 file_put_contents( "$dir/.htaccess", "Deny from all\n" ); 00131 } 00132 } 00133 if ( !is_writable( $dir ) ) { 00134 return Status::newFatal( 'config-sqlite-dir-unwritable', $dir ); 00135 } 00136 00137 # We haven't blown up yet, fall through 00138 return Status::newGood(); 00139 } 00140 00144 public function openConnection() { 00145 global $wgSQLiteDataDir; 00146 00147 $status = Status::newGood(); 00148 $dir = $this->getVar( 'wgSQLiteDataDir' ); 00149 $dbName = $this->getVar( 'wgDBname' ); 00150 try { 00151 # @todo FIXME: Need more sensible constructor parameters, e.g. single associative array 00152 # Setting globals kind of sucks 00153 $wgSQLiteDataDir = $dir; 00154 $db = new DatabaseSqlite( false, false, false, $dbName ); 00155 $status->value = $db; 00156 } catch ( DBConnectionError $e ) { 00157 $status->fatal( 'config-sqlite-connection-error', $e->getMessage() ); 00158 } 00159 return $status; 00160 } 00161 00165 public function needsUpgrade() { 00166 $dir = $this->getVar( 'wgSQLiteDataDir' ); 00167 $dbName = $this->getVar( 'wgDBname' ); 00168 // Don't create the data file yet 00169 if ( !file_exists( DatabaseSqlite::generateFileName( $dir, $dbName ) ) ) { 00170 return false; 00171 } 00172 00173 // If the data file exists, look inside it 00174 return parent::needsUpgrade(); 00175 } 00176 00180 public function setupDatabase() { 00181 $dir = $this->getVar( 'wgSQLiteDataDir' ); 00182 00183 # Sanity check. We checked this before but maybe someone deleted the 00184 # data dir between then and now 00185 $dir_status = self::dataDirOKmaybeCreate( $dir, false /* create? */ ); 00186 if ( !$dir_status->isOK() ) { 00187 return $dir_status; 00188 } 00189 00190 $db = $this->getVar( 'wgDBname' ); 00191 $file = DatabaseSqlite::generateFileName( $dir, $db ); 00192 if ( file_exists( $file ) ) { 00193 if ( !is_writable( $file ) ) { 00194 return Status::newFatal( 'config-sqlite-readonly', $file ); 00195 } 00196 } else { 00197 if ( file_put_contents( $file, '' ) === false ) { 00198 return Status::newFatal( 'config-sqlite-cant-create-db', $file ); 00199 } 00200 } 00201 // nuke the unused settings for clarity 00202 $this->setVar( 'wgDBserver', '' ); 00203 $this->setVar( 'wgDBuser', '' ); 00204 $this->setVar( 'wgDBpassword', '' ); 00205 $this->setupSchemaVars(); 00206 return $this->getConnection(); 00207 } 00208 00212 public function createTables() { 00213 $status = parent::createTables(); 00214 return $this->setupSearchIndex( $status ); 00215 } 00216 00221 public function setupSearchIndex( &$status ) { 00222 global $IP; 00223 00224 $module = DatabaseSqlite::getFulltextSearchModule(); 00225 $fts3tTable = $this->db->checkForEnabledSearch(); 00226 if ( $fts3tTable && !$module ) { 00227 $status->warning( 'config-sqlite-fts3-downgrade' ); 00228 $this->db->sourceFile( "$IP/maintenance/sqlite/archives/searchindex-no-fts.sql" ); 00229 } elseif ( !$fts3tTable && $module == 'FTS3' ) { 00230 $this->db->sourceFile( "$IP/maintenance/sqlite/archives/searchindex-fts3.sql" ); 00231 } 00232 return $status; 00233 } 00234 00238 public function getLocalSettings() { 00239 $dir = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgSQLiteDataDir' ) ); 00240 return 00241 "# SQLite-specific settings 00242 \$wgSQLiteDataDir = \"{$dir}\";"; 00243 } 00244 }