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' ) .
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'] );
128 $version = $conn->getServerVersion();
129 $status = static::meetsMinimumRequirement( $version );
134 $this->
setVar(
'wgDBuser', $this->
getVar(
'_InstallUser' ) );
135 $this->
setVar(
'wgDBpassword', $this->
getVar(
'_InstallPassword' ) );
164 $db = Database::factory(
'postgres', [
165 'host' => $this->
getVar(
'wgDBserver' ),
166 'port' => $this->
getVar(
'wgDBport' ),
168 'password' => $password,
171 'keywordTableMap' => [
'user' =>
'mwuser',
'text' =>
'pagecontent' ],
175 $status->fatal(
'config-connection-error', $e->getMessage() );
187 if ( isset( $this->pgConns[
$type] ) ) {
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':
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' ) );
269 foreach ( $dbs as
$db ) {
272 'host' => $this->
getVar(
'wgDBserver' ),
274 'password' => $password,
277 $conn = Database::factory(
'postgres', $p );
281 $error->getMessage() );
283 if ( $conn !==
false ) {
287 if ( $conn !==
false ) {
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';
346 $same = $this->
getVar(
'wgDBuser' ) === $this->
getVar(
'_InstallUser' );
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';
386 $this->
getVar(
'wgDBuser' ),
387 $this->
getVar(
'wgDBpassword' ) );
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' );
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__ );
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" );
523 $this->
getVar(
'_InstallUser' ), $schema );
528 $conn->determineCoreSchema( $schema );
534 $this->db->commit( __METHOD__ );
540 if ( !$this->
getVar(
'_CreateDBAccount' ) ) {
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__ );
572 $this->
getVar(
'wgDBuser' ), $e->getMessage() );
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' );
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__ );
642 return array_merge( parent::getGlobalDefaults(), [
643 'wgDBmwschema' =>
'mediawiki',
659 $exists = $conn->selectField(
'"pg_catalog"."pg_language"', 1,
660 [
'lanname' =>
'plpgsql' ], __METHOD__ );
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' );