47 '_InstallUser' =>
'postgres',
69 $this->parent->getHelpBox(
'config-db-host-help' )
71 $this->
getTextBox(
'wgDBport',
'config-db-port' ) .
72 Html::openElement(
'fieldset' ) .
73 Html::element(
'legend', [],
wfMessage(
'config-db-wiki-settings' )->text() ) .
78 $this->parent->getHelpBox(
'config-db-name-help' )
84 $this->parent->getHelpBox(
'config-db-schema-help' )
86 Html::closeElement(
'fieldset' ) .
100 $status = Status::newGood();
101 if ( !strlen( $newValues[
'wgDBname'] ) ) {
102 $status->fatal(
'config-missing-db-name' );
103 } elseif ( !preg_match(
'/^[a-zA-Z0-9_]+$/', $newValues[
'wgDBname'] ) ) {
104 $status->fatal(
'config-invalid-db-name', $newValues[
'wgDBname'] );
106 if ( !preg_match(
'/^[a-zA-Z0-9_]*$/', $newValues[
'wgDBmwschema'] ) ) {
107 $status->fatal(
'config-invalid-schema', $newValues[
'wgDBmwschema'] );
111 if ( $status->isOK() ) {
114 if ( !$status->isOK() ) {
119 if ( !$status->isOK() ) {
125 $conn = $status->value;
128 $version = $conn->getServerVersion();
129 $status = static::meetsMinimumRequirement( $version );
130 if ( !$status->isOK() ) {
134 $this->
setVar(
'wgDBuser', $this->
getVar(
'_InstallUser' ) );
135 $this->
setVar(
'wgDBpassword', $this->
getVar(
'_InstallPassword' ) );
137 return Status::newGood();
142 if ( $status->isOK() ) {
143 $this->db = $status->value;
162 $status = Status::newGood();
164 $db = Database::factory(
'postgres', [
165 'host' => $this->
getVar(
'wgDBserver' ),
166 'port' => $this->
getVar(
'wgDBport' ),
168 'password' => $password,
171 'keywordTableMap' => [
'user' =>
'mwuser',
'text' =>
'pagecontent' ],
173 $status->value =
$db;
175 $status->fatal(
'config-connection-error', $e->getMessage() );
187 if ( isset( $this->pgConns[
$type] ) ) {
188 return Status::newGood( $this->pgConns[
$type] );
192 if ( $status->isOK() ) {
196 $conn = $status->value;
198 $conn->commit( __METHOD__ );
199 $this->pgConns[
$type] = $conn;
234 $this->
getVar(
'_InstallUser' ),
235 $this->
getVar(
'_InstallPassword' ) );
236 case 'create-schema':
238 $this->
getVar(
'_InstallUser' ),
239 $this->
getVar(
'_InstallPassword' ),
240 $this->
getVar(
'wgDBname' ),
241 $this->
getVar(
'wgDBmwschema' ) );
242 case 'create-tables':
244 if ( $status->isOK() ) {
248 $conn = $status->value;
249 $safeRole = $conn->addIdentifierQuotes( $this->
getVar(
'wgDBuser' ) );
250 $conn->query(
"SET ROLE $safeRole" );
255 throw new MWException(
"Invalid special connection type: \"$type\"" );
264 if ( !in_array( $this->
getVar(
'wgDBname' ), $dbs ) ) {
265 array_unshift( $dbs, $this->
getVar(
'wgDBname' ) );
268 $status = Status::newGood();
269 foreach ( $dbs as
$db ) {
272 'host' => $this->
getVar(
'wgDBserver' ),
274 'password' => $password,
277 $conn = Database::factory(
'postgres', $p );
280 $status->fatal(
'config-pg-test-error',
$db,
281 $error->getMessage() );
283 if ( $conn !==
false ) {
287 if ( $conn !==
false ) {
288 return Status::newGood( $conn );
296 if ( !$status->isOK() ) {
302 $conn = $status->value;
303 $superuser = $this->
getVar(
'_InstallUser' );
305 $row = $conn->selectRow(
'"pg_catalog"."pg_roles"',
'*',
306 [
'rolname' => $superuser ], __METHOD__ );
317 return $perms->rolsuper ===
't' || $perms->rolcreaterole ===
't';
326 return $perms->rolsuper ===
't';
331 $noCreateMsg =
false;
333 $noCreateMsg =
'config-db-web-no-create-privs';
342 if ( !$status->isOK() ) {
346 $same = $this->
getVar(
'wgDBuser' ) === $this->
getVar(
'_InstallUser' );
354 if ( !$status->isOK() ) {
358 $exists = $status->value->roleExists( $this->
getVar(
'wgDBuser' ) );
363 $create = $this->
getVar(
'_CreateDBAccount' );
365 $this->
setVar(
'_CreateDBAccount',
false );
369 if ( !$create && !$exists ) {
371 $msg =
'config-install-user-missing-create';
373 $msg =
'config-install-user-missing';
376 return Status::newFatal( $msg, $this->
getVar(
'wgDBuser' ) );
381 return Status::newGood();
386 $this->
getVar(
'wgDBuser' ),
387 $this->
getVar(
'wgDBpassword' ) );
388 if ( !$status->isOK() ) {
396 return Status::newGood();
398 return Status::newFatal(
'config-pg-not-in-role' );
413 if ( !$status->isOK() ) {
416 $conn = $status->value;
417 $installerId = $conn->selectField(
'"pg_catalog"."pg_roles"',
'oid',
418 [
'rolname' => $this->
getVar(
'_InstallUser' ) ], __METHOD__ );
419 $webId = $conn->selectField(
'"pg_catalog"."pg_roles"',
'oid',
420 [
'rolname' => $this->
getVar(
'wgDBuser' ) ], __METHOD__ );
422 return $this->
isRoleMember( $conn, $installerId, $webId, $this->maxRoleSearchDepth );
433 protected function isRoleMember( $conn, $targetMember, $group, $maxDepth ) {
434 if ( $targetMember === $group ) {
439 $res = $conn->select(
'"pg_catalog"."pg_auth_members"', [
'member' ],
440 [
'roleid' => $group ], __METHOD__ );
441 foreach (
$res as $row ) {
442 if ( $row->member == $targetMember ) {
448 if ( $maxDepth > 0 &&
449 $this->
isRoleMember( $conn, $targetMember, $row->member, $maxDepth - 1 )
462 'callback' => [ $this,
'setupUser' ],
465 'name' =>
'pg-commit',
466 'callback' => [ $this,
'commitChanges' ],
469 'name' =>
'pg-plpgsql',
470 'callback' => [ $this,
'setupPLpgSQL' ],
474 'callback' => [ $this,
'setupSchema' ]
477 if ( $this->
getVar(
'_CreateDBAccount' ) ) {
478 $this->parent->addInstallStep( $createDbAccount,
'database' );
480 $this->parent->addInstallStep( $commitCB,
'interwiki' );
481 $this->parent->addInstallStep( $plpgCB,
'database' );
482 $this->parent->addInstallStep( $schemaCB,
'database' );
487 if ( !$status->isOK() ) {
490 $conn = $status->value;
492 $dbName = $this->
getVar(
'wgDBname' );
494 $exists = $conn->selectField(
'"pg_catalog"."pg_database"',
'1',
495 [
'datname' => $dbName ], __METHOD__ );
497 $safedb = $conn->addIdentifierQuotes( $dbName );
498 $conn->query(
"CREATE DATABASE $safedb", __METHOD__ );
501 return Status::newGood();
507 if ( !$status->isOK() ) {
511 $conn = $status->value;
512 '@phan-var DatabasePostgres $conn';
515 $schema = $this->
getVar(
'wgDBmwschema' );
516 $safeschema = $conn->addIdentifierQuotes( $schema );
517 $safeuser = $conn->addIdentifierQuotes( $this->
getVar(
'wgDBuser' ) );
518 if ( !$conn->schemaExists( $schema ) ) {
520 $conn->query(
"CREATE SCHEMA $safeschema AUTHORIZATION $safeuser" );
522 return Status::newFatal(
'config-install-pg-schema-failed',
523 $this->
getVar(
'_InstallUser' ), $schema );
528 $conn->determineCoreSchema( $schema );
530 return Status::newGood();
534 $this->db->commit( __METHOD__ );
536 return Status::newGood();
540 if ( !$this->
getVar(
'_CreateDBAccount' ) ) {
541 return Status::newGood();
545 if ( !$status->isOK() ) {
549 $conn = $status->value;
550 '@phan-var DatabasePostgres $conn';
552 $safeuser = $conn->addIdentifierQuotes( $this->
getVar(
'wgDBuser' ) );
553 $safepass = $conn->addQuotes( $this->
getVar(
'wgDBpassword' ) );
556 $userExists = $conn->roleExists( $this->
getVar(
'wgDBuser' ) );
557 if ( !$userExists ) {
560 $sql =
"CREATE ROLE $safeuser NOCREATEDB LOGIN PASSWORD $safepass";
566 $sql .=
' ROLE' . $conn->addIdentifierQuotes( $this->
getVar(
'_InstallUser' ) );
569 $conn->query( $sql, __METHOD__ );
571 return Status::newFatal(
'config-install-user-create-failed',
572 $this->
getVar(
'wgDBuser' ), $e->getMessage() );
576 return Status::newGood();
580 $port = $this->
getVar(
'wgDBport' );
581 $schema = $this->
getVar(
'wgDBmwschema' );
583 return "# Postgres specific settings
584\$wgDBport = \"{$port}\";
585\$wgDBmwschema = \"{$schema}\";";
591 # Normal user and password are selected after this step, so for now
592 # just copy these two
594 $wgDBpassword = $this->
getVar(
'_InstallPassword' );
598 $schema = $this->
getVar(
'wgDBmwschema' );
601 if ( !$status->isOK() ) {
606 $conn = $status->value;
607 '@phan-var DatabasePostgres $conn';
609 if ( $conn->tableExists(
'archive' ) ) {
610 $status->warning(
'config-install-tables-exist' );
616 $conn->begin( __METHOD__ );
618 if ( !$conn->schemaExists( $schema ) ) {
619 $status->fatal(
'config-install-pg-schema-not-exist' );
624 if ( $error !==
true ) {
625 $conn->reportQueryError( $error, 0,
'', __METHOD__ );
626 $conn->rollback( __METHOD__ );
627 $status->fatal(
'config-install-tables-failed', $error );
629 $conn->commit( __METHOD__ );
632 if ( $status->isOK() ) {
642 return array_merge( parent::getGlobalDefaults(), [
643 'wgDBmwschema' =>
'mediawiki',
651 if ( !$status->isOK() ) {
657 $conn = $status->value;
659 $exists = $conn->selectField(
'"pg_catalog"."pg_language"', 1,
660 [
'lanname' =>
'plpgsql' ], __METHOD__ );
663 return Status::newGood();
668 $exists = $conn->selectField(
669 [
'"pg_catalog"."pg_class"',
'"pg_catalog"."pg_namespace"' ],
672 'pg_namespace.oid=relnamespace',
673 'nspname' =>
'pg_catalog',
674 'relname' =>
'pg_pltemplate',
679 $conn->query(
'CREATE LANGUAGE plpgsql' );
681 return Status::newFatal(
'config-pg-no-plpgsql', $this->
getVar(
'wgDBname' ) );
684 return Status::newFatal(
'config-pg-no-plpgsql', $this->
getVar(
'wgDBname' ) );
687 return Status::newGood();
$wgDBuser
Database username.
$wgDBpassword
Database user's password.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Base class for DBMS-specific installation helper classes.
getWebUserBox( $noCreateMsg=false)
Get a standard web-user fieldset.
submitWebUserBox()
Submit the form from getWebUserBox().
static checkExtension( $name)
Convenience function.
enableLB()
Set up LBFactory so that wfGetDB() etc.
Database $db
The database connection.
setVarsFromRequest( $varNames)
Convenience function to set variables based on form data.
getSchemaPath( $db)
Return a path to the DBMS-specific schema file, otherwise default to tables.sql.
getVar( $var, $default=null)
Get a variable, taking local defaults into account.
getTextBox( $var, $label, $attribs=[], $helpData="")
Get a labelled text box to configure a local variable.
setVar( $name, $value)
Convenience alias for $this->parent->setVar()
submitInstallUserBox()
Submit a standard install user fieldset.
getInstallUserBox()
Get a standard install-user fieldset.
Class for setting up the MediaWiki database using Postgres.
getConnection()
Connect to the database using the administrative user/password currently defined in the session.
getPgConnection( $type)
Get a special type of connection.
openConnectionToAnyDB( $user, $password)
getName()
Return the internal name, e.g.
openConnectionWithParams( $user, $password, $dbName, $schema)
Open a PG connection with given parameters.
preUpgrade()
Allow DB installers a chance to make checks before upgrade.
setupDatabase()
Create the database and return a Status object indicating success or failure.
getGlobalDefaults()
Get a name=>value map of MW configuration globals for the default values.
createTables()
Create database tables from scratch.
getConnectForm()
Get HTML for a web form that configures this database.
submitSettingsForm()
Set variables based on the request array, assuming it was submitted via the form return by getSetting...
static $notMinimumVersionMessage
preInstall()
Allow DB installers a chance to make last-minute changes before installation occurs.
openConnection()
Open a connection to the database using the administrative user/password currently defined in the ses...
getInstallUserPermissions()
isRoleMember( $conn, $targetMember, $group, $maxDepth)
Recursive helper for canCreateObjectsForWebUser().
canCreateObjectsForWebUser()
Returns true if the install user is able to create objects owned by the web user, false otherwise.
getSettingsForm()
Get HTML for a web form that retrieves settings used for installation.
getLocalSettings()
Get the DBMS-specific options for LocalSettings.php generation.
openPgConnection( $type)
Get a connection of a specific PostgreSQL-specific type.
submitConnectForm()
Set variables based on the request array, assuming it was submitted via the form returned by getConne...