MediaWiki
REL1_21
|
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 # Table prefix is not used on SQLite, keep it empty 00117 $this->setVar( 'wgDBprefix', '' ); 00118 return $result; 00119 } 00120 00126 private static function dataDirOKmaybeCreate( $dir, $create = false ) { 00127 if ( !is_dir( $dir ) ) { 00128 if ( !is_writable( dirname( $dir ) ) ) { 00129 $webserverGroup = Installer::maybeGetWebserverPrimaryGroup(); 00130 if ( $webserverGroup !== null ) { 00131 return Status::newFatal( 'config-sqlite-parent-unwritable-group', $dir, dirname( $dir ), basename( $dir ), $webserverGroup ); 00132 } else { 00133 return Status::newFatal( 'config-sqlite-parent-unwritable-nogroup', $dir, dirname( $dir ), basename( $dir ) ); 00134 } 00135 } 00136 00137 # Called early on in the installer, later we just want to sanity check 00138 # if it's still writable 00139 if ( $create ) { 00140 wfSuppressWarnings(); 00141 $ok = wfMkdirParents( $dir, 0700, __METHOD__ ); 00142 wfRestoreWarnings(); 00143 if ( !$ok ) { 00144 return Status::newFatal( 'config-sqlite-mkdir-error', $dir ); 00145 } 00146 # Put a .htaccess file in in case the user didn't take our advice 00147 file_put_contents( "$dir/.htaccess", "Deny from all\n" ); 00148 } 00149 } 00150 if ( !is_writable( $dir ) ) { 00151 return Status::newFatal( 'config-sqlite-dir-unwritable', $dir ); 00152 } 00153 00154 # We haven't blown up yet, fall through 00155 return Status::newGood(); 00156 } 00157 00161 public function openConnection() { 00162 global $wgSQLiteDataDir; 00163 00164 $status = Status::newGood(); 00165 $dir = $this->getVar( 'wgSQLiteDataDir' ); 00166 $dbName = $this->getVar( 'wgDBname' ); 00167 try { 00168 # @todo FIXME: Need more sensible constructor parameters, e.g. single associative array 00169 # Setting globals kind of sucks 00170 $wgSQLiteDataDir = $dir; 00171 $db = new DatabaseSqlite( false, false, false, $dbName ); 00172 $status->value = $db; 00173 } catch ( DBConnectionError $e ) { 00174 $status->fatal( 'config-sqlite-connection-error', $e->getMessage() ); 00175 } 00176 return $status; 00177 } 00178 00182 public function needsUpgrade() { 00183 $dir = $this->getVar( 'wgSQLiteDataDir' ); 00184 $dbName = $this->getVar( 'wgDBname' ); 00185 // Don't create the data file yet 00186 if ( !file_exists( DatabaseSqlite::generateFileName( $dir, $dbName ) ) ) { 00187 return false; 00188 } 00189 00190 // If the data file exists, look inside it 00191 return parent::needsUpgrade(); 00192 } 00193 00197 public function setupDatabase() { 00198 $dir = $this->getVar( 'wgSQLiteDataDir' ); 00199 00200 # Sanity check. We checked this before but maybe someone deleted the 00201 # data dir between then and now 00202 $dir_status = self::dataDirOKmaybeCreate( $dir, false /* create? */ ); 00203 if ( !$dir_status->isOK() ) { 00204 return $dir_status; 00205 } 00206 00207 $db = $this->getVar( 'wgDBname' ); 00208 $file = DatabaseSqlite::generateFileName( $dir, $db ); 00209 if ( file_exists( $file ) ) { 00210 if ( !is_writable( $file ) ) { 00211 return Status::newFatal( 'config-sqlite-readonly', $file ); 00212 } 00213 } else { 00214 if ( file_put_contents( $file, '' ) === false ) { 00215 return Status::newFatal( 'config-sqlite-cant-create-db', $file ); 00216 } 00217 } 00218 // nuke the unused settings for clarity 00219 $this->setVar( 'wgDBserver', '' ); 00220 $this->setVar( 'wgDBuser', '' ); 00221 $this->setVar( 'wgDBpassword', '' ); 00222 $this->setupSchemaVars(); 00223 return $this->getConnection(); 00224 } 00225 00229 public function createTables() { 00230 $status = parent::createTables(); 00231 return $this->setupSearchIndex( $status ); 00232 } 00233 00238 public function setupSearchIndex( &$status ) { 00239 global $IP; 00240 00241 $module = DatabaseSqlite::getFulltextSearchModule(); 00242 $fts3tTable = $this->db->checkForEnabledSearch(); 00243 if ( $fts3tTable && !$module ) { 00244 $status->warning( 'config-sqlite-fts3-downgrade' ); 00245 $this->db->sourceFile( "$IP/maintenance/sqlite/archives/searchindex-no-fts.sql" ); 00246 } elseif ( !$fts3tTable && $module == 'FTS3' ) { 00247 $this->db->sourceFile( "$IP/maintenance/sqlite/archives/searchindex-fts3.sql" ); 00248 } 00249 return $status; 00250 } 00251 00255 public function getLocalSettings() { 00256 $dir = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgSQLiteDataDir' ) ); 00257 return 00258 "# SQLite-specific settings 00259 \$wgSQLiteDataDir = \"{$dir}\";"; 00260 } 00261 }