Various Postgres fixes (bug 26612 stuff)
authorChad Horohoe <demon@users.mediawiki.org>
Wed, 23 Feb 2011 16:01:22 +0000 (16:01 +0000)
committerChad Horohoe <demon@users.mediawiki.org>
Wed, 23 Feb 2011 16:01:22 +0000 (16:01 +0000)
* 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
includes/installer/PostgresInstaller.php
includes/installer/PostgresUpdater.php

index c9c95b0..41e5f57 100644 (file)
@@ -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 ) {
index b7f9c8f..e6020bd 100644 (file)
@@ -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' );
index 22010b2..c387575 100644 (file)
@@ -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" );