MediaWiki  master
DatabaseInstaller.php
Go to the documentation of this file.
1 <?php
29 
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 
110  public function checkPrerequisites() {
111  return Status::newGood();
112  }
113 
121  abstract public function getConnectForm();
122 
132  abstract public function submitConnectForm();
133 
142  public function getSettingsForm() {
143  return false;
144  }
145 
153  public function submitSettingsForm() {
154  return Status::newGood();
155  }
156 
165  abstract public function openConnection();
166 
173  abstract public function setupDatabase();
174 
186  public function getConnection() {
187  if ( $this->db ) {
188  return Status::newGood( $this->db );
189  }
190 
191  $status = $this->openConnection();
192  if ( $status->isOK() ) {
193  $this->db = $status->value;
194  // Enable autocommit
195  $this->db->clearFlag( DBO_TRX );
196  $this->db->commit( __METHOD__ );
197  }
198 
199  return $status;
200  }
201 
210  private function stepApplySourceFile(
211  $sourceFileMethod,
212  $stepName,
213  $archiveTableMustNotExist = false
214  ) {
215  $status = $this->getConnection();
216  if ( !$status->isOK() ) {
217  return $status;
218  }
219  $this->db->selectDB( $this->getVar( 'wgDBname' ) );
220 
221  if ( $archiveTableMustNotExist && $this->db->tableExists( 'archive', __METHOD__ ) ) {
222  $status->warning( "config-$stepName-tables-exist" );
223  $this->enableLB();
224 
225  return $status;
226  }
227 
228  $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
229  $this->db->begin( __METHOD__ );
230 
231  $error = $this->db->sourceFile(
232  call_user_func( [ $this, $sourceFileMethod ], $this->db )
233  );
234  if ( $error !== true ) {
235  $this->db->reportQueryError( $error, 0, '', __METHOD__ );
236  $this->db->rollback( __METHOD__ );
237  $status->fatal( "config-$stepName-tables-failed", $error );
238  } else {
239  $this->db->commit( __METHOD__ );
240  }
241  // Resume normal operations
242  if ( $status->isOK() ) {
243  $this->enableLB();
244  }
245 
246  return $status;
247  }
248 
255  public function createTables() {
256  return $this->stepApplySourceFile( 'getGeneratedSchemaPath', 'install', true );
257  }
258 
265  public function createManualTables() {
266  // TODO: Set "archiveTableMustNotExist" to "false" when archive table is migrated to tables.json
267  return $this->stepApplySourceFile( 'getSchemaPath', 'install-manual', true );
268  }
269 
276  public function insertUpdateKeys() {
277  return $this->stepApplySourceFile( 'getUpdateKeysPath', 'updates', false );
278  }
279 
288  private function getSqlFilePath( $db, $filename ) {
289  global $IP;
290 
291  $dbmsSpecificFilePath = "$IP/maintenance/" . $db->getType() . "/$filename";
292  if ( file_exists( $dbmsSpecificFilePath ) ) {
293  return $dbmsSpecificFilePath;
294  } else {
295  return "$IP/maintenance/$filename";
296  }
297  }
298 
307  public function getSchemaPath( $db ) {
308  return $this->getSqlFilePath( $db, 'tables.sql' );
309  }
310 
318  public function getGeneratedSchemaPath( $db ) {
319  return $this->getSqlFilePath( $db, 'tables-generated.sql' );
320  }
321 
330  public function getUpdateKeysPath( $db ) {
331  return $this->getSqlFilePath( $db, 'update-keys.sql' );
332  }
333 
339  public function createExtensionTables() {
340  $status = $this->getConnection();
341  if ( !$status->isOK() ) {
342  return $status;
343  }
344 
345  // Now run updates to create tables for old extensions
346  DatabaseUpdater::newForDB( $this->db )->doUpdates( [ 'extensions' ] );
347 
348  return $status;
349  }
350 
356  abstract public function getLocalSettings();
357 
364  public function getSchemaVars() {
365  return [];
366  }
367 
376  public function setupSchemaVars() {
377  $status = $this->getConnection();
378  if ( $status->isOK() ) {
379  // @phan-suppress-next-line PhanUndeclaredMethod
380  $status->value->setSchemaVars( $this->getSchemaVars() );
381  } else {
382  $msg = __METHOD__ . ': unexpected error while establishing'
383  . ' a database connection with message: '
384  . $status->getMessage()->plain();
385  throw new MWException( $msg );
386  }
387  }
388 
394  public function enableLB() {
395  $status = $this->getConnection();
396  if ( !$status->isOK() ) {
397  throw new MWException( __METHOD__ . ': unexpected DB connection error' );
398  }
399  $connection = $status->value;
400 
401  $this->parent->resetMediaWikiServices( null, [
402  'DBLoadBalancerFactory' => function () use ( $connection ) {
403  return LBFactorySingle::newFromConnection( $connection );
404  }
405  ] );
406  }
407 
414  public function doUpgrade() {
415  $this->setupSchemaVars();
416  $this->enableLB();
417 
418  $ret = true;
419  ob_start( [ $this, 'outputHandler' ] );
420  $up = DatabaseUpdater::newForDB( $this->db );
421  try {
422  $up->doUpdates();
423  $up->purgeCache();
424  } catch ( MWException $e ) {
425  echo "\nAn error occurred:\n";
426  echo $e->getText();
427  $ret = false;
428  } catch ( Exception $e ) {
429  echo "\nAn error occurred:\n";
430  echo $e->getMessage();
431  $ret = false;
432  }
433  ob_end_flush();
434 
435  return $ret;
436  }
437 
444  public function preInstall() {
445  }
446 
451  public function preUpgrade() {
452  }
453 
459  public function getGlobalNames() {
460  return $this->globalNames;
461  }
462 
469  public function __construct( $parent ) {
470  $this->parent = $parent;
471  }
472 
480  protected static function checkExtension( $name ) {
481  return extension_loaded( $name );
482  }
483 
489  public function getReadableName() {
490  // Messages: config-type-mysql, config-type-postgres, config-type-sqlite
491  return wfMessage( 'config-type-' . $this->getName() )->text();
492  }
493 
499  public function getGlobalDefaults() {
500  $defaults = [];
501  foreach ( $this->getGlobalNames() as $var ) {
502  if ( isset( $GLOBALS[$var] ) ) {
503  $defaults[$var] = $GLOBALS[$var];
504  }
505  }
506  return $defaults;
507  }
508 
513  public function getInternalDefaults() {
515  }
516 
523  public function getVar( $var, $default = null ) {
524  $defaults = $this->getGlobalDefaults();
525  $internal = $this->getInternalDefaults();
526  if ( isset( $defaults[$var] ) ) {
527  $default = $defaults[$var];
528  } elseif ( isset( $internal[$var] ) ) {
529  $default = $internal[$var];
530  }
531 
532  return $this->parent->getVar( $var, $default );
533  }
534 
540  public function setVar( $name, $value ) {
541  $this->parent->setVar( $name, $value );
542  }
543 
553  public function getTextBox( $var, $label, $attribs = [], $helpData = "" ) {
554  $name = $this->getName() . '_' . $var;
555  $value = $this->getVar( $var );
556  if ( !isset( $attribs ) ) {
557  $attribs = [];
558  }
559 
560  return $this->parent->getTextBox( [
561  'var' => $var,
562  'label' => $label,
563  'attribs' => $attribs,
564  'controlName' => $name,
565  'value' => $value,
566  'help' => $helpData
567  ] );
568  }
569 
580  public function getPasswordBox( $var, $label, $attribs = [], $helpData = "" ) {
581  $name = $this->getName() . '_' . $var;
582  $value = $this->getVar( $var );
583  if ( !isset( $attribs ) ) {
584  $attribs = [];
585  }
586 
587  return $this->parent->getPasswordBox( [
588  'var' => $var,
589  'label' => $label,
590  'attribs' => $attribs,
591  'controlName' => $name,
592  'value' => $value,
593  'help' => $helpData
594  ] );
595  }
596 
606  public function getCheckBox( $var, $label, $attribs = [], $helpData = "" ) {
607  $name = $this->getName() . '_' . $var;
608  $value = $this->getVar( $var );
609 
610  return $this->parent->getCheckBox( [
611  'var' => $var,
612  'label' => $label,
613  'attribs' => $attribs,
614  'controlName' => $name,
615  'value' => $value,
616  'help' => $helpData
617  ] );
618  }
619 
632  public function getRadioSet( $params ) {
633  $params['controlName'] = $this->getName() . '_' . $params['var'];
634  $params['value'] = $this->getVar( $params['var'] );
635 
636  return $this->parent->getRadioSet( $params );
637  }
638 
646  public function setVarsFromRequest( $varNames ) {
647  return $this->parent->setVarsFromRequest( $varNames, $this->getName() . '_' );
648  }
649 
661  public function needsUpgrade() {
662  $status = $this->getConnection();
663  if ( !$status->isOK() ) {
664  return false;
665  }
666 
667  try {
668  $this->db->selectDB( $this->getVar( 'wgDBname' ) );
669  } catch ( DBConnectionError $e ) {
670  // Don't catch DBConnectionError
671  throw $e;
672  } catch ( DBExpectedError $e ) {
673  return false;
674  }
675 
676  return $this->db->tableExists( 'cur', __METHOD__ ) ||
677  $this->db->tableExists( 'revision', __METHOD__ );
678  }
679 
685  public function getInstallUserBox() {
686  return Html::openElement( 'fieldset' ) .
687  Html::element( 'legend', [], wfMessage( 'config-db-install-account' )->text() ) .
688  $this->getTextBox(
689  '_InstallUser',
690  'config-db-username',
691  [ 'dir' => 'ltr' ],
692  $this->parent->getHelpBox( 'config-db-install-username' )
693  ) .
694  $this->getPasswordBox(
695  '_InstallPassword',
696  'config-db-password',
697  [ 'dir' => 'ltr' ],
698  $this->parent->getHelpBox( 'config-db-install-password' )
699  ) .
700  Html::closeElement( 'fieldset' );
701  }
702 
707  public function submitInstallUserBox() {
708  $this->setVarsFromRequest( [ '_InstallUser', '_InstallPassword' ] );
709 
710  return Status::newGood();
711  }
712 
720  public function getWebUserBox( $noCreateMsg = false ) {
721  $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
722  $s = Html::openElement( 'fieldset' ) .
723  Html::element( 'legend', [], wfMessage( 'config-db-web-account' )->text() ) .
724  $this->getCheckBox(
725  '_SameAccount', 'config-db-web-account-same',
726  [ 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' ]
727  ) .
728  Html::openElement( 'div', [ 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ] ) .
729  $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
730  $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
731  $this->parent->getHelpBox( 'config-db-web-help' );
732  if ( $noCreateMsg ) {
733  $s .= Html::warningBox( wfMessage( $noCreateMsg )->plain(), 'config-warning-box' );
734  } else {
735  $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
736  }
737  $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
738 
739  return $s;
740  }
741 
747  public function submitWebUserBox() {
748  $this->setVarsFromRequest(
749  [ 'wgDBuser', 'wgDBpassword', '_SameAccount', '_CreateDBAccount' ]
750  );
751 
752  if ( $this->getVar( '_SameAccount' ) ) {
753  $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
754  $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
755  }
756 
757  if ( $this->getVar( '_CreateDBAccount' ) && strval( $this->getVar( 'wgDBpassword' ) ) == '' ) {
758  return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
759  }
760 
761  return Status::newGood();
762  }
763 
770  public function populateInterwikiTable() {
771  $status = $this->getConnection();
772  if ( !$status->isOK() ) {
773  return $status;
774  }
775  $this->db->selectDB( $this->getVar( 'wgDBname' ) );
776 
777  if ( $this->db->selectRow( 'interwiki', '1', [], __METHOD__ ) ) {
778  $status->warning( 'config-install-interwiki-exists' );
779 
780  return $status;
781  }
782  global $IP;
783  Wikimedia\suppressWarnings();
784  $rows = file( "$IP/maintenance/interwiki.list",
785  FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
786  Wikimedia\restoreWarnings();
787  $interwikis = [];
788  if ( !$rows ) {
789  return Status::newFatal( 'config-install-interwiki-list' );
790  }
791  foreach ( $rows as $row ) {
792  $row = preg_replace( '/^\s*([^#]*?)\s*(#.*)?$/', '\\1', $row ); // strip comments - whee
793  if ( $row == "" ) {
794  continue;
795  }
796  $row .= "|";
797  $interwikis[] = array_combine(
798  [ 'iw_prefix', 'iw_url', 'iw_local', 'iw_api', 'iw_wikiid' ],
799  explode( '|', $row )
800  );
801  }
802  $this->db->insert( 'interwiki', $interwikis, __METHOD__ );
803 
804  return Status::newGood();
805  }
806 
807  public function outputHandler( $string ) {
808  return htmlspecialchars( $string );
809  }
810 }
DatabaseInstaller\createManualTables
createManualTables()
Create database tables from scratch.
Definition: DatabaseInstaller.php:265
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:194
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:318
DatabaseInstaller\checkExtension
static checkExtension( $name)
Convenience function.
Definition: DatabaseInstaller.php:480
DatabaseInstaller\doUpgrade
doUpgrade()
Perform database upgrades.
Definition: DatabaseInstaller.php:414
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:186
DatabaseInstaller\getTextBox
getTextBox( $var, $label, $attribs=[], $helpData="")
Get a labelled text box to configure a local variable.
Definition: DatabaseInstaller.php:553
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1220
DatabaseInstaller\checkPrerequisites
checkPrerequisites()
Checks for installation prerequisites other than those checked by isCompiled() Stable to override.
Definition: DatabaseInstaller.php:110
DatabaseInstaller\getSchemaVars
getSchemaVars()
Override this to provide DBMS-specific schema variables, to be substituted into tables....
Definition: DatabaseInstaller.php:364
$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:451
DatabaseInstaller\preInstall
preInstall()
Allow DB installers a chance to make last-minute changes before installation occurs.
Definition: DatabaseInstaller.php:444
DatabaseInstaller\submitSettingsForm
submitSettingsForm()
Set variables based on the request array, assuming it was submitted via the form return by getSetting...
Definition: DatabaseInstaller.php:153
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:489
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 Stable to override.
Definition: DatabaseInstaller.php:255
DatabaseInstaller\getInternalDefaults
getInternalDefaults()
Get a name=>value map of internal variables used during installation.
Definition: DatabaseInstaller.php:513
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:288
DatabaseInstaller\getConnectForm
getConnectForm()
Get HTML for a web form that configures this database.
MWException
MediaWiki exception.
Definition: MWException.php:29
DatabaseInstaller\getPasswordBox
getPasswordBox( $var, $label, $attribs=[], $helpData="")
Get a labelled password box to configure a local variable.
Definition: DatabaseInstaller.php:580
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:149
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:330
DatabaseInstaller\submitWebUserBox
submitWebUserBox()
Submit the form from getWebUserBox().
Definition: DatabaseInstaller.php:747
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:807
DatabaseInstaller\setupSchemaVars
setupSchemaVars()
Set appropriate schema variables in the current database connection.
Definition: DatabaseInstaller.php:376
DatabaseInstaller\getSchemaPath
getSchemaPath( $db)
Return a path to the DBMS-specific schema file, otherwise default to tables.sql Stable to override.
Definition: DatabaseInstaller.php:307
DatabaseInstaller\getWebUserBox
getWebUserBox( $noCreateMsg=false)
Get a standard web-user fieldset.
Definition: DatabaseInstaller.php:720
DatabaseInstaller\getRadioSet
getRadioSet( $params)
Get a set of labelled radio buttons.
Definition: DatabaseInstaller.php:632
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:210
DatabaseInstaller\getGlobalDefaults
getGlobalDefaults()
Get a name=>value map of MW configuration globals for the default values.
Definition: DatabaseInstaller.php:499
DatabaseInstaller\getVar
getVar( $var, $default=null)
Get a variable, taking local defaults into account.
Definition: DatabaseInstaller.php:523
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 Stable to override.
Definition: DatabaseInstaller.php:339
DatabaseInstaller\submitInstallUserBox
submitInstallUserBox()
Submit a standard install user fieldset.
Definition: DatabaseInstaller.php:707
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:459
DatabaseInstaller\getSettingsForm
getSettingsForm()
Get HTML for a web form that retrieves settings used for installation.
Definition: DatabaseInstaller.php:142
Wikimedia\Rdbms\DBExpectedError
Base class for the more common types of database errors.
Definition: DBExpectedError.php:34
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:394
DatabaseInstaller\populateInterwikiTable
populateInterwikiTable()
Common function for databases that don't understand the MySQLish syntax of interwiki....
Definition: DatabaseInstaller.php:770
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:540
DatabaseInstaller\getInstallUserBox
getInstallUserBox()
Get a standard install-user fieldset.
Definition: DatabaseInstaller.php:685
DatabaseInstaller\setVarsFromRequest
setVarsFromRequest( $varNames)
Convenience function to set variables based on form data.
Definition: DatabaseInstaller.php:646
Wikimedia\Rdbms\DBConnectionError
@newable
Definition: DBConnectionError.php:27
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:276
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:606
DatabaseInstaller\__construct
__construct( $parent)
Construct and initialise parent.
Definition: DatabaseInstaller.php:469
DatabaseInstaller\needsUpgrade
needsUpgrade()
Determine whether an existing installation of MediaWiki is present in the configured administrative c...
Definition: DatabaseInstaller.php:661