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