MediaWiki  master
DatabaseInstaller.php
Go to the documentation of this file.
1 <?php
30 
37 abstract class DatabaseInstaller {
38 
44  public $parent;
45 
49  public static $minimumVersion;
50 
54  protected static $notMinimumVersionMessage;
55 
61  public $db = null;
62 
68  protected $internalDefaults = [];
69 
75  protected $globalNames = [];
76 
84  public static function meetsMinimumRequirement( $serverVersion ) {
85  if ( version_compare( $serverVersion, static::$minimumVersion ) < 0 ) {
86  return Status::newFatal(
87  static::$notMinimumVersionMessage, static::$minimumVersion, $serverVersion
88  );
89  }
90 
91  return Status::newGood();
92  }
93 
97  abstract public function getName();
98 
102  abstract public function isCompiled();
103 
109  public function checkPrerequisites() {
110  return Status::newGood();
111  }
112 
120  abstract public function getConnectForm();
121 
131  abstract public function submitConnectForm();
132 
140  public function getSettingsForm() {
141  return false;
142  }
143 
150  public function submitSettingsForm() {
151  return Status::newGood();
152  }
153 
162  abstract public function openConnection();
163 
170  abstract public function setupDatabase();
171 
182  public function getConnection() {
183  if ( $this->db ) {
184  return Status::newGood( $this->db );
185  }
186 
187  $status = $this->openConnection();
188  if ( $status->isOK() ) {
189  $this->db = $status->value;
190  // Enable autocommit
191  $this->db->clearFlag( DBO_TRX );
192  $this->db->commit( __METHOD__ );
193  }
194 
195  return $status;
196  }
197 
206  private function stepApplySourceFile(
207  $sourceFileMethod,
208  $stepName,
209  $archiveTableMustNotExist = false
210  ) {
211  $status = $this->getConnection();
212  if ( !$status->isOK() ) {
213  return $status;
214  }
215  $this->db->selectDB( $this->getVar( 'wgDBname' ) );
216 
217  if ( $archiveTableMustNotExist && $this->db->tableExists( 'archive', __METHOD__ ) ) {
218  $status->warning( "config-$stepName-tables-exist" );
219  $this->enableLB();
220 
221  return $status;
222  }
223 
224  $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
225  $this->db->begin( __METHOD__ );
226 
227  $error = $this->db->sourceFile(
228  call_user_func( [ $this, $sourceFileMethod ], $this->db )
229  );
230  if ( $error !== true ) {
231  $this->db->reportQueryError( $error, 0, '', __METHOD__ );
232  $this->db->rollback( __METHOD__ );
233  $status->fatal( "config-$stepName-tables-failed", $error );
234  } else {
235  $this->db->commit( __METHOD__ );
236  }
237  // Resume normal operations
238  if ( $status->isOK() ) {
239  $this->enableLB();
240  }
241 
242  return $status;
243  }
244 
250  public function createTables() {
251  return $this->stepApplySourceFile( 'getGeneratedSchemaPath', 'install', true );
252  }
253 
259  public function createManualTables() {
260  // TODO: Set "archiveTableMustNotExist" to "false" when archive table is migrated to tables.json
261  return $this->stepApplySourceFile( 'getSchemaPath', 'install-manual', true );
262  }
263 
269  public function insertUpdateKeys() {
270  return $this->stepApplySourceFile( 'getUpdateKeysPath', 'updates', false );
271  }
272 
281  private function getSqlFilePath( $db, $filename ) {
282  global $IP;
283 
284  $dbmsSpecificFilePath = "$IP/maintenance/" . $db->getType() . "/$filename";
285  if ( file_exists( $dbmsSpecificFilePath ) ) {
286  return $dbmsSpecificFilePath;
287  } else {
288  return "$IP/maintenance/$filename";
289  }
290  }
291 
299  public function getSchemaPath( $db ) {
300  return $this->getSqlFilePath( $db, 'tables.sql' );
301  }
302 
309  public function getGeneratedSchemaPath( $db ) {
310  return $this->getSqlFilePath( $db, 'tables-generated.sql' );
311  }
312 
320  public function getUpdateKeysPath( $db ) {
321  return $this->getSqlFilePath( $db, 'update-keys.sql' );
322  }
323 
328  public function createExtensionTables() {
329  $status = $this->getConnection();
330  if ( !$status->isOK() ) {
331  return $status;
332  }
333 
334  // Now run updates to create tables for old extensions
335  DatabaseUpdater::newForDB( $this->db )->doUpdates( [ 'extensions' ] );
336 
337  return $status;
338  }
339 
345  abstract public function getLocalSettings();
346 
352  public function getSchemaVars() {
353  return [];
354  }
355 
362  public function setupSchemaVars() {
363  $status = $this->getConnection();
364  if ( $status->isOK() ) {
365  // @phan-suppress-next-line PhanUndeclaredMethod
366  $status->value->setSchemaVars( $this->getSchemaVars() );
367  } else {
368  $msg = __METHOD__ . ': unexpected error while establishing'
369  . ' a database connection with message: '
370  . $status->getMessage()->plain();
371  throw new MWException( $msg );
372  }
373  }
374 
380  public function enableLB() {
381  $status = $this->getConnection();
382  if ( !$status->isOK() ) {
383  throw new MWException( __METHOD__ . ': unexpected DB connection error' );
384  }
385 
386  MediaWikiServices::resetGlobalInstance();
387  $services = MediaWikiServices::getInstance();
388 
389  $connection = $status->value;
390  $services->redefineService( 'DBLoadBalancerFactory', function () use ( $connection ) {
391  return LBFactorySingle::newFromConnection( $connection );
392  } );
393  }
394 
401  public function doUpgrade() {
402  $this->setupSchemaVars();
403  $this->enableLB();
404 
405  $ret = true;
406  ob_start( [ $this, 'outputHandler' ] );
407  $up = DatabaseUpdater::newForDB( $this->db );
408  try {
409  $up->doUpdates();
410  $up->purgeCache();
411  } catch ( MWException $e ) {
412  echo "\nAn error occurred:\n";
413  echo $e->getText();
414  $ret = false;
415  } catch ( Exception $e ) {
416  echo "\nAn error occurred:\n";
417  echo $e->getMessage();
418  $ret = false;
419  }
420  ob_end_flush();
421 
422  return $ret;
423  }
424 
430  public function preInstall() {
431  }
432 
436  public function preUpgrade() {
437  }
438 
443  public function getGlobalNames() {
444  return $this->globalNames;
445  }
446 
452  public function __construct( $parent ) {
453  $this->parent = $parent;
454  }
455 
463  protected static function checkExtension( $name ) {
464  return extension_loaded( $name );
465  }
466 
471  public function getReadableName() {
472  // Messages: config-type-mysql, config-type-postgres, config-type-sqlite
473  return wfMessage( 'config-type-' . $this->getName() )->text();
474  }
475 
480  public function getGlobalDefaults() {
481  $defaults = [];
482  foreach ( $this->getGlobalNames() as $var ) {
483  if ( isset( $GLOBALS[$var] ) ) {
484  $defaults[$var] = $GLOBALS[$var];
485  }
486  }
487  return $defaults;
488  }
489 
494  public function getInternalDefaults() {
496  }
497 
504  public function getVar( $var, $default = null ) {
505  $defaults = $this->getGlobalDefaults();
506  $internal = $this->getInternalDefaults();
507  if ( isset( $defaults[$var] ) ) {
508  $default = $defaults[$var];
509  } elseif ( isset( $internal[$var] ) ) {
510  $default = $internal[$var];
511  }
512 
513  return $this->parent->getVar( $var, $default );
514  }
515 
521  public function setVar( $name, $value ) {
522  $this->parent->setVar( $name, $value );
523  }
524 
534  public function getTextBox( $var, $label, $attribs = [], $helpData = "" ) {
535  $name = $this->getName() . '_' . $var;
536  $value = $this->getVar( $var );
537  if ( !isset( $attribs ) ) {
538  $attribs = [];
539  }
540 
541  return $this->parent->getTextBox( [
542  'var' => $var,
543  'label' => $label,
544  'attribs' => $attribs,
545  'controlName' => $name,
546  'value' => $value,
547  'help' => $helpData
548  ] );
549  }
550 
561  public function getPasswordBox( $var, $label, $attribs = [], $helpData = "" ) {
562  $name = $this->getName() . '_' . $var;
563  $value = $this->getVar( $var );
564  if ( !isset( $attribs ) ) {
565  $attribs = [];
566  }
567 
568  return $this->parent->getPasswordBox( [
569  'var' => $var,
570  'label' => $label,
571  'attribs' => $attribs,
572  'controlName' => $name,
573  'value' => $value,
574  'help' => $helpData
575  ] );
576  }
577 
587  public function getCheckBox( $var, $label, $attribs = [], $helpData = "" ) {
588  $name = $this->getName() . '_' . $var;
589  $value = $this->getVar( $var );
590 
591  return $this->parent->getCheckBox( [
592  'var' => $var,
593  'label' => $label,
594  'attribs' => $attribs,
595  'controlName' => $name,
596  'value' => $value,
597  'help' => $helpData
598  ] );
599  }
600 
613  public function getRadioSet( $params ) {
614  $params['controlName'] = $this->getName() . '_' . $params['var'];
615  $params['value'] = $this->getVar( $params['var'] );
616 
617  return $this->parent->getRadioSet( $params );
618  }
619 
627  public function setVarsFromRequest( $varNames ) {
628  return $this->parent->setVarsFromRequest( $varNames, $this->getName() . '_' );
629  }
630 
641  public function needsUpgrade() {
642  $status = $this->getConnection();
643  if ( !$status->isOK() ) {
644  return false;
645  }
646 
647  try {
648  $this->db->selectDB( $this->getVar( 'wgDBname' ) );
649  } catch ( DBConnectionError $e ) {
650  // Don't catch DBConnectionError
651  throw $e;
652  } catch ( DBExpectedError $e ) {
653  return false;
654  }
655 
656  return $this->db->tableExists( 'cur', __METHOD__ ) ||
657  $this->db->tableExists( 'revision', __METHOD__ );
658  }
659 
665  public function getInstallUserBox() {
666  return Html::openElement( 'fieldset' ) .
667  Html::element( 'legend', [], wfMessage( 'config-db-install-account' )->text() ) .
668  $this->getTextBox(
669  '_InstallUser',
670  'config-db-username',
671  [ 'dir' => 'ltr' ],
672  $this->parent->getHelpBox( 'config-db-install-username' )
673  ) .
674  $this->getPasswordBox(
675  '_InstallPassword',
676  'config-db-password',
677  [ 'dir' => 'ltr' ],
678  $this->parent->getHelpBox( 'config-db-install-password' )
679  ) .
680  Html::closeElement( 'fieldset' );
681  }
682 
687  public function submitInstallUserBox() {
688  $this->setVarsFromRequest( [ '_InstallUser', '_InstallPassword' ] );
689 
690  return Status::newGood();
691  }
692 
700  public function getWebUserBox( $noCreateMsg = false ) {
701  $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
702  $s = Html::openElement( 'fieldset' ) .
703  Html::element( 'legend', [], wfMessage( 'config-db-web-account' )->text() ) .
704  $this->getCheckBox(
705  '_SameAccount', 'config-db-web-account-same',
706  [ 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' ]
707  ) .
708  Html::openElement( 'div', [ 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ] ) .
709  $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
710  $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
711  $this->parent->getHelpBox( 'config-db-web-help' );
712  if ( $noCreateMsg ) {
713  $s .= Html::warningBox( wfMessage( $noCreateMsg )->plain(), 'config-warning-box' );
714  } else {
715  $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
716  }
717  $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
718 
719  return $s;
720  }
721 
727  public function submitWebUserBox() {
728  $this->setVarsFromRequest(
729  [ 'wgDBuser', 'wgDBpassword', '_SameAccount', '_CreateDBAccount' ]
730  );
731 
732  if ( $this->getVar( '_SameAccount' ) ) {
733  $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
734  $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
735  }
736 
737  if ( $this->getVar( '_CreateDBAccount' ) && strval( $this->getVar( 'wgDBpassword' ) ) == '' ) {
738  return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
739  }
740 
741  return Status::newGood();
742  }
743 
749  public function populateInterwikiTable() {
750  $status = $this->getConnection();
751  if ( !$status->isOK() ) {
752  return $status;
753  }
754  $this->db->selectDB( $this->getVar( 'wgDBname' ) );
755 
756  if ( $this->db->selectRow( 'interwiki', '1', [], __METHOD__ ) ) {
757  $status->warning( 'config-install-interwiki-exists' );
758 
759  return $status;
760  }
761  global $IP;
762  Wikimedia\suppressWarnings();
763  $rows = file( "$IP/maintenance/interwiki.list",
764  FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
765  Wikimedia\restoreWarnings();
766  $interwikis = [];
767  if ( !$rows ) {
768  return Status::newFatal( 'config-install-interwiki-list' );
769  }
770  foreach ( $rows as $row ) {
771  $row = preg_replace( '/^\s*([^#]*?)\s*(#.*)?$/', '\\1', $row ); // strip comments - whee
772  if ( $row == "" ) {
773  continue;
774  }
775  $row .= "|";
776  $interwikis[] = array_combine(
777  [ 'iw_prefix', 'iw_url', 'iw_local', 'iw_api', 'iw_wikiid' ],
778  explode( '|', $row )
779  );
780  }
781  $this->db->insert( 'interwiki', $interwikis, __METHOD__ );
782 
783  return Status::newGood();
784  }
785 
786  public function outputHandler( $string ) {
787  return htmlspecialchars( $string );
788  }
789 }
DatabaseInstaller\createManualTables
createManualTables()
Create database tables from scratch.
Definition: DatabaseInstaller.php:259
DatabaseInstaller\$globalNames
array $globalNames
Array of MW configuration globals this class uses.
Definition: DatabaseInstaller.php:75
Wikimedia\Rdbms\Database
Relational database abstraction object.
Definition: Database.php:50
DatabaseUpdater\newForDB
static newForDB(IMaintainableDatabase $db, $shared=false, Maintenance $maintenance=null)
Definition: DatabaseUpdater.php:193
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
DatabaseInstaller\getGeneratedSchemaPath
getGeneratedSchemaPath( $db)
Return a path to the DBMS-specific automatically generated schema file.
Definition: DatabaseInstaller.php:309
DatabaseInstaller\checkExtension
static checkExtension( $name)
Convenience function.
Definition: DatabaseInstaller.php:463
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:152
DatabaseInstaller\doUpgrade
doUpgrade()
Perform database upgrades.
Definition: DatabaseInstaller.php:401
WebInstaller
Class for the core installer web interface.
Definition: WebInstaller.php:32
DatabaseInstaller\getConnection
getConnection()
Connect to the database using the administrative user/password currently defined in the session.
Definition: DatabaseInstaller.php:182
DatabaseInstaller\getTextBox
getTextBox( $var, $label, $attribs=[], $helpData="")
Get a labelled text box to configure a local variable.
Definition: DatabaseInstaller.php:534
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1219
DatabaseInstaller\checkPrerequisites
checkPrerequisites()
Checks for installation prerequisites other than those checked by isCompiled()
Definition: DatabaseInstaller.php:109
DatabaseInstaller\getSchemaVars
getSchemaVars()
Override this to provide DBMS-specific schema variables, to be substituted into tables....
Definition: DatabaseInstaller.php:352
$s
$s
Definition: mergeMessageFileList.php:185
Html\warningBox
static warningBox( $html, $className='')
Return a warning box.
Definition: Html.php:726
DatabaseInstaller\preUpgrade
preUpgrade()
Allow DB installers a chance to make checks before upgrade.
Definition: DatabaseInstaller.php:436
DatabaseInstaller\preInstall
preInstall()
Allow DB installers a chance to make last-minute changes before installation occurs.
Definition: DatabaseInstaller.php:430
DatabaseInstaller\submitSettingsForm
submitSettingsForm()
Set variables based on the request array, assuming it was submitted via the form return by getSetting...
Definition: DatabaseInstaller.php:150
DatabaseInstaller\getLocalSettings
getLocalSettings()
Get the DBMS-specific options for LocalSettings.php generation.
DBO_TRX
const DBO_TRX
Definition: defines.php:12
DatabaseInstaller\getReadableName
getReadableName()
Get the internationalised name for this DBMS.
Definition: DatabaseInstaller.php:471
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
DatabaseInstaller\createTables
createTables()
Create database tables from scratch from the automatically generated file.
Definition: DatabaseInstaller.php:250
DatabaseInstaller\getInternalDefaults
getInternalDefaults()
Get a name=>value map of internal variables used during installation.
Definition: DatabaseInstaller.php:494
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:315
DatabaseInstaller\getSqlFilePath
getSqlFilePath( $db, $filename)
Return a path to the DBMS-specific SQL file if it exists, otherwise default SQL file.
Definition: DatabaseInstaller.php:281
DatabaseInstaller\getConnectForm
getConnectForm()
Get HTML for a web form that configures this database.
MWException
MediaWiki exception.
Definition: MWException.php:28
DatabaseInstaller\getPasswordBox
getPasswordBox( $var, $label, $attribs=[], $helpData="")
Get a labelled password box to configure a local variable.
Definition: DatabaseInstaller.php:561
Wikimedia\Rdbms\LBFactorySingle
An LBFactory class that always returns a single database object.
Definition: LBFactorySingle.php:32
MWException\getText
getText()
Get the text to display when reporting the error on the command line.
Definition: MWException.php:140
DatabaseInstaller\submitConnectForm
submitConnectForm()
Set variables based on the request array, assuming it was submitted via the form returned by getConne...
DatabaseInstaller\getUpdateKeysPath
getUpdateKeysPath( $db)
Return a path to the DBMS-specific update key file, otherwise default to update-keys....
Definition: DatabaseInstaller.php:320
DatabaseInstaller\submitWebUserBox
submitWebUserBox()
Submit the form from getWebUserBox().
Definition: DatabaseInstaller.php:727
DatabaseInstaller\$minimumVersion
static string $minimumVersion
Set by subclasses.
Definition: DatabaseInstaller.php:49
DatabaseInstaller\getName
getName()
Return the internal name, e.g.
DatabaseInstaller\outputHandler
outputHandler( $string)
Definition: DatabaseInstaller.php:786
DatabaseInstaller\setupSchemaVars
setupSchemaVars()
Set appropriate schema variables in the current database connection.
Definition: DatabaseInstaller.php:362
DatabaseInstaller\getSchemaPath
getSchemaPath( $db)
Return a path to the DBMS-specific schema file, otherwise default to tables.sql.
Definition: DatabaseInstaller.php:299
DatabaseInstaller\getWebUserBox
getWebUserBox( $noCreateMsg=false)
Get a standard web-user fieldset.
Definition: DatabaseInstaller.php:700
DatabaseInstaller\getRadioSet
getRadioSet( $params)
Get a set of labelled radio buttons.
Definition: DatabaseInstaller.php:613
DatabaseInstaller\stepApplySourceFile
stepApplySourceFile( $sourceFileMethod, $stepName, $archiveTableMustNotExist=false)
Apply a SQL source file to the database as part of running an installation step.
Definition: DatabaseInstaller.php:206
DatabaseInstaller\getGlobalDefaults
getGlobalDefaults()
Get a name=>value map of MW configuration globals for the default values.
Definition: DatabaseInstaller.php:480
DatabaseInstaller\getVar
getVar( $var, $default=null)
Get a variable, taking local defaults into account.
Definition: DatabaseInstaller.php:504
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
DBO_DDLMODE
const DBO_DDLMODE
Definition: defines.php:16
DatabaseInstaller\createExtensionTables
createExtensionTables()
Create the tables for each extension the user enabled.
Definition: DatabaseInstaller.php:328
DatabaseInstaller\submitInstallUserBox
submitInstallUserBox()
Submit a standard install user fieldset.
Definition: DatabaseInstaller.php:687
DatabaseInstaller
Base class for DBMS-specific installation helper classes.
Definition: DatabaseInstaller.php:37
DatabaseInstaller\getGlobalNames
getGlobalNames()
Get an array of MW configuration globals that will be configured by this class.
Definition: DatabaseInstaller.php:443
DatabaseInstaller\getSettingsForm
getSettingsForm()
Get HTML for a web form that retrieves settings used for installation.
Definition: DatabaseInstaller.php:140
Wikimedia\Rdbms\DBExpectedError
Base class for the more common types of database errors.
Definition: DBExpectedError.php:32
DatabaseInstaller\openConnection
openConnection()
Open a connection to the database using the administrative user/password currently defined in the ses...
DatabaseInstaller\$notMinimumVersionMessage
static string $notMinimumVersionMessage
Set by subclasses.
Definition: DatabaseInstaller.php:54
DatabaseInstaller\enableLB
enableLB()
Set up LBFactory so that wfGetDB() etc.
Definition: DatabaseInstaller.php:380
DatabaseInstaller\populateInterwikiTable
populateInterwikiTable()
Common function for databases that don't understand the MySQLish syntax of interwiki....
Definition: DatabaseInstaller.php:749
Html\openElement
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:251
DatabaseInstaller\setVar
setVar( $name, $value)
Convenience alias for $this->parent->setVar()
Definition: DatabaseInstaller.php:521
DatabaseInstaller\getInstallUserBox
getInstallUserBox()
Get a standard install-user fieldset.
Definition: DatabaseInstaller.php:665
DatabaseInstaller\setVarsFromRequest
setVarsFromRequest( $varNames)
Convenience function to set variables based on form data.
Definition: DatabaseInstaller.php:627
Wikimedia\Rdbms\DBConnectionError
Definition: DBConnectionError.php:26
Wikimedia\Rdbms\IDatabase\getType
getType()
Get the type of the DBMS (e.g.
DatabaseInstaller\meetsMinimumRequirement
static meetsMinimumRequirement( $serverVersion)
Whether the provided version meets the necessary requirements for this type.
Definition: DatabaseInstaller.php:84
DatabaseInstaller\$parent
WebInstaller $parent
The Installer object.
Definition: DatabaseInstaller.php:44
DatabaseInstaller\isCompiled
isCompiled()
DatabaseInstaller\$db
Database $db
The database connection.
Definition: DatabaseInstaller.php:61
DatabaseInstaller\setupDatabase
setupDatabase()
Create the database and return a Status object indicating success or failure.
DatabaseInstaller\insertUpdateKeys
insertUpdateKeys()
Insert update keys into table to prevent running unneded updates.
Definition: DatabaseInstaller.php:269
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
$IP
$IP
Definition: WebStart.php:49
DatabaseInstaller\$internalDefaults
array $internalDefaults
Internal variables for installation.
Definition: DatabaseInstaller.php:68
$GLOBALS
$GLOBALS['IP']
Definition: ComposerHookHandler.php:6
DatabaseInstaller\getCheckBox
getCheckBox( $var, $label, $attribs=[], $helpData="")
Get a labelled checkbox to configure a local boolean variable.
Definition: DatabaseInstaller.php:587
DatabaseInstaller\__construct
__construct( $parent)
Construct and initialise parent.
Definition: DatabaseInstaller.php:452
DatabaseInstaller\needsUpgrade
needsUpgrade()
Determine whether an existing installation of MediaWiki is present in the configured administrative c...
Definition: DatabaseInstaller.php:641