* (bug 385) Installer support for PostgreSQL, fixes for PG compatibility
authorBrion Vibber <brion@users.mediawiki.org>
Wed, 12 Apr 2006 08:15:28 +0000 (08:15 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Wed, 12 Apr 2006 08:15:28 +0000 (08:15 +0000)
Applied from: http://bugzilla.wikimedia.org/attachment.cgi?id=1517&action=view
I haven't tested it with PG personally yet, but it doesn't appear to interfere with other functionality.

18 files changed:
RELEASE-NOTES
config/index.php
includes/Article.php
includes/Database.php
includes/Export.php
includes/LoadBalancer.php
includes/Revision.php
includes/SpecialAncientpages.php
includes/SpecialBrokenRedirects.php
includes/SpecialDisambiguations.php
includes/SpecialListusers.php
includes/SpecialMostcategories.php
includes/SpecialMostlinked.php
includes/SpecialMostrevisions.php
includes/SpecialRecentchanges.php
includes/SpecialShortpages.php
includes/SpecialWatchlist.php
install-utils.inc

index 221acb7..5e8c925 100644 (file)
@@ -52,6 +52,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 5537) Add stub language file for Samogitian (bat-smg); inherits Lithuanian (lt)
 * Don't force edit summaries when a user is editing their own user/talk page
 * (bug 5510) Warning produced when using {{SUBPAGENAME}} in some namespaces
+* (bug 385) Installer support for PostgreSQL, fixes for PG compatibility
+
 
 == Compatibility ==
 
index 258ce36..b203385 100644 (file)
@@ -486,7 +486,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                $wgCommandLineMode = false;
                chdir( ".." );
                eval($local);
-               if (!in_array($conf->DBtype, array("mysql", "oracle"))) {
+               if (!in_array($conf->DBtype, array("mysql", "oracle", "postgres"))) {
                        $errs["DBtype"] = "Unknown database type.";
                        continue;
                }
@@ -505,16 +505,16 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                require_once( "maintenance/InitialiseMessages.inc" );
 
                $wgTitle = Title::newFromText( "Installation script" );
-               $mysqlOldClient = version_compare( mysql_get_client_info(), "4.1.0", "lt" );
-               if( $mysqlOldClient ) {
-                       print "<li><b>PHP is linked with old MySQL client libraries. If you are
-                               using a MySQL 4.1 server and have problems connecting to the database,
-                               see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
-                               >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b></li>\n";
-               }
                $dbc = new $dbclass;
-               
+
                if( $conf->DBtype == 'mysql' ) {
+                       $mysqlOldClient = version_compare( mysql_get_client_info(), "4.1.0", "lt" );
+                       if( $mysqlOldClient ) {
+                               print "<li><b>PHP is linked with old MySQL client libraries. If you are
+                                       using a MySQL 4.1 server and have problems connecting to the database,
+                                       see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
+                                       >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b></li>\n";
+                       }
                        $ok = true; # Let's be optimistic
                        
                        # Decide if we're going to use the superuser or the regular database user
@@ -575,13 +575,13 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                        if( !$ok ) { continue; }
 
                } else /* not mysql */ {
-                       print "<li>Connecting to SQL server...";
+                       echo( "<li>Attempting to connect to database server as $wgDBuser..." );
                        $wgDatabase = $dbc->newFromParams($wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1);
                        if (!$wgDatabase->isOpen()) {
                                print " error: " . $wgDatabase->lastError() . "</li>\n";
                        } else {
                                $wgDatabase->ignoreErrors(true);
-                               $myver = get_db_version();
+                               $myver = $wgDatabase->getServerVersion();
                        }
                }
 
@@ -591,27 +591,27 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                }
 
                print "<li>Connected to $myver";
-               if( version_compare( $myver, "4.0.0" ) < 0 ) {
-                       die( " -- mysql 4.0 or later required. Aborting." );
-               }
-               $mysqlNewAuth   = version_compare( $myver, "4.1.0", "ge" );
-               if( $mysqlNewAuth && $mysqlOldClient ) {
-                       print "; <b class='error'>You are using MySQL 4.1 server, but PHP is linked
-                               to old client libraries; if you have trouble with authentication, see
-                               <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
-                               >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>";
-               }
-               if( $wgDBmysql5 ) {
-                       if( $mysqlNewAuth ) {
-                               print "; enabling MySQL 4.1/5.0 charset mode";
-                       } else {
-                               print "; <b class='error'>MySQL 4.1/5.0 charset mode enabled,
-                                       but older version detected; will likely fail.</b>";
+               if ($conf->DBtype == 'mysql') {
+                       if( version_compare( $myver, "4.0.0" ) < 0 ) {
+                               die( " -- mysql 4.0 or later required. Aborting." );
                        }
-               }
-               print "</li>\n";
+                       $mysqlNewAuth   = version_compare( $myver, "4.1.0", "ge" );
+                       if( $mysqlNewAuth && $mysqlOldClient ) {
+                               print "; <b class='error'>You are using MySQL 4.1 server, but PHP is linked
+                                       to old client libraries; if you have trouble with authentication, see
+                                       <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'
+                                       >http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>";
+                       }
+                       if( $wgDBmysql5 ) {
+                               if( $mysqlNewAuth ) {
+                                       print "; enabling MySQL 4.1/5.0 charset mode";
+                               } else {
+                                       print "; <b class='error'>MySQL 4.1/5.0 charset mode enabled,
+                                               but older version detected; will likely fail.</b>";
+                               }
+                       }
+                       print "</li>\n";
 
-               if ($conf->DBtype == 'mysql') {
                        @$sel = mysql_select_db( $wgDBname, $wgDatabase->mConn );
                        if( $sel ) {
                                print "<li>Database <tt>" . htmlspecialchars( $wgDBname ) . "</tt> exists</li>\n";
@@ -640,7 +640,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
 
                        # Create user if required
                        if ( $conf->Root ) {
-                               $conn = Database::newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
+                               $conn = $dbc->newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
                                if ( $conn->isOpen() ) {
                                        print "<li>DB user account ok</li>\n";
                                        $conn->close();
@@ -673,6 +673,9 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                                        dbsource( "../maintenance/tables.sql", $wgDatabase );
                                }
                                dbsource( "../maintenance/interwiki.sql", $wgDatabase );
+                       } else if ($conf->DBtype == 'postgres') {
+                               dbsource( "../maintenance/postgres/tables.sql", $wgDatabase );
+                               $wgDatabase->update_interwiki();
                        } else {
                                dbsource( "../maintenance/oracle/tables.sql", $wgDatabase );
                                dbsource( "../maintenance/oracle/interwiki.sql", $wgDatabase );
@@ -690,7 +693,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                        # Set up the "regular user" account *if we can, and if we need to*
                        if( $conf->Root ) {
                                # See if we need to
-                               $wgDatabase2 = Database::newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
+                               $wgDatabase2 = $dbc->newFromParams( $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, 1 );
                                if( $wgDatabase2->isOpen() ) {
                                        # Nope, just close the test connection and continue
                                        $wgDatabase2->close();
@@ -973,6 +976,7 @@ if( count( $errs ) ) {
                <ul class='plain'>
                        <li><?php aField( $conf, "DBtype", "MySQL", "radio", "mysql"); ?></li>
                        <li><?php aField( $conf, "DBtype", "Oracle (experimental)", "radio", "oracle" ); ?></li>
+                       <li><?php aField( $conf, "DBtype", "PostgreSQL", "radio", "postgres" ); ?></li>
                </ul>
        </div>
 
@@ -981,7 +985,7 @@ if( count( $errs ) ) {
        ?></div>
        <p class="config-desc">
                If your database server isn't on your web server, enter the name
-               or IP address here.  MySQL only.
+               or IP address here. MySQL and PostgreSQL only. If using a port for PostgreSQL, enter the number here.
        </p>
 
        <div class="config-input"><?php
index 4676a4e..67053ba 100644 (file)
@@ -2483,7 +2483,7 @@ class Article {
         */
        function incViewCount( $id ) {
                $id = intval( $id );
-               global $wgHitcounterUpdateFreq;
+               global $wgHitcounterUpdateFreq, $wgDBtype;
 
                $dbw =& wfGetDB( DB_MASTER );
                $pageTable = $dbw->tableName( 'page' );
@@ -2514,12 +2514,15 @@ class Article {
                        wfProfileIn( 'Article::incViewCount-collect' );
                        $old_user_abort = ignore_user_abort( true );
 
-                       $dbw->query("LOCK TABLES $hitcounterTable WRITE");
-                       $dbw->query("CREATE TEMPORARY TABLE $acchitsTable TYPE=HEAP ".
+                       if ($wgDBtype == 'mysql')
+                               $dbw->query("LOCK TABLES $hitcounterTable WRITE");
+                       $tabletype = $wgDBtype == 'mysql' ? "ENGINE=HEAP " : '';
+                       $dbw->query("CREATE TEMPORARY TABLE $acchitsTable $tabletype".
                                "SELECT hc_id,COUNT(*) AS hc_n FROM $hitcounterTable ".
                                'GROUP BY hc_id');
                        $dbw->query("DELETE FROM $hitcounterTable");
-                       $dbw->query('UNLOCK TABLES');
+                       if ($wgDBtype == 'mysql')
+                               $dbw->query('UNLOCK TABLES');
                        $dbw->query("UPDATE $pageTable,$acchitsTable SET page_counter=page_counter + hc_n ".
                                'WHERE page_id = hc_id');
                        $dbw->query("DROP TABLE $acchitsTable");
index 423cf1b..c6eecbd 100644 (file)
@@ -1687,6 +1687,7 @@ class Database {
 
                $cmd = "";
                $done = false;
+               $dollarquote = false;
 
                while ( ! feof( $fp ) ) {
                        $line = trim( fgets( $fp, 1024 ) );
@@ -1695,9 +1696,21 @@ class Database {
                        if ( $sl < 0 ) { continue; }
                        if ( '-' == $line{0} && '-' == $line{1} ) { continue; }
 
-                       if ( ';' == $line{$sl} && ($sl < 2 || ';' != $line{$sl - 1})) {
-                               $done = true;
-                               $line = substr( $line, 0, $sl );
+                       ## Allow dollar quoting for function declarations
+                       if (substr($line,0,4) == '$mw$') {
+                               if ($dollarquote) {
+                                       $dollarquote = false;
+                                       $done = true;
+                               }
+                               else {
+                                       $dollarquote = true;
+                               }
+                       }
+                       else if (!$dollarquote) {
+                               if ( ';' == $line{$sl} && ($sl < 2 || ';' != $line{$sl - 1})) {
+                                       $done = true;
+                                       $line = substr( $line, 0, $sl );
+                               }
                        }
 
                        if ( '' != $cmd ) { $cmd .= ' '; }
index c060e72..6a8e219 100644 (file)
@@ -187,8 +187,7 @@ class WikiExporter {
                }
                if( $cond == '' ) {
                        // Optimization hack for full-database dump
-                       $pageindex = 'FORCE INDEX (PRIMARY)';
-                       $revindex = 'FORCE INDEX (PRIMARY)';
+                       $revindex = $pageindex = $this->db->useIndexClause("PRIMARY");
                        $straight = ' /*! STRAIGHT_JOIN */ ';
                } else {
                        $pageindex = '';
index 87769a5..465f3b9 100644 (file)
@@ -334,6 +334,7 @@ class LoadBalancer {
         */
        function &getConnection( $i, $fail = true, $groups = array() )
        {
+               global $wgDBtype;
                $fname = 'LoadBalancer::getConnection';
                wfProfileIn( $fname );
 
@@ -354,8 +355,12 @@ class LoadBalancer {
                        }
                }
 
+               # For now, only go through all this for mysql databases
+               if ($wgDBtype != 'mysql') {
+                       $i = $this->getWriterIndex();
+               }
                # Operation-based index
-               if ( $i == DB_SLAVE ) {
+               elseif ( $i == DB_SLAVE ) {
                        $i = $this->getReaderIndex();
                } elseif ( $i == DB_MASTER ) {
                        $i = $this->getWriterIndex();
index a89bb8b..c289bf7 100644 (file)
@@ -644,7 +644,6 @@ class Revision {
                );
 
                $this->mId = !is_null($rev_id) ? $rev_id : $dbw->insertId();
-
                wfProfileOut( $fname );
                return $this->mId;
        }
index d3381c7..f25caf4 100644 (file)
@@ -28,15 +28,18 @@ class AncientPagesPage extends QueryPage {
        function isSyndicated() { return false; }
 
        function getSQL() {
+               global $wgDBtype;
                $db =& wfGetDB( DB_SLAVE );
                $page = $db->tableName( 'page' );
                $revision = $db->tableName( 'revision' );
                #$use_index = $db->useIndexClause( 'cur_timestamp' ); # FIXME! this is gone
+               $epoch = $wgDBtype == 'mysql' ? 'UNIX_TIMESTAMP(rev_timestamp)' :
+                       'EXTRACT(epoch FROM rev_timestamp)';
                return
                        "SELECT 'Ancientpages' as type,
                                        page_namespace as namespace,
                                page_title as title,
-                               UNIX_TIMESTAMP(rev_timestamp) as value
+                               $epoch as value
                        FROM $page, $revision
                        WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0
                          AND page_latest=rev_id";
index 836bbe6..1c9be92 100644 (file)
@@ -38,12 +38,10 @@ class BrokenRedirectsPage extends PageQueryPage {
                                p1.page_title     AS title,
                                pl_namespace,
                                pl_title
-                          FROM ($pagelinks, $page AS p1)
-                     LEFT JOIN $page AS p2
-                            ON pl_namespace=p2.page_namespace AND pl_title=p2.page_title
-                         WHERE p1.page_is_redirect=1
-                           AND pl_from=p1.page_id
-                           AND p2.page_namespace IS NULL";
+                          FROM $pagelinks AS pl
+                   JOIN $page p1 ON (p1.page_is_redirect=1 AND pl.pl_from=p1.page_id)
+                     LEFT JOIN $page AS p2 ON (pl_namespace=p2.page_namespace AND pl_title=p2.page_title
+                               AND p2.page_namespace IS NULL)";
                return $sql;
        }
 
index b14fd73..d30e325 100644 (file)
@@ -47,7 +47,7 @@ class DisambiguationsPage extends PageQueryPage {
                        wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n");
                }
 
-               $sql = "SELECT 'Disambiguations' AS 'type', pa.page_namespace AS namespace,"
+               $sql = "SELECT 'Disambiguations' AS \"type\", pa.page_namespace AS namespace,"
                         ." pa.page_title AS title, la.pl_from AS value"
                         ." FROM {$templatelinks} AS lb, {$page} AS pa, {$pagelinks} AS la"
                         ." WHERE lb.tl_namespace = $dns AND lb.tl_title = $dtitle" # disambiguation template
index 17cc923..3bf16e5 100644 (file)
@@ -135,7 +135,7 @@ class ListUsersPage extends QueryPage {
                        "FROM $user ".
                        "LEFT JOIN $user_groups ON user_id=ug_user " .
                        $this->userQueryWhere( $dbr ) .
-                       " GROUP BY user_name";
+                       " GROUP BY user_name, user_id";
 
                return $sql;
        }
index 17dbb5d..0deaac9 100644 (file)
@@ -34,7 +34,7 @@ class MostcategoriesPage extends QueryPage {
                        FROM $categorylinks
                        LEFT JOIN $page ON cl_from = page_id
                        WHERE page_namespace = " . NS_MAIN . "
-                       GROUP BY cl_from
+                       GROUP BY cl_from, page_namespace, page_title
                        HAVING COUNT(*) > 1
                        ";
        }
index 28a209e..5747174 100644 (file)
@@ -34,11 +34,10 @@ class MostlinkedPage extends QueryPage {
                                pl_namespace AS namespace,
                                pl_title AS title,
                                COUNT(*) AS value,
-
                                page_namespace
                        FROM $pagelinks
                        LEFT JOIN $page ON pl_namespace=page_namespace AND pl_title=page_title
-                       GROUP BY pl_namespace,pl_title
+                       GROUP BY pl_namespace,pl_title,page_namespace
                        HAVING COUNT(*) > 1";
        }
 
index 6bc807e..46c66ec 100644 (file)
@@ -36,7 +36,7 @@ class MostrevisionsPage extends QueryPage {
                        FROM $revision
                        LEFT JOIN $page ON page_id = rev_page
                        WHERE page_namespace = " . NS_MAIN . "
-                       GROUP BY rev_page
+                       GROUP BY rev_page, page_namespace, page_title
                        HAVING COUNT(*) > 1
                        ";
        }
index 70da5bf..838b578 100644 (file)
@@ -16,7 +16,7 @@ require_once( 'Revision.php' );
  * Constructor
  */
 function wfSpecialRecentchanges( $par, $specialPage ) {
-       global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol;
+       global $wgUser, $wgOut, $wgRequest, $wgUseRCPatrol, $wgDBtype;
        global $wgRCShowWatchingUsers, $wgShowUpdatedMarker;
        global $wgAllowCategorizedRecentChanges ;
        $fname = 'wfSpecialRecentchanges';
@@ -162,7 +162,8 @@ function wfSpecialRecentchanges( $par, $specialPage ) {
        $uid = $wgUser->getID();
 
        // Perform query
-       $sql2 = "SELECT * FROM $recentchanges FORCE INDEX (rc_timestamp) " .
+       $forceclause = $dbr->useIndexClause("rc_timestamp");
+       $sql2 = "SELECT * FROM $recentchanges $forceclause".
          ($uid ? "LEFT OUTER JOIN $watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace " : "") .
          "WHERE rc_timestamp >= '{$cutoff}' {$hidem} " .
          "ORDER BY rc_timestamp DESC";
index 5d748c2..5d3dc3a 100644 (file)
@@ -38,12 +38,13 @@ class ShortPagesPage extends QueryPage {
                $page = $dbr->tableName( 'page' );
                $name = $dbr->addQuotes( $this->getName() );
 
+               $forceindex = $dbr->useIndexClause("page_len");
                return
                        "SELECT $name as type,
                                page_namespace as namespace,
                                page_title as title,
                                page_len AS value
-                       FROM $page FORCE INDEX (page_len)
+                       FROM $page $forceindex
                        WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0";
        }
 
index 3d9fbd8..816b82c 100644 (file)
@@ -269,13 +269,13 @@ function wfSpecialWatchlist( $par ) {
        }
 
        $sql = "SELECT
-         rc_namespace page_namespace,rc_title page_title,
-         rc_comment rev_comment, rc_cur_id page_id,
-         rc_user rev_user,rc_user_text rev_user_text,
-         rc_timestamp rev_timestamp,rc_minor rev_minor_edit,
-         rc_this_oldid rev_id,
+         rc_namespace AS page_namespace, rc_title AS page_title,
+         rc_comment AS rev_comment, rc_cur_id AS page_id,
+         rc_user AS rev_user, rc_user_text AS rev_user_text,
+         rc_timestamp AS rev_timestamp, rc_minor AS rev_minor_edit,
+         rc_this_oldid AS rev_id,
          rc_last_oldid,
-         rc_new page_is_new,wl_notificationtimestamp
+         rc_new AS page_is_new,wl_notificationtimestamp
          FROM $watchlist,$recentchanges,$page
          WHERE wl_user=$uid
          AND wl_namespace=rc_namespace
index 33109a6..9a8bab1 100644 (file)
@@ -15,12 +15,18 @@ function install_version_checks() {
                die( -1 );
        }
 
-       if (!extension_loaded('mysql')) {
-               if (!dl('mysql.so')) {
-                       print 'Could not load MySQL driver! Please compile '.
-                                 "php --with-mysql or install the mysql.so module.\n";
+       $gotdatabase = 0;
+       ## XXX We should quiet the warnings thrown here
+       if (extension_loaded('mysql') or dl('mysql.so')) {
+               $gotdatabase = 'mysql';
+       }
+       else if (extension_loaded('pgsql') or dl('pgsql.so')) {
+               $gotdatabase = 'pg';
+       }
+       if (!$gotdatabase) {
+               print "Could not load the MySQL or the PostgreSQL driver! Please compile ".
+                         "php with either --with-mysql or --with-pgsql, or install the mysql.so or pg.so module.\n";
                exit;
-               }
        }
 
        global $wgCommandLineMode;