+ /**
+ * Get a connection of a specific PostgreSQL-specific type. Connections
+ * of a given type are cached.
+ *
+ * PostgreSQL lacks cross-database operations, so after the new database is
+ * created, you need to make a separate connection to connect to that
+ * database and add tables to it.
+ *
+ * New tables are owned by the user that creates them, and MediaWiki's
+ * PostgreSQL support has always assumed that the table owner will be
+ * $wgDBuser. So before we create new tables, we either need to either
+ * connect as the other user or to execute a SET ROLE command. Using a
+ * separate connection for this allows us to avoid accidental cross-module
+ * dependencies.
+ *
+ * @param $type The type of connection to get:
+ * - create-db: A connection for creating DBs, suitable for pre-
+ * installation.
+ * - create-schema: A connection to the new DB, for creating schemas and
+ * other similar objects in the new DB.
+ * - create-tables: A connection with a role suitable for creating tables.
+ *
+ * @return A Status object. On success, a connection object will be in the
+ * value member.
+ */
+ protected function openPgConnection( $type ) {
+ switch ( $type ) {
+ case 'create-db':
+ return $this->openConnectionToAnyDB(
+ $this->getVar( '_InstallUser' ),
+ $this->getVar( '_InstallPassword' ) );
+ case 'create-schema':
+ return $this->openConnectionWithParams(
+ $this->getVar( '_InstallUser' ),
+ $this->getVar( '_InstallPassword' ),
+ $this->getVar( 'wgDBname' ) );
+ case 'create-tables':
+ $status = $this->openPgConnection( 'create-schema' );
+ if ( $status->isOK() ) {
+ /**
+ * @var $conn DatabaseBase
+ */
+ $conn = $status->value;
+ $safeRole = $conn->addIdentifierQuotes( $this->getVar( 'wgDBuser' ) );
+ $conn->query( "SET ROLE $safeRole" );
+ }
+ return $status;
+ default:
+ throw new MWException( "Invalid special connection type: \"$type\"" );
+ }
+ }
+
+ public function openConnectionToAnyDB( $user, $password ) {
+ $dbs = array(
+ 'template1',
+ 'postgres',
+ );
+ if ( !in_array( $this->getVar( 'wgDBname' ), $dbs ) ) {
+ array_unshift( $dbs, $this->getVar( 'wgDBname' ) );
+ }
+ $conn = false;
+ $status = Status::newGood();
+ foreach ( $dbs as $db ) {
+ try {
+ $conn = new DatabasePostgres(
+ $this->getVar( 'wgDBserver' ),
+ $user,
+ $password,
+ $db );
+ } catch ( DBConnectionError $error ) {
+ $conn = false;
+ $status->fatal( 'config-pg-test-error', $db,
+ $error->getMessage() );
+ }
+ if ( $conn !== false ) {
+ break;
+ }
+ }
+ if ( $conn !== false ) {
+ return Status::newGood( $conn );
+ } else {
+ return $status;
+ }
+ }
+
+ protected function getInstallUserPermissions() {
+ $status = $this->getPgConnection( 'create-db' );