From 62679f963e76dc1eb4fa749df356ef87d9c42c53 Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Wed, 23 Feb 2011 16:01:22 +0000 Subject: [PATCH] Various Postgres fixes (bug 26612 stuff) * Remove last of $wgDBuser-specific settings like timezone, datestyle and search_path. This is all handled by open() :D * Only set search_path if the schema exists (rather than just set to some random string), fall back to 'public' otherwise * Only call setupUser() if we need to _CreateDBAccount, otherwise it returns immediately and confuses you (no functional change) * Implement selectDB() for Postgres, basically call open() with a new DB name * Try to fix setupDatabase() for this "user must be owner of relation" error I'm getting when the $wgDBuser exists (have tried with roles granted && no roles granted). I get no errors at all when --- includes/db/DatabasePostgres.php | 17 ++++-- includes/installer/PostgresInstaller.php | 70 ++++++++++++------------ includes/installer/PostgresUpdater.php | 55 ------------------- 3 files changed, 49 insertions(+), 93 deletions(-) diff --git a/includes/db/DatabasePostgres.php b/includes/db/DatabasePostgres.php index c9c95b002e..41e5f57d9e 100644 --- a/includes/db/DatabasePostgres.php +++ b/includes/db/DatabasePostgres.php @@ -203,16 +203,25 @@ class DatabasePostgres extends DatabaseBase { $this->query( "SET timezone = 'GMT'", __METHOD__ ); global $wgDBmwschema; - if ( isset( $wgDBmwschema ) - && preg_match( '/^\w+$/', $wgDBmwschema ) - ) { + if ( $this->schemaExists( $wgDBmwschema ) ) { $safeschema = $this->addIdentifierQuotes( $wgDBmwschema ); - $this->doQuery( "SET search_path = $safeschema, public" ); + $this->doQuery( "SET search_path = $safeschema" ); + } else { + $this->doQuery( "SET search_path = public" ); } return $this->mConn; } + /** + * Postgres doesn't support selectDB in the same way MySQL does. So if the + * DB name doesn't match the open connection, open a new one + * @return + */ + function selectDB( $db ) { + return (bool)$this->open( $this->mServer, $this->mUser, $this->mPassword, $db ); + } + function makeConnectionString( $vars ) { $s = ''; foreach ( $vars as $name => $value ) { diff --git a/includes/installer/PostgresInstaller.php b/includes/installer/PostgresInstaller.php index b7f9c8f393..e6020bd708 100644 --- a/includes/installer/PostgresInstaller.php +++ b/includes/installer/PostgresInstaller.php @@ -188,17 +188,18 @@ class PostgresInstaller extends DatabaseInstaller { 'name' => 'pg-commit', 'callback' => array( $this, 'commitChanges' ), ); - $userCB = array( - 'name' => 'user', - 'callback' => array( $this, 'setupUser' ), - ); $plpgCB = array( 'name' => 'pg-plpgsql', 'callback' => array( $this, 'setupPLpgSQL' ), ); $this->parent->addInstallStep( $commitCB, 'interwiki' ); - $this->parent->addInstallStep( $userCB ); $this->parent->addInstallStep( $plpgCB, 'database' ); + if( $this->getVar( '_CreateDBAccount' ) ) { + $this->parent->addInstallStep( array( + 'name' => 'user', + 'callback' => array( $this, 'setupUser' ), + ) ); + } } function setupDatabase() { @@ -211,46 +212,45 @@ class PostgresInstaller extends DatabaseInstaller { $conn = $status->value; $dbName = $this->getVar( 'wgDBname' ); + $schema = $this->getVar( 'wgDBmwschema' ); + $user = $this->getVar( 'wgDBuser' ); + $safeschema = $conn->addIdentifierQuotes( $schema ); + $safeuser = $conn->addIdentifierQuotes( $user ); + $SQL = "SELECT 1 FROM pg_catalog.pg_database WHERE datname = " . $conn->addQuotes( $dbName ); $rows = $conn->numRows( $conn->query( $SQL ) ); if( !$rows ) { - $schema = $this->getVar( 'wgDBmwschema' ); - $user = $this->getVar( 'wgDBuser' ); - - $safeschema = $conn->addIdentifierQuotes( $schema ); - $safeuser = $conn->addIdentifierQuotes( $user ); - $safedb = $conn->addIdentifierQuotes( $dbName ); - $conn->query( "CREATE DATABASE $safedb OWNER $safeuser", __METHOD__ ); - - $this->useAdmin = false; + } else { + $conn->query( "ALTER DATABASE $safedb OWNER TO $safeuser", __METHOD__ ); + } + + $this->useAdmin = false; $status = $this->getConnection(); if ( !$status->isOK() ) { return $status; } - $conn = $status->value; + $conn = $status->value; - $result = $conn->schemaExists( $schema ); + if( !$conn->schemaExists( $schema ) ) { + $result = $conn->query( "CREATE SCHEMA $safeschema AUTHORIZATION $safeuser" ); if( !$result ) { - $result = $conn->query( "CREATE SCHEMA $safeschema AUTHORIZATION $safeuser" ); - if( !$result ) { - $status->fatal( 'config-install-pg-schema-failed', $user, $schema ); - } - } else { - $safeschema2 = $conn->addQuotes( $schema ); - $SQL = "SELECT 'GRANT ALL ON '||pg_catalog.quote_ident(relname)||' TO $safeuser;'\n". - "FROM pg_catalog.pg_class p, pg_catalog.pg_namespace n\n" . - "WHERE relnamespace = n.oid AND n.nspname = $safeschema2\n" . - "AND p.relkind IN ('r','S','v')\n"; - $SQL .= "UNION\n"; - $SQL .= "SELECT 'GRANT ALL ON FUNCTION '||pg_catalog.quote_ident(proname)||'('||\n". - "pg_catalog.oidvectortypes(p.proargtypes)||') TO $safeuser;'\n" . - "FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n\n" . - "WHERE p.pronamespace = n.oid AND n.nspname = $safeschema2"; - $conn->query( "SET search_path = $safeschema" ); - $res = $conn->query( $SQL ); + $status->fatal( 'config-install-pg-schema-failed', $user, $schema ); } + } else { + $safeschema2 = $conn->addQuotes( $schema ); + $SQL = "SELECT 'GRANT ALL ON '||pg_catalog.quote_ident(relname)||' TO $safeuser;'\n". + "FROM pg_catalog.pg_class p, pg_catalog.pg_namespace n\n" . + "WHERE relnamespace = n.oid AND n.nspname = $safeschema2\n" . + "AND p.relkind IN ('r','S','v')\n"; + $SQL .= "UNION\n"; + $SQL .= "SELECT 'GRANT ALL ON FUNCTION '||pg_catalog.quote_ident(proname)||'('||\n". + "pg_catalog.oidvectortypes(p.proargtypes)||') TO $safeuser;'\n" . + "FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n\n" . + "WHERE p.pronamespace = n.oid AND n.nspname = $safeschema2"; + $conn->query( "SET search_path = $safeschema" ); + $res = $conn->query( $SQL ); } return $status; } @@ -286,6 +286,9 @@ class PostgresInstaller extends DatabaseInstaller { if ( $res !== true && !( $res instanceOf ResultWrapper ) ) { $status->fatal( 'config-install-user-failed', $this->getVar( 'wgDBuser' ), $res ); } + if( $status->isOK() ) { + $this->db->query("ALTER USER $safeuser SET search_path = $safeschema"); + } } return $status; @@ -318,7 +321,6 @@ class PostgresInstaller extends DatabaseInstaller { if ( !$status->isOK() ) { return $status; } - $this->db->selectDB( $this->getVar( 'wgDBname' ) ); if( $this->db->tableExists( 'user' ) ) { $status->warning( 'config-install-tables-exist' ); diff --git a/includes/installer/PostgresUpdater.php b/includes/installer/PostgresUpdater.php index 22010b2eb1..c3875754ae 100644 --- a/includes/installer/PostgresUpdater.php +++ b/includes/installer/PostgresUpdater.php @@ -21,9 +21,6 @@ class PostgresUpdater extends DatabaseUpdater { */ protected function getCoreUpdateList() { return array( - # beginning - array( 'checkPgUser' ), - # new sequences array( 'addSequence', 'logging_log_id_seq' ), array( 'addSequence', 'page_restrictions_pr_id_seq' ), @@ -506,58 +503,6 @@ END; $this->db->query( $command ); } - /** - * Verify that this user is configured correctly - */ - protected function checkPgUser() { - global $wgDBmwschema, $wgDBuser; - - $config = $this->db->selectField( - 'pg_catalog.pg_user', "array_to_string(useconfig,'*')", - array( 'usename' => $wgDBuser ), __METHOD__ ); - - $conf = array(); - foreach ( explode( '*', $config ) as $c ) { - list( $x, $y ) = explode( '=', $c ); - $conf[$x] = $y; - } - - if ( !array_key_exists( 'search_path', $conf ) ) { - $search_path = ''; - } else { - $search_path = $conf['search_path']; - } - - if ( strpos( $search_path, $wgDBmwschema ) === false ) { - $this->output( "Adding in schema '$wgDBmwschema' to search_path for user '$wgDBuser'\n" ); - $search_path = "$wgDBmwschema, $search_path"; - } - $search_path = str_replace( ', ,', ',', $search_path ); - if ( array_key_exists( 'search_path', $conf ) === false || $search_path != $conf['search_path'] ) { - $this->db->query( "ALTER USER $wgDBuser SET search_path = $search_path" ); - $this->db->query( "SET search_path = $search_path" ); - } else { - $path = $conf['search_path']; - $this->output( "... search_path for user '$wgDBuser' looks correct ($path)\n" ); - } - - $goodconf = array( - 'client_min_messages' => 'error', - 'DateStyle' => 'ISO, YMD', - 'TimeZone' => 'GMT' - ); - - foreach ( $goodconf as $key => $value ) { - if ( !array_key_exists( $key, $conf ) or $conf[$key] !== $value ) { - $this->output( "Setting $key to '$value' for user '$wgDBuser'\n" ); - $this->db->query( "ALTER USER $wgDBuser SET $key = '$value'" ); - $this->db->query( "SET $key = '$value'" ); - } else { - $this->output( "... default value of '$key' is correctly set to '$value' for user '$wgDBuser'\n" ); - } - } - } - protected function convertArchive2() { if ( $this->db->tableExists( "archive2" ) ) { $this->output( "Converting 'archive2' back to normal archive table\n" ); -- 2.20.1