* Support for table name prefixes throughout the code. No support yet for converting...
authorTim Starling <tstarling@users.mediawiki.org>
Sun, 18 Jul 2004 08:48:43 +0000 (08:48 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sun, 18 Jul 2004 08:48:43 +0000 (08:48 +0000)
* DB_WRITE now called DB_MASTER, DB_READ now called DB_SLAVE
* Converted to use SQL wrapper functions instead of direct SQL in various places
* Experimental method for preserving the chronological order of events when slave servers are used. Untested.
* Fixes to the new post-parse existence test feature
* Some.. other stuff

93 files changed:
config/index.php
includes/Article.php
includes/Block.php
includes/Database.php
includes/DatabaseFunctions.php
includes/DatabasePostgreSQL.php
includes/DefaultSettings.php
includes/DifferenceEngine.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/Image.php
includes/ImagePage.php
includes/LinkCache.php
includes/LinksUpdate.php
includes/LoadBalancer.php
includes/LogPage.php
includes/MagicWord.php
includes/Math.php
includes/MessageCache.php
includes/ObjectCache.php
includes/OutputPage.php
includes/PageHistory.php
includes/Parser.php
includes/Profiling.php
includes/QueryPage.php
includes/RawPage.php
includes/RecentChange.php
includes/SearchEngine.php
includes/SearchUpdate.php
includes/Setup.php
includes/SiteStatsUpdate.php
includes/Skin.php
includes/SpecialAllpages.php
includes/SpecialAncientpages.php
includes/SpecialBooksources.php
includes/SpecialCategories.php
includes/SpecialContributions.php
includes/SpecialDeadendpages.php
includes/SpecialExport.php
includes/SpecialGeo.php
includes/SpecialImagelist.php
includes/SpecialImport.php
includes/SpecialListadmins.php
includes/SpecialListusers.php
includes/SpecialLonelypages.php
includes/SpecialLongpages.php
includes/SpecialMaintenance.php
includes/SpecialMakesysop.php
includes/SpecialNewpages.php
includes/SpecialPopularpages.php
includes/SpecialRandompage.php
includes/SpecialRecentchanges.php
includes/SpecialRecentchangeslinked.php
includes/SpecialShortpages.php
includes/SpecialStatistics.php
includes/SpecialUndelete.php
includes/SpecialUnusedimages.php
includes/SpecialWantedpages.php
includes/SpecialWatchlist.php
includes/SpecialWhatlinkshere.php
includes/SquidUpdate.php
includes/Title.php
includes/User.php
includes/UserTalkUpdate.php
includes/ViewCountUpdate.php
includes/WatchedItem.php
index.php
install-utils.inc
irc/rcdumper.php
languages/Language.php
maintenance/InitialiseMessages.inc
maintenance/archives/convertdb.php
maintenance/archives/moveCustomMessages.inc
maintenance/archives/patch-image_name_unique.sql [new file with mode: 0644]
maintenance/archives/upgradeWatchlist.php
maintenance/attribute.php
maintenance/compressOld.inc
maintenance/convertLinks.inc
maintenance/importPhase2.php
maintenance/indexes.sql
maintenance/rebuildInterwiki.inc [new file with mode: 0644]
maintenance/rebuildInterwiki.php
maintenance/rebuildMessages.php
maintenance/rebuildlinks.inc
maintenance/rebuildrecentchanges.inc
maintenance/rebuildtextindex.inc
maintenance/refreshLinks.inc
maintenance/remove-brokenlinks.php
maintenance/tables.sql
maintenance/trivialCmdLine.php
maintenance/updateSearchIndex.inc
maintenance/updaters.inc
texvc.phtml

index c97d78b..0682cd2 100644 (file)
@@ -184,6 +184,7 @@ class ConfigData {
 <?php
 $endl = "
 ";
+$wgConfiguring = true;
 $conf = new ConfigData;
 
 install_version_checks();
@@ -441,6 +442,7 @@ if( $conf->posted && ( 0 == count( $errs ) ) ) {
                        do_querycache_update(); flush();
                        do_objectcache_update(); flush();
                        do_categorylinks_update(); flush();
+                       do_image_name_unique_update(); flush();
 
                        if ( isTemplateInitialised() ) {
                                print "Template namespace already initialised\n";
@@ -744,7 +746,7 @@ function writeLocalSettings( $conf ) {
                for ( $i=0; $i<8; $i++ ) {
                        $proxyKey .= dechex(mt_rand(0, 0x7fffffff));
                }
-               print "Warning: \$wgProxyKey is insecure\n";
+               print "<li>Warning: \$wgProxyKey is insecure</li>\n";
        }
 
        # Add slashes to strings for double quoting
@@ -768,7 +770,7 @@ if ( \$wgCommandLineMode ) {
        if ( isset( \$_SERVER ) && array_key_exists( 'REQUEST_METHOD', \$_SERVER ) ) {
                die( \"This script must be run from the command line\\n\" );
        }
-} else {
+} elseif ( !\$wgConfiguring ) {
        ## Compress output if the browser supports it
        {$zlib}if( !ini_get( 'zlib.output_compression' ) ) ob_start( 'ob_gzhandler' );
 }
index 1638141..21fd21b 100644 (file)
@@ -143,7 +143,7 @@ class Article {
                                        $index = $matches[4];
                                        if ( $machineID == 0 ) {
                                                # Current connection
-                                               $db =& wfGetDB( DB_READ );
+                                               $db =& wfGetDB( DB_SLAVE );
                                        } else {
                                                # Alternate connection
                                                $db =& $wgLoadBalancer->getConnection( $machineID );
@@ -337,7 +337,7 @@ class Article {
        {
                global $wgOut, $wgMwRedir, $wgRequest;
 
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                # Query variables :P
                $oldid = $wgRequest->getVal( 'oldid' );
                $redirect = $wgRequest->getVal( 'redirect' );
@@ -445,7 +445,7 @@ class Article {
                $this->mContent = false;
 
                $fname = 'Article::getContentWithout';
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
 
                if ( ! $oldid ) {       # Retrieve current version
                        $id = $this->getID();
@@ -516,7 +516,7 @@ class Article {
        {
                if ( -1 == $this->mCounter ) {
                        $id = $this->getID();
-                       $dbr =& wfGetDB( DB_READ );
+                       $dbr =& wfGetDB( DB_SLAVE );
                        $this->mCounter = $dbr->getField( 'cur', 'cur_counter', "cur_id={$id}" );
                }
                return $this->mCounter;
@@ -546,7 +546,7 @@ class Article {
                
                $fname = 'Article::loadLastEdit';
 
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $s = $dbr->getArray( 'cur', 
                  array( 'cur_user','cur_user_text','cur_timestamp', 'cur_comment','cur_minor_edit' ),
                  array( 'cur_id' => $this->getID() ), $fname );
@@ -598,7 +598,7 @@ class Article {
 
                $title = $this->mTitle;
                $contribs = array();
-               $dbr = wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $oldTable = $dbr->tableName( 'old' );
                $userTable = $dbr->tableName( 'user' );
                $encDBkey = $dbr->strencode( $title->getDBkey() );
@@ -759,7 +759,7 @@ class Article {
                $won = wfInvertTimestamp( $now );
                wfSeedRandom();
                $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
 
                $cur_id = $dbw->nextSequenceValue( 'cur_cur_id_seq' ); 
 
@@ -903,7 +903,7 @@ class Article {
                else { $redir = 0; }
 
                $text = $this->preSaveTransform( $text );
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
 
                # Update article, but only if changed.
 
@@ -1029,7 +1029,9 @@ class Article {
                global $wgMwRedir;
 
                $wgLinkCache = new LinkCache();
-
+               # Select for update
+               $wgLinkCache->forUpdate( true );
+               
                # Get old version of link table to allow incremental link updates
                $wgLinkCache->preFill( $this->mTitle );
                $wgLinkCache->clear();
@@ -1110,7 +1112,7 @@ class Article {
                $reason = $wgRequest->getText( 'wpReasonProtect' );
 
                if ( $confirm ) {
-                       $dbw =& wfGetDB( DB_WRITE );
+                       $dbw =& wfGetDB( DB_MASTER );
                        $dbw->updateArray( 'cur', 
                                array( /* SET */
                                        'cur_touched' => wfTimestampNow(),
@@ -1240,7 +1242,7 @@ class Article {
                # determine whether this page has earlier revisions
                # and insert a warning if it does
                # we select the text because it might be useful below
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $ns = $this->mTitle->getNamespace();
                $title = $this->mTitle->getDBkey();
                $old = $dbr->getArray( 'old', 
@@ -1402,7 +1404,7 @@ class Article {
                $fname = 'Article::doDeleteArticle';
                wfDebug( $fname."\n" );
                
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $ns = $this->mTitle->getNamespace();
                $t = $this->mTitle->getDBkey();
                $id = $this->mTitle->getArticleID();
@@ -1527,7 +1529,7 @@ class Article {
                        $wgOut->readOnlyPage( $this->getContent( true ) );
                        return;
                }
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
 
                # Enhanced rollback, marks edits rc_bot=1
                $bot = $wgRequest->getBool( 'bot' );
@@ -1633,7 +1635,7 @@ class Article {
                
                wfSeedRandom();
                if ( 0 == mt_rand( 0, 999 ) ) {
-                       $dbw =& wfGetDB( DB_WRITE );
+                       $dbw =& wfGetDB( DB_MASTER );
                        $cutoff = wfUnix2Timestamp( time() - ( 7 * 86400 ) );
                        $sql = "DELETE FROM recentchanges WHERE rc_timestamp < '{$cutoff}'";
                        $dbw->query( $sql );
@@ -1733,8 +1735,10 @@ class Article {
 
        # Loads cur_touched and returns a value indicating if it should be used
        function checkTouched() {
+               $fname = 'Article::checkTouched';
+
                $id = $this->getID();
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $s = $dbr->getArray( 'cur', array( 'cur_touched', 'cur_is_redirect' ), 
                        array( 'cur_id' => $id ), $fname );
                if( $s !== false ) {
@@ -1751,7 +1755,7 @@ class Article {
                $fname = 'Article::quickEdit';
                wfProfileIn( $fname );
 
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $ns = $this->mTitle->getNamespace();
                $dbkey = $this->mTitle->getDBkey();
                $encDbKey = $dbw->strencode( $dbkey );
@@ -1810,7 +1814,7 @@ class Article {
                $id = intval( $id );
                global $wgHitcounterUpdateFreq;
 
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $curTable = $dbw->tableName( 'cur' );
                $hitcounterTable = $dbw->tableName( 'hitcounter' );
                $acchitsTable = $dbw->tableName( 'acchits' );
@@ -1894,31 +1898,32 @@ class Article {
        function info()
        {
                global $wgUser, $wgTitle, $wgOut, $wgLang, $wgAllowPageInfo;
-
+               $fname = 'Article::info';
+       
                if ( !$wgAllowPageInfo ) {
                        $wgOut->errorpage( "nosuchaction", "nosuchactiontext" );
                        return;
                }
+               
+               $dbr =& wfGetDB( DB_SLAVE );
 
                $basenamespace = $wgTitle->getNamespace() & (~1);
-               $cur_clause = "cur_title='".$wgTitle->getDBkey()."' AND cur_namespace=".$basenamespace;
-               $old_clause = "old_title='".$wgTitle->getDBkey()."' AND old_namespace=".$basenamespace;
-               $wl_clause  =  "wl_title='".$wgTitle->getDBkey()."' AND  wl_namespace=".$basenamespace;
+               $cur_clause = array( 'cur_title' => $wgTitle->getDBkey(), 'cur_namespace' => $basenamespace );
+               $old_clause = array( 'old_title' => $wgTitle->getDBkey(), 'old_namespace' => $basenamespace );
+               $wl_clause  = array( 'wl_title' => $wgTitle->getDBkey(), 'wl_namespace' => $basenamespace );
                $fullTitle = $wgTitle->makeName($basenamespace, $wgTitle->getDBKey());
                $wgOut->setPagetitle(  $fullTitle );
                $wgOut->setSubtitle( wfMsg( "infosubtitle" ));
 
                # first, see if the page exists at all.
-               $sql = "SELECT COUNT(*) FROM cur WHERE ".$cur_clause;
-               $exists = wfSingleQuery( $sql , DB_READ );
+               $exists = $dbr->selectField( 'cur', 'COUNT(*)', $cur_clause, $fname );
                if ($exists < 1) {
                        $wgOut->addHTML( wfMsg("noarticletext") );
                } else {
-                       $sql = "SELECT COUNT(*) FROM watchlist WHERE ".$wl_clause;
-                       $wgOut->addHTML( "<ul><li>" . wfMsg("numwatchers") . wfSingleQuery( $sql, DB_READ ) . "</li>" );
-                       $sql = "SELECT COUNT(*) FROM old WHERE ".$old_clause;
-                       $old = wfSingleQuery( $sql, DB_READ );
-                       $wgOut->addHTML( "<li>" . wfMsg("numedits") . ($old + 1) . "</li>");
+                       $numwatchers = $dbr->selectField( 'watchlist', 'COUNT(*)', $wl_clause, $fname );
+                       $wgOut->addHTML( "<ul><li>" . wfMsg("numwatchers", $numwatchers) . "</li>" );
+                       $old = $dbr->selectField( 'old', 'COUNT(*)', $old_clause, $fname );
+                       $wgOut->addHTML( "<li>" . wfMsg("numedits", $old + 1) . "</li>");
 
                        # to find number of distinct authors, we need to do some
                        # funny stuff because of the cur/old table split:
@@ -1926,40 +1931,33 @@ class Article {
                        # - then, find the number of *other* authors in 'old'
 
                        # find 'cur' author
-                       $sql = "SELECT cur_user_text FROM cur WHERE ".$cur_clause;
-                       $cur_author = wfSingleQuery( $sql, DB_READ );
+                       $cur_author = $dbr->selectField( 'cur', 'cur_user_text', $cur_clause, $fname );
 
                        # find number of 'old' authors excluding 'cur' author
-                       $sql = "SELECT COUNT(DISTINCT old_user_text) FROM old WHERE ".$old_clause
-                                       ." AND old_user_text<>'" . $cur_author . "'";
-                       $authors = wfSingleQuery( $sql, DB_READ ) + 1;
+                       $authors = $dbr->selectField( 'old', 'COUNT(DISTINCT old_user_text)', 
+                               $old_clause + array( 'old_user_text<>' . $dbr->addQuotes( $cur_author ) ), $fname ) + 1;
 
                        # now for the Talk page ...
-                       $cur_clause = "cur_title='".$wgTitle->getDBkey()."' AND cur_namespace=".($basenamespace+1);
-                       $old_clause = "old_title='".$wgTitle->getDBkey()."' AND old_namespace=".($basenamespace+1);
+                       $cur_clause = array( 'cur_title' => $wgTitle->getDBkey(), 'cur_namespace' => $basenamespace+1 );
+                       $old_clause = array( 'old_title' => $wgTitle->getDBkey(), 'old_namespace' => $basenamespace+1 );
 
                        # does it exist?
-                       $sql = "SELECT COUNT(*) FROM cur WHERE ".$cur_clause;
-                       $exists = wfSingleQuery( $sql , DB_READ );
+                       $exists = $dbr->selectField( 'cur', 'COUNT(*)', $cur_clause, $fname );
 
                        # number of edits
                        if ($exists > 0) {
-                               $sql = "SELECT COUNT(*) FROM old WHERE ".$old_clause;
-                               $old = wfSingleQuery( $sql, DB_READ );
-                               $wgOut->addHTML( "<li>" . wfMsg("numtalkedits") . ($old + 1) . "</li>");
+                               $old = $dbr->selectField( 'old', 'COUNT(*)', $old_clause, $fname );
+                               $wgOut->addHTML( "<li>" . wfMsg("numtalkedits", $old + 1) . "</li>");
                        }
-                       $wgOut->addHTML( "<li>" . wfMsg("numauthors") . $authors . "</li>" );
+                       $wgOut->addHTML( "<li>" . wfMsg("numauthors", $authors) . "</li>" );
 
                        # number of authors
                        if ($exists > 0) {
-                               $sql = "SELECT cur_user_text FROM cur WHERE ".$cur_clause;
-                               $cur_author = wfSingleQuery( $sql, DB_READ );
-
-                               $sql = "SELECT COUNT(DISTINCT old_user_text) FROM old WHERE "
-                                               .$old_clause." AND old_user_text<>'" . $cur_author . "'";
-                               $authors = wfSingleQuery( $sql, DB_READ ) + 1;
+                               $cur_author = $dbr->selectField( 'cur', 'cur_user_text', $cur_clause, $fname );
+                               $authors = $dbr->selectField( 'cur', 'COUNT(DISTINCT old_user_text)', 
+                                       $old_clause + array( 'old_user_text<>' . $dbr->addQuotes( $cur_author ) ), $fname );
 
-                               $wgOut->addHTML( "<li>" . wfMsg("numtalkauthors") . $authors . "</li></ul>" );
+                               $wgOut->addHTML( "<li>" . wfMsg("numtalkauthors", $authors) . "</li></ul>" );
                        }
                }
        }
index 80b102a..427fda2 100644 (file)
@@ -49,7 +49,7 @@ class Block
 
                $ret = false;
                $killed = false;
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $ipblocks = $dbr->tableName( 'ipblocks' );
 
                if ( 0 == $user && $address=="" ) {
@@ -132,14 +132,14 @@ class Block
        # Callback with a Block object for every block
        /*static*/ function enumBlocks( $callback, $tag, $killExpired = true ) 
        {
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $ipblocks = $dbr->tableName( 'ipblocks' );
                
                $sql = "SELECT * FROM $ipblocks ORDER BY ipb_timestamp DESC";
                $res = $dbr->query( $sql, 'Block::enumBans' );
                $block = new Block();
 
-               while ( $row = wfFetchObject( $res ) ) {
+               while ( $row = $dbr->fetchObject( $res ) ) {
                        $block->initFromRow( $row );
                        if ( $killExpired ) {
                                if ( !$block->deleteIfExpired() ) {
@@ -155,7 +155,7 @@ class Block
        function delete() 
        {
                $fname = 'Block::delete';
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
 
                if ( $this->mAddress == "" ) {
                        $condition = array( 'ipb_id' => $this->mId );
@@ -168,7 +168,7 @@ class Block
 
        function insert() 
        {
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $dbw->insertArray( 'ipblocks',
                        array(
                                'ipb_address' => $this->mAddress,
@@ -214,7 +214,7 @@ class Block
                        $this->mTimestamp = wfTimestampNow();
                        $this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
 
-                       $dbw =& wfGetDB( DB_WRITE );
+                       $dbw =& wfGetDB( DB_MASTER );
                        $dbw->updateArray( 'ipblocks', 
                                array( /* SET */ 
                                        'ipb_timestamp' => $this->mTimestamp,
index d101ccc..3ba8998 100644 (file)
@@ -9,6 +9,13 @@ define( "LIST_COMMA", 0 );
 define( "LIST_AND", 1 );
 define( "LIST_SET", 2 );
 
+# Number of times to re-try an operation in case of deadlock
+define( "DEADLOCK_TRIES", 4 );
+# Minimum time to wait before retry, in microseconds
+define( "DEADLOCK_DELAY_MIN", 500000 );
+# Maximum time to wait before retry
+define( "DEADLOCK_DELAY_MAX", 1500000 );
+
 class Database {
 
 #------------------------------------------------------------------------------
@@ -22,6 +29,7 @@ class Database {
        /* private */ var $mOut, $mDebug, $mOpened = false;
        
        /* private */ var $mFailFunction; 
+       /* private */ var $mTablePrefix;
 
 #------------------------------------------------------------------------------
 # Accessors
@@ -61,9 +69,10 @@ class Database {
 #------------------------------------------------------------------------------
 
        function Database( $server = false, $user = false, $password = false, $dbName = false, 
-               $failFunction = false, $debug = false, $bufferResults = true, $ignoreErrors = false )
+               $failFunction = false, $debug = false, $bufferResults = true, $ignoreErrors = false,
+               $tablePrefix = 'get from global' )
        {
-               global $wgOut;
+               global $wgOut, $wgDBprefix;
                # Can't get a reference if it hasn't been set yet
                if ( !isset( $wgOut ) ) {
                        $wgOut = NULL;
@@ -74,6 +83,12 @@ class Database {
                $this->mIgnoreErrors = $ignoreErrors;
                $this->mDebug = $debug;
                $this->mBufferResults = $bufferResults;
+               if ( $tablePrefix == 'get from global' ) {
+                       $this->mTablePrefix = $wgDBprefix;
+               } else {
+                       $this->mTablePrefix = $tablePrefix;
+               }
+
                if ( $server ) {
                        $this->open( $server, $user, $password, $dbName );
                }
@@ -188,29 +203,7 @@ class Database {
                }
        
                if ( false === $ret ) {
-                       # Ignore errors during error handling to avoid infinite recursion
-                       $ignore = $this->setIgnoreErrors( true );
-
-                       $error = mysql_error( $this->mConn );
-                       $errno = mysql_errno( $this->mConn );
-                       if( $ignore || $tempIgnore ) {
-                               wfDebug("SQL ERROR (ignored): " . $error . "\n");
-                       } else {
-                               $sql1line = str_replace( "\n", "\\n", $sql );
-                               wfLogDBError("$fname\t$errno\t$error\t$sql1line\n");
-                               wfDebug("SQL ERROR: " . $error . "\n");
-                               if ( $wgCommandLineMode ) {
-                                       wfDebugDieBacktrace( "A database error has occurred\n" .
-                                         "Query: $sql\n" .
-                                         "Function: $fname\n" .
-                                         "Error: $errno $error\n"
-                                       );
-                               } elseif ( $this->mOut ) {
-                                       // this calls wfAbruptExit()
-                                       $this->mOut->databaseError( $fname, $sql, $error, $errno );                             
-                               }
-                       }
-                       $this->setIgnoreErrors( $ignore );
+                       $this->reportQueryError( mysql_error(), mysql_errno(), $sql, $fname, $tempIgnore );
                }
                
                if ( $wgProfiling ) {
@@ -219,6 +212,34 @@ class Database {
                return $ret;
        }
        
+       function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
+               global $wgCommandLineMode, $wgFullyInitialised;
+               # Ignore errors during error handling to avoid infinite recursion
+               $ignore = $this->setIgnoreErrors( true );
+
+               if( $ignore || $tempIgnore ) {
+                       wfDebug("SQL ERROR (ignored): " . $error . "\n");
+               } else {
+                       $sql1line = str_replace( "\n", "\\n", $sql );
+                       wfLogDBError("$fname\t$errno\t$error\t$sql1line\n");
+                       wfDebug("SQL ERROR: " . $error . "\n");
+                       if ( $wgCommandLineMode || !$this->mOut || empty( $wgFullyInitialised ) ) {
+                               $message = "A database error has occurred\n" .
+                                 "Query: $sql\n" .
+                                 "Function: $fname\n" .
+                                 "Error: $errno $error\n";
+                               if ( !$wgCommandLineMode ) {    
+                                       $message = nl2br( $message );
+                               }
+                               wfDebugDieBacktrace( $message );
+                       } else {
+                               // this calls wfAbruptExit()
+                               $this->mOut->databaseError( $fname, $sql, $error, $errno );                             
+                       }
+               }
+               $this->setIgnoreErrors( $ignore );
+       }
+
        function freeResult( $res ) {
                if ( !@mysql_free_result( $res ) ) {
                        wfDebugDieBacktrace( "Unable to free MySQL result\n" );
@@ -263,41 +284,39 @@ class Database {
        {
                $table = $this->tableName( $table );
                $sql = "UPDATE $table SET $var = '" .
-                 wfStrencode( $value ) . "' WHERE ($cond)";
-               return !!$this->query( $sql, DB_WRITE, $fname );
+                 $this->strencode( $value ) . "' WHERE ($cond)";
+               return !!$this->query( $sql, DB_MASTER, $fname );
        }
        
+       function getField( $table, $var, $cond, $fname = "Database::get", $options = array() ) {
+               return $this->selectField( $table, $var, $cond, $fname = "Database::get", $options = array() );
+       }
+
        # Simple SELECT wrapper, returns a single field, input must be encoded
        # Usually aborts on failure
        # If errors are explicitly ignored, returns FALSE on failure
-       function getField( $table, $var, $cond, $fname = "Database::get" )
+       function selectField( $table, $var, $cond, $fname = "Database::selectField", $options = array() )
        {
-               $table = $this->tableName( $table );
-               $from = $table?" FROM $table ":"";
-               if ( is_array( $cond ) ) {
-                       $where = ' WHERE ' . $this->makeList( $cond, LIST_AND );
-               } elseif ( $cond ) {
-                       $where = " WHERE ($cond)";
-               } else {
-                       $where = '';
+               if ( !is_array( $options ) ) {
+                       $options = array( $options );
                }
-               $sql = "SELECT $var $from $where LIMIT 1";
-               $result = $this->query( $sql, $fname );
-       
-               $ret = false;
-               if ( $this->numRows( $result ) > 0 ) {
-                       $s = $this->fetchRow( $result );
-                       $ret = $s[0];
-                       $this->freeResult( $result );
+               $options['LIMIT'] = 1;
+
+               $res = $this->select( $table, $var, $cond, $fname, $options );
+               if ( $res === false || !$this->numRows( $res ) ) {
+                       return false;
+               }
+               $row = $this->fetchRow( $res );
+               if ( $row !== false ) {
+                       $this->freeResult( $res );
+                       return $row[0];
+               } else {
+                       return false;
                }
-               return $ret;
        }
        
-       # SELECT wrapper
-       function select( $table, $vars, $conds, $fname = "Database::select", $options = array() )
-       {
-               $vars = implode( ",", $vars );
-               $table = $this->tableName( $table );
+       # Returns an optional USE INDEX clause to go after the table, and a string to go at the end of the query
+       function makeSelectOptions( $options ) {
                if ( !is_array( $options ) ) {
                        $options = array( $options );
                }
@@ -324,16 +343,33 @@ class Database {
                } else {
                        $useIndex = '';
                }
+               return array( $useIndex, $tailOpts );
+       }
 
+       # SELECT wrapper
+       function select( $table, $vars, $conds, $fname = "Database::select", $options = array() )
+       {
+               if ( is_array( $vars ) ) {
+                       $vars = implode( ",", $vars );
+               }
+               $table = $this->tableName( $table );
+               list( $useIndex, $tailOpts ) = $this->makeSelectOptions( $options );
+               
                if ( $conds !== false ) {
-                       $where = $this->makeList( $conds, LIST_AND );
-                       $sql = "SELECT $vars FROM $table $useIndex WHERE $where $tailOpts";
+                       if ( is_array( $conds ) ) {
+                               $conds = $this->makeList( $conds, LIST_AND );
+                       }
+                       $sql = "SELECT $vars FROM $table $useIndex WHERE $conds $tailOpts";
                } else {
                        $sql = "SELECT $vars FROM $table $useIndex $tailOpts";
                }
                return $this->query( $sql, $fname );
        }
        
+       function getArray( $table, $vars, $conds, $fname = "Database::getArray", $options = array() ) {
+               return $this->selectRow( $table, $vars, $conds, $fname, $options );
+       }
+       
        # Single row SELECT wrapper
        # Aborts or returns FALSE on error
        #
@@ -341,9 +377,9 @@ class Database {
        # $conds: a condition map, terms are ANDed together. 
        #    Items with numeric keys are taken to be literal conditions
        # Takes an array of selected variables, and a condition map, which is ANDed
-       # e.g. getArray( "cur", array( "cur_id" ), array( "cur_namespace" => 0, "cur_title" => "Astronomy" ) )
+       # e.g. selectRow( "cur", array( "cur_id" ), array( "cur_namespace" => 0, "cur_title" => "Astronomy" ) )
        #   would return an object where $obj->cur_id is the ID of the Astronomy article
-       function getArray( $table, $vars, $conds, $fname = "Database::getArray", $options = array() ) {
+       function selectRow( $table, $vars, $conds, $fname = "Database::selectRow", $options = array() ) {
                $options['LIMIT'] = 1;
                $res = $this->select( $table, $vars, $conds, $fname, $options );
                if ( $res === false || !$this->numRows( $res ) ) {
@@ -384,7 +420,7 @@ class Database {
        function fieldExists( $table, $field, $fname = "Database::fieldExists" )
        {
                $table = $this->tableName( $table );
-               $res = $this->query( "DESCRIBE $table", DB_READ, $fname );
+               $res = $this->query( "DESCRIBE $table", DB_SLAVE, $fname );
                if ( !$res ) {
                        return NULL;
                }
@@ -459,6 +495,22 @@ class Database {
                }
                return false;
        }
+       
+       function fieldType( $res, $index ) {
+               return mysql_field_type( $res, $index );
+       }
+
+       function indexUnique( $table, $index ) {
+               $indexInfo = $this->indexInfo( $table, $index );
+               if ( !$indexInfo ) {
+                       return NULL;
+               }
+               return !$indexInfo->Non_unique;
+       }
+
+       function insertArray( $table, $a, $fname = "Database::insertArray", $options = array() ) {
+               return $this->insert( $table, $a, $fname = "Database::insertArray", $options = array() );
+       }
 
        # INSERT wrapper, inserts an array into a table
        #
@@ -467,9 +519,12 @@ class Database {
        #
        # Usually aborts on failure
        # If errors are explicitly ignored, returns success
-       function insertArray( $table, $a, $fname = "Database::insertArray", $options = array() )
+       function insert( $table, $a, $fname = "Database::insert", $options = array() )
        {
                $table = $this->tableName( $table );
+               if ( !is_array( $options ) ) {
+                       $options = array( $options );
+               }
                if ( isset( $a[0] ) && is_array( $a[0] ) ) {
                        $multi = true;
                        $keys = array_keys( $a[0] );
@@ -496,9 +551,13 @@ class Database {
                }
                return !!$this->query( $sql, $fname );
        }
+
+       function updateArray( $table, $values, $conds, $fname = "Database::updateArray" ) {
+               return $this->update( $table, $values, $conds, $fname );
+       }
        
        # UPDATE wrapper, takes a condition array and a SET array
-       function updateArray( $table, $values, $conds, $fname = "Database::updateArray" )
+       function update( $table, $values, $conds, $fname = "Database::update" )
        {
                $table = $this->tableName( $table );
                $sql = "UPDATE $table SET " . $this->makeList( $values, LIST_SET );
@@ -559,9 +618,23 @@ class Database {
        }
 
        function tableName( $name ) {
+               if ( $this->mTablePrefix !== '' ) {
+                       if ( strpos( '.', $name ) === false ) {
+                               $name = $this->mTablePrefix . $name;
+                       }
+               }
                return $name;
        }
 
+       function tableNames() {
+               $inArray = func_get_args();
+               $retVal = array();
+               foreach ( $inArray as $name ) {
+                       $retVal[$name] = $this->tableName( $name );
+               }
+               return $retVal;
+       }
+       
        function strencode( $s ) {
                return addslashes( $s );
        }
@@ -653,7 +726,7 @@ class Database {
                $table = $this->tableName( $table );
                $sql = "SHOW COLUMNS FROM $table LIKE \"$field\";";
                $res = $this->query( $sql, "Database::textFieldSize" );
-               $row = wfFetchObject( $res );
+               $row = $this->fetchObject( $res );
                $this->freeResult( $res );
 
                if ( preg_match( "/\((.*)\)/", $row->Type, $m ) ) {
@@ -700,6 +773,84 @@ class Database {
        function limitResult($limit,$offset) {
                return " LIMIT ".(is_numeric($offset)?"{$offset},":"")."{$limit} ";
        }
+
+       function wasDeadlock() {
+               return $this->lastErrno() == 1213;
+       }
+
+       function deadlockLoop() {
+               $myFname = 'Database::deadlockLoop';
+               
+               $this->query( "BEGIN", $myFname );
+               $args = func_get_args();
+               $function = array_shift( $args );
+               $oldIgnore = $dbw->setIgnoreErrors( true );
+               $tries = DEADLOCK_TRIES;
+               if ( is_array( $function ) ) {
+                       $fname = $function[0];
+               } else {
+                       $fname = $function;
+               }
+               do {
+                       $retVal = call_user_func_array( $function, $args );
+                       $error = $this->lastError();
+                       $errno = $this->lastErrno();
+                       $sql = $this->lastQuery();
+                       
+                       if ( $errno ) {
+                               if ( $dbw->wasDeadlock() ) {
+                                       # Retry
+                                       usleep( mt_rand( DEADLOCK_DELAY_MIN, DEADLOCK_DELAY_MAX ) );
+                               } else {
+                                       $dbw->reportQueryError( $error, $errno, $sql, $fname );
+                               }
+                       }
+               } while( $dbw->wasDeadlock && --$tries > 0 );
+               $this->setIgnoreErrors( $oldIgnore );
+               if ( $tries <= 0 ) {
+                       $this->query( "ROLLBACK", $myFname );
+                       $this->reportQueryError( $error, $errno, $sql, $fname );
+                       return false;
+               } else {
+                       $this->query( "COMMIT", $myFname );
+                       return $retVal;
+               }
+       }
+
+       # Do a SELECT MASTER_POS_WAIT()
+       function masterPosWait( $file, $pos ) {
+               $encFile = $this->strencode( $file );
+               $sql = "SELECT MASTER_POS_WAIT('$encFile', $pos)";
+               $res = $this->query( $sql, "Database::masterPosWait" );
+               if ( $res && $row = $this->fetchRow( $res ) ) {
+                       $this->freeResult( $res );
+                       return $row[0];
+               } else {
+                       return false;
+               }
+       }
+
+       # Get the position of the master from SHOW SLAVE STATUS
+       function getSlavePos() {
+               $res = $this->query( 'SHOW SLAVE STATUS', 'Database::getSlavePos' );
+               $row = $this->fetchObject( $res );
+               if ( $row ) {
+                       return array( $row->Master_Log_File, $row->Read_Master_Log_Pos );
+               } else {
+                       return array( false, false );
+               }
+       }
+       
+       # Get the position of the master from SHOW MASTER STATUS
+       function getMasterPos() {
+               $res = $this->query( 'SHOW MASTER STATUS', 'Database::getMasterPos' );
+               $row = $this->fetchObject( $res );
+               if ( $row ) {
+                       return array( $row->File, $row->Position );
+               } else {
+                       return array( false, false );
+               }
+       }
 } 
 
 class DatabaseMysql extends Database {
index c5f1b6d..43594a3 100644 (file)
@@ -3,11 +3,6 @@
 
 # Backwards compatibility wrapper for Database.php
 
-# I imagine this file will eventually become a backwards
-# compatibility wrapper around a load balancer object, and
-# the load balancer will finally call Database, which will
-# represent a single connection
-
 # Note: $wgDatabase has ceased to exist. Destroy all references.
 
 # Usually aborts on failure
@@ -27,12 +22,13 @@ function wfQuery( $sql, $db, $fname = "" )
        }
 }
 
-function wfSingleQuery( $sql, $db, $fname = "" )
+function wfSingleQuery( $sql, $dbi, $fname = "" )
 {
-       $res = wfQuery($sql, $db, $fname );
-       $row = wfFetchRow( $res );
+       $db =& wfGetDB( $dbi );
+       $res = $db->query($sql, $fname );
+       $row = $db->fetchRow( $res );
        $ret = $row[0];
-       wfFreeResult( $res );
+       $db->freeResult( $res );
        return $ret;
 }
 
@@ -194,7 +190,7 @@ function wfLastDBquery( $dbi = DB_LAST )
        }
 }
 
-function wfSetSQL( $table, $var, $value, $cond, $dbi = DB_WRITE )
+function wfSetSQL( $table, $var, $value, $cond, $dbi = DB_MASTER )
 {
        $db =& wfGetDB( $dbi );
        if ( $db !== false ) {
@@ -234,7 +230,7 @@ function wfIndexExists( $table, $index, $dbi = DB_LAST )
        }
 }
 
-function wfInsertArray( $table, $array, $fname = "wfInsertArray", $dbi = DB_WRITE ) 
+function wfInsertArray( $table, $array, $fname = "wfInsertArray", $dbi = DB_MASTER ) 
 {
        $db =& wfGetDB( $dbi );
        if ( $db !== false ) {
@@ -254,7 +250,7 @@ function wfGetArray( $table, $vars, $conds, $fname = "wfGetArray", $dbi = DB_LAS
        }
 }
 
-function wfUpdateArray( $table, $values, $conds, $fname = "wfUpdateArray", $dbi = DB_WRITE )
+function wfUpdateArray( $table, $values, $conds, $fname = "wfUpdateArray", $dbi = DB_MASTER )
 {
        $db =& wfGetDB( $dbi );
        if ( $db !== false ) {
@@ -284,7 +280,7 @@ function wfStrencode( $s, $dbi = DB_LAST )
        }
 }
 
-function wfNextSequenceValue( $seqName, $dbi = DB_WRITE ) {
+function wfNextSequenceValue( $seqName, $dbi = DB_MASTER ) {
        $db =& wfGetDB( $dbi );
        if ( $db !== false ) {
                return $db->nextSequenceValue( $seqName );
@@ -293,7 +289,7 @@ function wfNextSequenceValue( $seqName, $dbi = DB_WRITE ) {
        }
 }
 
-function wfUseIndexClause( $index, $dbi = DB_READ ) {
+function wfUseIndexClause( $index, $dbi = DB_SLAVE ) {
        $db =& wfGetDB( $dbi );
        if ( $db !== false ) {
                return $db->useIndexClause( $index );
index 5edaa8c..06a79aa 100644 (file)
@@ -209,14 +209,23 @@ class DatabasePgsql extends Database {
 
        function insertArray( $table, $a, $fname = "Database::insertArray", $options = array() ) {
                # PostgreSQL doesn't support options
-               # We have a go at faking some of them
+               # We have a go at faking one of them
+               # TODO: DELAYED, LOW_PRIORITY 
+
+               # IGNORE is performed using single-row inserts, ignoring errors in each
                if ( in_array( 'IGNORE', $options ) ) {
-                       $ignore = true;
+                       # FIXME: need some way to distiguish between key collision and other types of error
                        $oldIgnore = $this->setIgnoreErrors( true );
-               }
-               $retVal = parent::insertArray( $table, $a, $fname, array() );
-               if ( $ignore ) {
+                       if ( !is_array( reset( $a ) ) ) {
+                               $a = array( $a );
+                       }
+                       foreach ( $a as $row ) {
+                               parent::insertArray( $table, $row, $fname, array() );
+                       }
                        $this->setIgnoreErrors( $oldIgnore );
+                       $retVal = true;
+               } else {
+                       $retVal = parent::insertArray( $table, $a, $fname, array() );
                }
                return $retVal;
        }
@@ -273,56 +282,46 @@ class DatabasePgsql extends Database {
        function replace( $table, $uniqueIndexes, $rows, $fname = "Database::replace" ) {
                $table = $this->tableName( $table );
 
-               # Delete rows which collide
-               if ( $uniqueIndexes ) {
-                       $sql = "DELETE FROM $table WHERE (";
-                       $first = true;
-                       foreach ( $uniqueIndexes as $index ) {
-                               if ( $first ) {
-                                       $first = false;
-                               } else {
-                                       $sql .= ") OR (";
-                               }
-                               if ( is_array( $col ) ) {
-                                       $first2 = true;
-                                       $sql .= "(";
-                                       foreach ( $index as $col ) {
-                                               if ( $first2 ) { 
-                                                       $first2 = false;
-                                               } else {
-                                                       $sql .= " AND ";
-                                               }
-                                               //midom: atleast unbreak the class (remove syntax errors)
-                                               //$sql .= "$col = " $this->strencode;
+               # Single row case
+               if ( !is_array( reset( $rows ) ) ) {
+                       $rows = array( $rows );
+               }
+
+               foreach( $rows as $row ) {
+                       # Delete rows which collide
+                       if ( $uniqueIndexes ) {
+                               $sql = "DELETE FROM $table WHERE (";
+                               $first = true;
+                               foreach ( $uniqueIndexes as $index ) {
+                                       if ( $first ) {
+                                               $first = false;
+                                       } else {
+                                               $sql .= ") OR (";
                                        }
-                               }
-                               if ( $first ) {
-                                       $first = false;
+                                       if ( is_array( $index ) ) {
+                                               $first2 = true;
+                                               $sql .= "(";
+                                               foreach ( $index as $col ) {
+                                                       if ( $first2 ) { 
+                                                               $first2 = false;
+                                                       } else {
+                                                               $sql .= " AND ";
+                                                       }
+                                                       $sql .= "$col=" . $this->addQuotes( $row[$col] )
+                                               }
                                } else {
-                                       $sql .= "OR ";
+                                               $sql .= "$index=" . $this->addQuotes( $row[$index] );
                                }
-                               $sql .= "$col IN (";
-                               $indexValues = array();
-                               foreach ( $rows as $row ) {
-                                       $indexValues[] = $row[$col];
                                }
-                               $sql .= $this->makeList( $indexValues, LIST_COMMA ) . ") ";
+                               $sql .= ")";
+                               $this->query( $sql, $fname );
                        }
-                       $this->query( $sql, $fname );
-               }
 
-               # Now insert the rows
-               $sql = "INSERT INTO $table (" . $this->makeList( array_flip( $rows[0] ) ) .") VALUES ";
-               $first = true;
-               foreach ( $rows as $row ) {
-                       if ( $first ) {
-                               $first = false;
-                       } else {
-                               $sql .= ",";
-                       }
-                       $sql .= "(" . $this->makeList( $row, LIST_COMMA ) . ")";
+                       # Now insert the row
+                       $sql = "INSERT INTO $table (" . $this->makeList( array_flip( $row ) ) .') VALUES (' .
+                               $this->makeList( $row, LIST_COMMA ) . ')';
+                       $this->query( $sql, $fname );
                }
-               $this->query( $sql, $fname );
        }
 
        # DELETE where the condition is a join
@@ -358,6 +357,11 @@ class DatabasePgsql extends Database {
        function limitResult($limit,$offset) {
                return " LIMIT $limit ".(is_numeric($offset)?" OFFSET {$offset} ":"");
        }
+
+       # FIXME: actually detecting deadlocks might be nice
+       function wasDeadlock() {
+               return false;
+       }
 }
 
 # Just an alias.
index aa7f853..eb9c1d1 100644 (file)
@@ -59,6 +59,7 @@ $wgDBname           = 'wikidb';
 $wgDBconnection     = '';
 $wgDBuser           = 'wikiuser';
 $wgDBtype           = "mysql"; # "mysql" for working code and "PostgreSQL" for development/broken code
+$wgDBprefix         = ''; # Table name prefix
 
 # Database load balancer
 # This is a two-dimensional array, an array of server info structures
@@ -68,7 +69,7 @@ $wgDBtype           = "mysql"; # "mysql" for working code and "PostgreSQL" for d
 #   user:      DB user
 #   password:  DB password
 #   type:      "mysql" or "pgsql"
-#   load:      ratio of DB_READ load, must be >=0, the sum of all loads must be >0
+#   load:      ratio of DB_SLAVE load, must be >=0, the sum of all loads must be >0
 # Leave at false to use the single-server variables above
 $wgDBservers           = false; 
 
index 30d369e..df68822 100644 (file)
@@ -121,7 +121,7 @@ cellpadding='0' cellspacing='4px' class='diff'><tr>
                global $wgTitle, $wgOut, $wgLang;
                $fname = "DifferenceEngine::loadText";
                
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                if ( 0 == $this->mNewid || 0 == $this->mOldid ) {
                        $wgOut->setArticleFlag( true );
                        $this->mNewtitle = wfMsg( "currentrev" );
index cb2be1b..8ec9c17 100644 (file)
@@ -543,7 +543,7 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
        /* private */ function mergeChangesInto( &$text ){
                $fname = 'EditPage::mergeChangesInto';
                $oldDate = $this->edittime;
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $obj = $dbr->getArray( 'cur', array( 'cur_text' ), array( 'cur_id' => $this->mTitle->getArticleID() ), 
                        $fname, 'FOR UPDATE' );
 
index a72e849..a00ba73 100644 (file)
@@ -63,11 +63,13 @@ function do_html_entity_decode( $string, $quote_style=ENT_COMPAT, $charset='ISO-
 
 $wgRandomSeeded = false;
 
+# Seed Mersenne Twister
+# Only necessary in PHP < 4.2.0
 function wfSeedRandom()
 {
        global $wgRandomSeeded;
 
-       if ( ! $wgRandomSeeded ) {
+       if ( ! $wgRandomSeeded && version_compare( phpversion(), '4.2.0' ) < 0 ) {
                $seed = hexdec(substr(md5(microtime()),-8)) & 0x7fffffff;
                mt_srand( $seed );
                $wgRandomSeeded = true;
@@ -423,7 +425,7 @@ function wfNumberOfArticles()
        $fname = 'wfLoadSiteStats';
 
        if ( -1 != $wgNumberOfArticles ) return;
-       $dbr =& wfGetDB( DB_READ );
+       $dbr =& wfGetDB( DB_SLAVE );
        $s = $dbr->getArray( 'site_stats', 
                array( 'ss_total_views', 'ss_total_edits', 'ss_good_articles' ),
                array( 'ss_row_id' => 1 ), $fname
@@ -508,11 +510,10 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
        global $wgUseCopyrightUpload; 
        
        $fname = 'wfRecordUpload';
-       $dbw =& wfGetDB( DB_WRITE );
+       $dbw =& wfGetDB( DB_MASTER );
        
        # img_name must be unique
-       $indexInfo = $dbw->indexInfo( 'image', 'img_name' );
-       if ( $indexInfo && $indexInfo->Non_unique ) {
+       if ( !$dbw->indexUnique( 'image', 'img_name' ) ) {
                wfDebugDieBacktrace( 'Database schema not up to date, please run maintenance/archives/patch-img_name_unique.sql' );
        }
                        
@@ -535,7 +536,7 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
        # Test to see if the row exists using INSERT IGNORE
        # This avoids race conditions by locking the row until the commit, and also 
        # doesn't deadlock. SELECT FOR UPDATE causes a deadlock for every race condition.
-       $dbw->insertArray( 'image', 
+       $dbw->insert( 'image', 
                array(
                        'img_name' => $name,
                        'img_size'=> $size,
@@ -545,63 +546,70 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
                        'img_user_text' => $wgUser->getName(),
                ), $fname, 'IGNORE'
        );
+       $descTitle = Title::makeTitle( NS_IMAGE, $name );
 
        if ( $dbw->affectedRows() ) {
                # Successfully inserted, this is a new image
+               $id = $descTitle->getArticleID();
                
-               $sql = 'SELECT cur_id,cur_text FROM cur WHERE cur_namespace=' .
-                 Namespace::getImage() . " AND cur_title='" .
-                 wfStrencode( $name ) . "'";
-               $res = wfQuery( $sql, DB_READ, $fname );
-               if ( 0 == wfNumRows( $res ) ) {
-                       $common =
-                         Namespace::getImage() . ",'" .
-                         wfStrencode( $name ) . "','" .
-                         wfStrencode( $desc ) . "','" . $wgUser->getID() . "','" .
-                         wfStrencode( $wgUser->getName() ) . "','" . $now .
-                         "',1";
-                       $sql = 'INSERT INTO cur (cur_namespace,cur_title,' .
-                         'cur_comment,cur_user,cur_user_text,cur_timestamp,cur_is_new,' .
-                         'cur_text,inverse_timestamp,cur_touched) VALUES (' .
-                         $common .
-                         ",'" . wfStrencode( $textdesc ) . "','{$won}','{$now}')";
-                       wfQuery( $sql, DB_WRITE, $fname );
-                       $id = wfInsertId() or 0; # We should throw an error instead
+               if ( $id == 0 ) {
+                       $seqVal = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
+                       $dbw->insertArray( 'cur', 
+                               array( 
+                                       'cur_id' => $seqVal,
+                                       'cur_namespace' => NS_IMAGE,
+                                       'cur_title' => $name,
+                                       'cur_comment' => $desc,
+                                       'cur_user' => $wgUser->getID(),
+                                       'cur_user_text' => $wgUser->getName(),
+                                       'cur_timestamp' => $now,
+                                       'cur_is_new' => 1,
+                                       'cur_text' => $textdesc,
+                                       'inverse_timestamp' => $won,
+                                       'cur_touched' => $now
+                               ), $fname
+                       );
+                       $id = $dbw->insertId() or 0; # We should throw an error instead
                        
-                       $titleObj = Title::makeTitle( NS_IMAGE, $name );
-                       RecentChange::notifyNew( $now, $titleObj, 0, $wgUser, $desc );
+                       RecentChange::notifyNew( $now, $descTitle, 0, $wgUser, $desc );
                        
                        $u = new SearchUpdate( $id, $name, $desc );
                        $u->doUpdate();
                }
        } else {
                # Collision, this is an update of an image
+               # Get current image row for update
                $s = $dbw->getArray( 'image', array( 'img_name','img_size','img_timestamp','img_description',
                  'img_user','img_user_text' ), array( 'img_name' => $name ), $fname, 'FOR UPDATE' );
-               $s = wfFetchObject( $res );
-
-               $sql = 'INSERT INTO oldimage (oi_name,oi_archive_name,oi_size,' .
-                 "oi_timestamp,oi_description,oi_user,oi_user_text) VALUES ('" .
-                 wfStrencode( $s->img_name ) . "','" .
-                 wfStrencode( $oldver ) .
-                 "',{$s->img_size},'{$s->img_timestamp}','" .
-                 wfStrencode( $s->img_description ) . "','" .
-                 wfStrencode( $s->img_user ) . "','" .
-                 wfStrencode( $s->img_user_text) . "')";
-               wfQuery( $sql, DB_WRITE, $fname );
-
-               $sql = "UPDATE image SET img_size={$size}," .
-                 "img_timestamp='" . wfTimestampNow() . "',img_user='" .
-                 $wgUser->getID() . "',img_user_text='" .
-                 wfStrencode( $wgUser->getName() ) . "', img_description='" .
-                 wfStrencode( $desc ) . "' WHERE img_name='" .
-                 wfStrencode( $name ) . "'";
-               wfQuery( $sql, DB_WRITE, $fname );
+
+               # Insert it into oldimage
+               $dbw->insertArray( 'oldimage',
+                       array(
+                               'oi_name' => $s->img_name,
+                               'oi_archive_name' => $oldver,
+                               'oi_size' => $s->img_size,
+                               'oi_timestamp' => $s->img_timestamp,
+                               'oi_description' => $s->img_description,
+                               'oi_user' => $s->img_user,
+                               'oi_user_text' => $s->img_user_text
+                       ), $fname
+               );
+               
+               # Update the current image row
+               $dbw->updateArray( 'image', 
+                       array( /* SET */
+                               'img_size' => $size,
+                               'img_timestamp' => wfTimestampNow(),
+                               'img_user' => $wgUser->getID(),
+                               'img_user_text' => $wgUser->getName(),
+                               'img_description' => $desc,
+                       ), array( /* WHERE */
+                               'img_name' => $name
+                       ), $fname
+               );
                
-               $sql = "UPDATE cur SET cur_touched='{$now}' WHERE cur_namespace=" .
-                 Namespace::getImage() . " AND cur_title='" .
-                 wfStrencode( $name ) . "'";
-               wfQuery( $sql, DB_WRITE, $fname );
+               # Invalidate the cache for the description page
+               $descTitle->invalidateCache();
        }
 
        $log = new LogPage( wfMsg( 'uploadlogpage' ), wfMsg( 'uploadlogpagetext' ) );
@@ -755,10 +763,13 @@ function wfHtmlEscapeFirst( $text ) {
 }
 
 # Sets dest to source and returns the original value of dest
+# If source is NULL, it just returns the value, it doesn't set the variable
 function wfSetVar( &$dest, $source )
 {
        $temp = $dest;
-       $dest = $source;
+       if ( !is_null( $source ) ) {
+               $dest = $source;
+       }
        return $temp;
 }
 
index eb9dd8e..b35f0db 100644 (file)
@@ -261,8 +261,8 @@ class Image
        function nextHistoryLine()
        {
                $fname = "Image::nextHistoryLine()";
+               $dbr =& wfGetDB( DB_SLAVE );
                if ( $this->historyLine == 0 ) {// called for the first time, return line from cur 
-                       $dbr =& wfGetDB( DB_READ );
                        $this->historyRes = $dbr->select( 'image', 
                                array( 'img_size','img_description','img_user','img_user_text','img_timestamp', "'' AS oi_archive_name" ), 
                                array( 'img_name' => $this->title->getDBkey() ),
@@ -272,7 +272,6 @@ class Image
                                return FALSE; 
                        }
                } else if ( $this->historyLine == 1 ) {
-                       $dbr =& wfGetDB( DB_READ );
                        $this->historyRes = $dbr->select( 'oldimage', 
                                array( 'oi_size AS img_size', 'oi_description AS img_description', 'oi_user AS img_user',
                                        'oi_user_text AS img_user_text', 'oi_timestamp AS img_timestamp', 'oi_archive_name'
@@ -281,7 +280,7 @@ class Image
                }
                $this->historyLine ++;
 
-               return wfFetchObject( $this->historyRes );
+               return $dbr->fetchObject( $this->historyRes );
        }
 
        function resetHistory()
index 8073cdd..d06f06a 100644 (file)
@@ -85,13 +85,13 @@ class ImagePage extends Article {
 
                $wgOut->addHTML( "<h2>" . wfMsg( "imagelinks" ) . "</h2>\n" );
 
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $cur = $dbr->tableName( 'cur' );
                $imagelinks = $dbr->tableName( 'imagelinks' );
                
                $sql = "SELECT cur_namespace,cur_title FROM $imagelinks,$cur WHERE il_to=" .
                  $dbr->addQuotes( $this->mTitle->getDBkey() ) . " AND il_from=cur_id";
-               $res = $dbr->query( $sql, DB_READ, "Article::imageLinks" );
+               $res = $dbr->query( $sql, DB_SLAVE, "Article::imageLinks" );
 
                if ( 0 == $dbr->numRows( $res ) ) {
                        $wgOut->addHtml( "<p>" . wfMsg( "nolinkstoimage" ) . "</p>\n" );
@@ -162,7 +162,7 @@ class ImagePage extends Article {
                $image = $wgRequest->getVal( 'image' );
                $oldimage = $wgRequest->getVal( 'oldimage' );
                
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
 
                if ( !is_null( $image ) ) {
                        $dest = wfImageDir( $image );
@@ -273,7 +273,7 @@ class ImagePage extends Article {
                }
                $oldver = wfTimestampNow() . "!{$name}";
                
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $size = $dbr->getField( "oldimage", "oi_size", "oi_archive_name='" .
                  $dbr->strencode( $oldimage ) . "'" );
 
index 8dcba6f..4bb1dfe 100644 (file)
@@ -14,7 +14,8 @@ class LinkCache {
        /* private */ var $mGoodLinks, $mBadLinks, $mActive;
        /* private */ var $mImageLinks, $mCategoryLinks;
        /* private */ var $mPreFilled, $mOldGoodLinks, $mOldBadLinks;
-       
+       /* private */ var $mForUpdate;
+
        /* private */ function getKey( $title ) {
                global $wgDBname;
                return "$wgDBname:lc:title:$title";
@@ -24,6 +25,7 @@ class LinkCache {
        {
                $this->mActive = true;
                $this->mPreFilled = false;
+               $this->mForUpdate = false;
                $this->mGoodLinks = array();
                $this->mBadLinks = array();
                $this->mImageLinks = array();
@@ -32,6 +34,11 @@ class LinkCache {
                $this->mOldBadLinks = array();
        }
 
+       # General accessor to get/set whether SELECT FOR UPDATE should be used
+       function forUpdate( $update = NULL ) { 
+               return wfSetVar( $this->mForUpdate, $update );
+       }
+       
        function getGoodLinkID( $title )
        {
                if ( array_key_exists( $title, $this->mGoodLinks ) ) {
@@ -131,8 +138,15 @@ class LinkCache {
                if( $wgLinkCacheMemcached )
                        $id = $wgMemc->get( $key = $this->getKey( $title ) );
                if( ! is_integer( $id ) ) {
-                       $dbr =& wfGetDB( DB_READ );
-                       $id = $dbr->getField( 'cur', 'cur_id', array( 'cur_namespace' => $ns, 'cur_title' => $t ), $fname );
+                       if ( $this->mForUpdate ) {
+                               $db =& wfGetDB( DB_MASTER );
+                               $options = array( 'FOR UPDATE' );
+                       } else {
+                               $db =& wfGetDB( DB_SLAVE );
+                               $options = array();
+                       }
+
+                       $id = $db->getField( 'cur', 'cur_id', array( 'cur_namespace' => $ns, 'cur_title' => $t ), $fname, $options );
                        if ( !$id ) {
                                $id = 0;
                        }
@@ -170,23 +184,29 @@ class LinkCache {
                                return;
                        }
                }
+               if ( $this->mForUpdate ) {
+                       $db =& wfGetDB( DB_MASTER );
+                       $options = 'FOR UPDATE';
+               } else {
+                       $db =& wfGetDB( DB_SLAVE );
+                       $options = '';
+               }
 
-               $dbr =& wfGetDB( DB_READ );
-               $cur = $dbr->tableName( 'cur' );
-               $links = $dbr->tableName( 'links' );
+               $cur = $db->tableName( 'cur' );
+               $links = $db->tableName( 'links' );
 
                $sql = "SELECT cur_id,cur_namespace,cur_title
                        FROM $cur,$links
-                       WHERE cur_id=l_to AND l_from=$id";
-               $res = $dbr->query( $sql, $fname );
-               while( $s = $dbr->fetchObject( $res ) ) {
+                       WHERE cur_id=l_to AND l_from=$id $options";
+               $res = $db->query( $sql, $fname );
+               while( $s = $db->fetchObject( $res ) ) {
                        $this->addGoodLink( $s->cur_id,
                                Title::makeName( $s->cur_namespace, $s->cur_title )
                                );
                }
                
-               $res = $dbr->select( 'brokenlinks', array( 'bl_to' ), array( 'bl_from' => $id ), $fname );
-               while( $s = wfFetchObject( $res ) ) {
+               $res = $db->select( 'brokenlinks', array( 'bl_to' ), array( 'bl_from' => $id ), $fname, array( $options ) );
+               while( $s = $db->fetchObject( $res ) ) {
                        $this->addBadLink( $s->bl_to );
                }
                
@@ -271,9 +291,17 @@ class LinkCache {
        }
 
        /* private */ function fillFromLinkscc( $id ){ 
+               $fname = 'LinkCache::fillFromLinkscc';
+
                $id = IntVal( $id );
-               $dbr =& wfGetDB( DB_READ );
-               $raw = $dbr->getField( 'linkscc', 'lcc_cacheobj', array( 'lcc_pageid' => $id ) );
+               if ( $this->mForUpdate ) {
+                       $db =& wfGetDB( DB_MASTER );
+                       $options = 'FOR UPDATE';
+               } else {
+                       $db =& wfGetDB( DB_SLAVE );
+                       $options = '';
+               }
+               $raw = $db->getField( 'linkscc', 'lcc_cacheobj', array( 'lcc_pageid' => $id ), $fname, $options );
                if ( $raw === false ) {
                        return false;
                }
@@ -304,7 +332,7 @@ class LinkCache {
                } else {
                        $ser = serialize( $this );
                }
-               $db =& wfGetDB( DB_WRITE );
+               $db =& wfGetDB( DB_MASTER );
                $db->replace( 'linkscc', array( 'lcc_pageid' ), array( 'lcc_pageid' => $pid, 'lcc_cacheobj' => $ser ) );
        }
 
@@ -315,7 +343,7 @@ class LinkCache {
                if ( $wgEnablePersistentLC ) {
                        $fname = "LinkCache::linksccClearLinksTo";
                        $pid = intval( $pid );
-                       $dbw =& wfGetDB( DB_WRITE );
+                       $dbw =& wfGetDB( DB_MASTER );
                        # Delete linkscc rows which link to here
                        $dbw->deleteJoin( 'linkscc', 'links', 'lcc_pageid', 'l_from', array( 'l_to' => $pid ), $fname );
                        # Delete linkscc row representing this page
@@ -331,7 +359,7 @@ class LinkCache {
                $fname = 'LinkCache::linksccClearBrokenLinksTo';
 
                if ( $wgEnablePersistentLC ) {
-                       $dbw =& wfGetDB( DB_WRITE );
+                       $dbw =& wfGetDB( DB_MASTER );
                        $dbw->deleteJoin( 'linkscc', 'brokenlinks', 'lcc_pageid', 'bl_from', array( 'bl_to' => $title ), $fname );
                }
        }
@@ -341,7 +369,7 @@ class LinkCache {
                global $wgEnablePersistentLC;
                if ( $wgEnablePersistentLC ) {
                        $pid = intval( $pid );
-                       $dbw =& wfGetDB( DB_WRITE );
+                       $dbw =& wfGetDB( DB_MASTER );
                        $dbw->delete( 'linkscc', array( 'lcc_pageid' => $pid ) );
                }
        }
index 64b9aaf..31a1f48 100644 (file)
@@ -26,7 +26,7 @@ class LinksUpdate {
                $del = array();
                $add = array();
 
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $links = $dbw->tableName( 'links' );
                $brokenlinks = $dbw->tableName( 'brokenlinks' );
                $imagelinks = $dbw->tableName( 'imagelinks' );
@@ -189,7 +189,7 @@ class LinksUpdate {
                wfProfileIn( $fname );
                
                
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $links = $dbw->tableName( 'links' );
                $brokenlinks = $dbw->tableName( 'brokenlinks' );
                $imagelinks = $dbw->tableName( 'imagelinks' );
@@ -292,7 +292,7 @@ class LinksUpdate {
                /* Call for a newly created page, or just to make sure state is consistent */
                $fname = "LinksUpdate::fixBrokenLinks";
 
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $cur = $dbw->tableName( 'cur' );
                $links = $dbw->tableName( 'links' );
                
index cfc3894..00d2c1d 100644 (file)
@@ -5,10 +5,14 @@ require_once( "Database.php" );
 
 # Valid database indexes
 # Operation-based indexes
-define( "DB_READ", -1 );     # Read from the slave (or only server)
-define( "DB_WRITE", -2 );    # Write to master (or only server)
+define( "DB_SLAVE", -1 );     # Read from the slave (or only server)
+define( "DB_MASTER", -2 );    # Write to master (or only server)
 define( "DB_LAST", -3 );     # Whatever database was used last
 
+# Obsolete aliases
+define( "DB_READ", -1 );
+define( "DB_WRITE", -2 );
+
 # Task-based indexes
 # ***NOT USED YET, EXPERIMENTAL***
 # These may be defined in $wgDBservers. If they aren't, the default reader or writer will be used
@@ -20,10 +24,13 @@ define( "DB_ASKSQL_R", 1002 );    # Special:Asksql read
 define( "DB_WATCHLIST_R", 1004 ); # Watchlist read
 define( "DB_TASK_LAST", 1004) ;   # Last in list
 
+define( "MASTER_WAIT_TIMEOUT", 15 ); # Time to wait for a slave to synchronise
+
 class LoadBalancer {
        /* private */ var $mServers, $mConnections, $mLoads;
        /* private */ var $mFailFunction;
        /* private */ var $mForce, $mReadIndex, $mLastConn;
+       /* private */ var $mWaitForFile, $mWaitForPos;
 
        function LoadBalancer()
        {
@@ -52,12 +59,12 @@ class LoadBalancer {
                $this->mConnections = array();
                $this->mLastConn = false;
                $this->mLoads = array();
+               $this->mWaitForFile = false;
+               $this->mWaitForPos = false;
 
                foreach( $servers as $i => $server ) {
                        $this->mLoads[$i] = $server['load'];
                }
-
-               wfSeedRandom();
        }
        
        # Given an array of non-normalised probabilities, this function will select
@@ -119,6 +126,50 @@ class LoadBalancer {
                return $conn;
        }
 
+       # Set the master wait position
+       # If a DB_SLAVE connection has been opened already, waits
+       # Otherwise sets a variable telling it to wait if such a connection is opened
+       function waitFor( $file, $pos ) {
+               $this->mWaitForFile = false;
+               $this->mWaitForPos = false;
+
+               if ( count( $this->mServers ) == 1 ) {
+                       return;
+               }
+               
+               $this->mWaitForFile = $file;
+               $this->mWaitForPos = $pos;
+
+               if ( $this->mReadIndex > 0 ) {
+                       $this->doWait( $this->mReadIndex );
+               } 
+       }
+
+       # Wait for a given slave to catch up to the master pos stored in $this
+       function doWait( $index ) {
+               global $wgMemc;
+               
+               $key = "masterpos:" . $index;
+               $memcPos = $wgMemc->get( $key );
+               if ( $memcPos ) {
+                       list( $file, $pos ) = explode( ' ', $memcPos );
+                       # If the saved position is later than the requested position, return now
+                       if ( $file == $this->mWaitForFile && $this->mWaitForPos <= $pos ) {
+                               return;
+                       }
+               }
+
+               $conn =& $this->getConnection( $index );
+               $result = $conn->masterPosWait( $this->mWaitForFile, $this->mWaitForPos, MASTER_WAIT_TIMEOUT );
+               if ( $result == -1 ) {
+                       # Timed out waiting for slave, use master instead
+                       # This is not the ideal solution. If there are a large number of slaves, a slow
+                       # replicated write query will cause the master to be swamped with reads. However
+                       # that's a relatively graceful failure mode, so it will do for now.
+                       $this->mReadIndex = 0;
+               } 
+       }               
+
        function &getConnection( $i, $fail = false )
        {
                /*
@@ -126,18 +177,18 @@ class LoadBalancer {
                if ( $i >= DB_TASK_FIRST && $i < DB_TASK_LAST ) {
                        if ( $i % 2 ) {
                                # Odd index use writer
-                               $i = DB_WRITE;
+                               $i = DB_MASTER;
                        } else {
                                # Even index use reader
-                               $i = DB_READ;
+                               $i = DB_SLAVE;
                        }
                }*/
 
                # Operation-based index
                # Note, getReader() and getWriter() will re-enter this function
-               if ( $i == DB_READ ) {
+               if ( $i == DB_SLAVE ) {
                        $this->mLastConn =& $this->getReader();
-               } elseif ( $i == DB_WRITE ) {
+               } elseif ( $i == DB_MASTER ) {
                        $this->mLastConn =& $this->getWriter();
                } elseif ( $i == DB_LAST ) {
                        # Just use $this->mLastConn, which should already be set
@@ -147,8 +198,11 @@ class LoadBalancer {
                        }
                } else {
                        # Explicit index
-                       if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) {
+                       if ( !array_key_exists( $i, $this->mConnections ) || !$this->mConnections[$i]->isOpen() ) {
                                $this->mConnections[$i] = $this->makeConnection( $this->mServers[$i] );
+                               if ( $i != 0 && $this->mWaitForFile ) {
+                                       $this->doWait( $i );
+                               }
                        }
                        if ( !$this->mConnections[$i]->isOpen() ) {
                                wfDebug( "Failed to connect to database $i at {$this->mServers[$i]['host']}\n" );
@@ -206,4 +260,36 @@ class LoadBalancer {
        {
                return array_key_exists( $i, $this->mServers );
        }
+
+       # Get the number of defined servers (not the number of open connections)
+       function getServerCount() {
+               return count( $this->mServers );
+       }
+
+       # Save master pos to the session and to memcached, if the session exists
+       function saveMasterPos() {
+               global $wgSessionStarted;
+               if ( $wgSessionStarted && count( $this->mServers ) > 1 ) {
+                       # If this entire request was served from a slave without opening a connection to the 
+                       # master (however unlikely that may be), then we can fetch the position from the slave.
+                       if ( empty( $this->mConnections[0] ) ) {
+                               $conn =& $this->getConnection( DB_SLAVE );
+                               list( $file, $pos ) = $conn->getSlavePos();
+                       } else {
+                               $conn =& $this->getConnection( 0 );
+                               list( $file, $pos ) = $conn->getMasterPos();
+                       }
+                       if ( $file !== false ) {
+                               $_SESSION['master_log_file'] = $file;
+                               $_SESSION['master_pos'] = $pos;
+                       }
+               }
+       }
+
+       # Loads the master pos from the session, waits for it if necessary
+       function loadMasterPos() {
+               if ( isset( $_SESSION['master_log_file'] ) && isset( $_SESSION['master_pos'] ) ) {
+                       $this->waitFor( $_SESSION['master_log_file'], $_SESSION['master_pos'] );
+               }
+       }
 }
index 31f598c..1c2aa20 100644 (file)
@@ -20,7 +20,7 @@ class LogPage {
        {
                $fname = 'LogPage::getContent';
 
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $s = $dbw->getArray( 'cur', 
                        array( 'cur_id','cur_text','cur_timestamp' ),
                        array( 'cur_namespace' => Namespace::getWikipedia(), 'cur_title' => $this->mTitle ), 
@@ -56,7 +56,7 @@ class LogPage {
                global $wgUser;
                $fname = "LogPage::saveContent";
 
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $uid = $wgUser->getID();
 
                if( !$this->mContentLoaded ) return false;
index 33b8f09..697fe87 100644 (file)
@@ -84,6 +84,9 @@ class MagicWord {
        {
                global $wgMagicWords;
                
+               if ( !is_array( $wgMagicWords ) ) {
+                       wfDebugDieBacktrace( "Incorrect initialisation order, \$wgMagicWords does not exist\n" );
+               }
                if (!array_key_exists( $id, $wgMagicWords ) ) {
                        $mw = new MagicWord();
                        $mw->load( $id );
index 10ae193..8dce2b8 100644 (file)
@@ -120,7 +120,7 @@ class MathRenderer {
                
                        $md5_sql = pack("H32", $this->md5); # Binary packed, not hex
                        
-                       $dbw =& wfGetDB( DB_WRITE );
+                       $dbw =& wfGetDB( DB_MASTER );
                        $dbw->replace( 'math', array( 'math_inputhash' ),
                          array( 
                                'math_inputhash' => $md5_sql, 
@@ -149,7 +149,7 @@ class MathRenderer {
                $fname = 'MathRenderer::_recall';
 
                $this->md5 = md5( $this->tex );
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $rpage = $dbr->getArray( 'math', 
                        array( 'math_outputhash','math_html_conservativeness','math_html','math_mathml' ),
                        array( 'math_inputhash' => pack("H32", $this->md5)), # Binary packed, not hex
index a6f00f5..8b28aaf 100755 (executable)
@@ -51,16 +51,18 @@ class MessageCache
                                wfDebug( "MessageCache::load(): loading all messages\n" );
                                $this->lock();
                                # Other threads don't need to load the messages if another thread is doing it.
-                               $this->mMemc->set( $this->mMemcKey, "loading", MSG_LOAD_TIMEOUT );
-                               $this->loadFromDB();
-                               # Save in memcached
-                               # Keep trying if it fails, this is kind of important
-                               for ( $i=0; $i<20 && !$this->mMemc->set( $this->mMemcKey, $this->mCache, $this->mExpiry ); $i++ ) {
-                                       usleep(mt_rand(500000,1500000));
-                               }
-                               if ( $i == 20 ) {
-                                       $this->mMemc->set( $this->mMemcKey, "error", 86400 );
-                                       wfDebug( "MemCached set error in MessageCache: restart memcached server!\n" );
+                               $success = $this->mMemc->set( $this->mMemcKey, "loading", MSG_LOAD_TIMEOUT );
+                               if ( $success ) {
+                                       $this->loadFromDB();
+                                       # Save in memcached
+                                       # Keep trying if it fails, this is kind of important
+                                       for ( $i=0; $i<20 && !$this->mMemc->set( $this->mMemcKey, $this->mCache, $this->mExpiry ); $i++ ) {
+                                               usleep(mt_rand(500000,1500000));
+                                       }
+                                       if ( $i == 20 ) {
+                                               $this->mMemc->set( $this->mMemcKey, "error", 86400 );
+                                               wfDebug( "MemCached set error in MessageCache: restart memcached server!\n" );
+                                       }
                                }
                                $this->unlock();
                        }
@@ -90,7 +92,7 @@ class MessageCache
        function loadFromDB()
        {
                $fname = "MessageCache::loadFromDB";
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $res = $dbr->select( 'cur', 
                        array( 'cur_title', 'cur_text' ), 
                        array( 'cur_is_redirect' => 0, 'cur_namespace' => NS_MEDIAWIKI ),
@@ -181,7 +183,7 @@ class MessageCache
                        
                        # If it wasn't in the cache, load each message from the DB individually
                        if ( !$message && $useDB) {
-                               $dbr =& wfGetDB( DB_READ );
+                               $dbr =& wfGetDB( DB_SLAVE );
                                $result = $dbr->getArray( "cur", array("cur_text"), 
                                  array( "cur_namespace" => NS_MEDIAWIKI, "cur_title" => $title ),
                                  "MessageCache::get" );
index 5bcfde7..18705d0 100644 (file)
@@ -285,19 +285,19 @@ class /* abstract */ SqlBagOStuff extends BagOStuff {
 
 class MediaWikiBagOStuff extends SqlBagOStuff {
        function _doquery($sql) {
-               $dbw = wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                return $dbw->query($sql, "MediaWikiBagOStuff:_doquery");
        }
        function _fetchobject($result) {
-               $dbw = wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                return $dbw->fetchObject($result);
        }
        function _freeresult($result) {
-               $dbw = wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                return $dbw->freeResult($result);
        }
        function _dberror($result) {
-               $dbw = wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                return $dbw->lastError();
        }
        function _maxdatetime() {
@@ -307,7 +307,7 @@ class MediaWikiBagOStuff extends SqlBagOStuff {
                return gmdate( "Y-m-d H:i:s", $ts );
        }
        function _strencode($s) {
-               $dbw = wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                return $dbw->strencode($s);
        }
 }
index fb66267..5f6fc1e 100644 (file)
@@ -10,7 +10,7 @@ class OutputPage {
        var $mSubtitle, $mRedirect;
        var $mLastModified, $mCategoryLinks;
        var $mScripts;
-
+       
        var $mSuppressQuickbar;
        var $mOnloadHandler;
        var $mDoNothing;
@@ -345,8 +345,11 @@ class OutputPage {
 
 
                $this->sendCacheControl();
-               
+               # Perform link colouring
                $this->mBodytext = $this->parseLinkHolders();
+               
+               # Disable temporary placeholders, so that the skin produces HTML
+               $sk->postParseLinkColour( false );
 
                header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" );
                header( "Content-language: {$wgLanguageCode}" );
@@ -753,40 +756,45 @@ class OutputPage {
                }
                # FIXME: get these working
                # $fix = htmlspecialchars( $wgStylePath . "/ie-png-fix.js" );
-               # $ret .= "<!--[if gte IE 5.5000]><script type='text/javascript' src='$fix'></script><![endif]-->";
+               # $ret .= "<!--[if gte IE 5.5000]><script type='text/javascript' src='$fix'>< /script><![endif]-->";
                return $ret;
        }
        
        # Parse <tmp=> link placeholders to avoid using linkcache
-       # $wgInternalLinks populated in Skin::makeLinkObj()
+       # Placeholders created in Skin::makeLinkObj()
        function parseLinkHolders()
        {
-               global $wgUser, $wgInternalLinks;
+               global $wgUser;
                
                $fname = 'OutputPage::parseLinkHolders';
                wfProfileIn( $fname );
                
                # Get placeholders from body
-               preg_match_all( "/<tmp=(.*?)>/", $this->mBodytext, $tmpLinks );
+               preg_match_all( "/<tmp=(.*?) (.*?) (.*?) (.*?)>/", $this->mBodytext, $tmpLinks );
                
                if ( !empty( $tmpLinks[0] ) ) {
-                       $dbr =& wfGetDB( DB_READ );
+                       $dbr =& wfGetDB( DB_SLAVE );
+                       $cur = $dbr->tableName( 'cur' );
                        $sk = $wgUser->getSkin();
+                       $threshold = $wgUser->getOption('stubthreshold');
                        
-                       # Index the DB key along with other information
-                       foreach ( $tmpLinks[1] as $key => $val ) {
-                               $wgInternalLinks['dbkey'][$key] = $wgInternalLinks['obj'][$key]->getDBkey();
-                       }
-                       
-                       # Sort according to namespace
-                       asort($wgInternalLinks['ns']);
-                       
+                       $namespaces =& $tmpLinks[1];
+                       $dbkeys =& $tmpLinks[2];
+                       $queries =& $tmpLinks[3];
+                       $texts =& $tmpLinks[4];
+
+                       # Sort by namespace
+                       asort( $namespaces );
+       
                        # Generate query
-                       foreach ( $wgInternalLinks['ns'] as $key => $val ) {
+                       foreach ( $namespaces as $key => $val ) {
                                if ( !isset( $current ) ) {
                                        $current = $val;
-                                       $query =  "SELECT cur_title, LENGTH(cur_text) AS cur_len, cur_is_redirect FROM cur ";
-                                       $query .= "WHERE (cur_namespace=$val AND cur_title IN(";
+                                       $query =  "SELECT cur_namespace, cur_title";
+                                       if ( $threshold > 0 ) {
+                                               $query .= ", LENGTH(cur_text) AS cur_len, cur_is_redirect";
+                                       } 
+                                       $query .= " FROM $cur WHERE (cur_namespace=$val AND cur_title IN(";
                                } elseif ( $current != $val ) {
                                        $current = $val;
                                        $query .= ")) OR (cur_namespace=$val AND cur_title IN(";
@@ -794,49 +802,52 @@ class OutputPage {
                                        $query .= ", ";
                                }
                                
-                               $query .= $dbr->addQuotes( $wgInternalLinks['dbkey'][$key] );
+                               $query .= $dbr->addQuotes( $dbkeys[$key] );
                        }
 
                        $query .= "))";
                        
-                       $res = $dbr->query( $query );
+                       $res = $dbr->query( $query, $fname );
                        
-                       # Fetch data and pass to appropriate make*LinkObj()
-                       # Index search and replace strings to substitute placeholders for actual links
-                       while ( $s = $dbr->fetchRow($res) ) {
-                               $i = array_search($s['cur_title'], $wgInternalLinks['dbkey']);
-                               $threshold = $wgUser->getOption('stubthreshold');
-                               if ( $threshold > 0 ) {
-                                       $size = $s['cur_len'];
-                                       if ( $s['cur_is_redirect'] || ( $wgInternalLinks['ns'][$i] != 0 ) ) {
-                                               $size = $threshold * 2; # Really big
+                       # Fetch data and form into an associative array
+                       # non-existent = broken
+                       # 1 = known
+                       # 2 = stub
+                       $colours = array();
+                       while ( $s = $dbr->fetchObject($res) ) {
+                               $key = $s->cur_namespace . ' ' . $s->cur_title;
+                               if ( $threshold >  0 ) {
+                                       $size = $s->cur_len;
+                                       if ( $s->cur_is_redirect || $s->cur_namespace != 0 || $length < $threshold ) {
+                                               $colours[$key] = 1;
+                                       } else {
+                                               $colours[$key] = 2;
                                        }
+                                       $colours[$key] = array( $s->cur_len, $s->cur_is_redirect );
                                } else {
-                                       $size = 1;
-                               }
-                               
-                               if ( $size < $threshold ) {
-                                       $wgInternalLinks['replace'][$i] = $sk->makeStubLinkObj( $wgInternalLinks['obj'][$i],
-                                               $wgInternalLinks['text'][$i], $wgInternalLinks['query'][$i], '',
-                                               $wgInternalLinks['prefix'][$i]);
-                               } else {
-                                       $wgInternalLinks['replace'][$i] = $sk->makeKnownLinkObj( $wgInternalLinks['obj'][$i],
-                                               $wgInternalLinks['text'][$i], $wgInternalLinks['query'][$i], '',
-                                               $wgInternalLinks['prefix'][$i]);
+                                       $colours[$key] = 1;
                                }
                        }
                        
-                       # Finish populating search and replace arrays for broken links
-                       foreach ( $wgInternalLinks['ns'] as $key => $val ) {
-                               $search[]  = $tmpLinks[0][$key];
-                               $replace[] = ( empty ( $wgInternalLinks['replace'][$key] ) ) ?
-                                       $sk->makeBrokenLinkObj( $wgInternalLinks['obj'][$key],
-                                               $wgInternalLinks['text'][$key], $wgInternalLinks['query'][$key], '',
-                                               $wgInternalLinks['prefix'][$key])
-                                       : $wgInternalLinks['replace'][$key];
+                       # Construct search and replace arrays
+                       $search = $replace = array();
+                       foreach ( $namespaces as $key => $ns ) {
+                               $cKey = $ns . ' ' . $dbkeys[$key];
+                               $search[] = $tmpLinks[0][$key];
+                               $title = Title::makeTitle( $ns, $dbkeys[$key] );
+                               if ( empty( $colours[$cKey] ) ) {
+                                       $replace[] = $sk->makeBrokenLinkObj( $title, $texts[$key], $queries[$key] );
+                               } elseif ( $colours[$cKey] == 1 ) {
+                                       $replace[] = $sk->makeKnownLinkObj( $title, $texts[$key], $queries[$key] );
+                               } elseif ( $colours[$cKey] == 2 ) {
+                                       $replace[] = $sk->makeStubLinkObj( $title, $texts[$key], $queries[$key] );
+                               }
                        }
-                       
+
+                       # Do the thing
                        $out = str_replace( $search, $replace, $this->mBodytext );
+               } else {
+                       $out = $this->mBodytext;
                }
                
                wfProfileOut( $fname );
index adc4790..13c1b44 100644 (file)
@@ -55,7 +55,7 @@ class PageHistory {
                $namespace = $this->mTitle->getNamespace();
                $title = $this->mTitle->getText();
                
-               $db =& wfGetDB( DB_READ );
+               $db =& wfGetDB( DB_SLAVE );
                $use_index = $db->useIndexClause( 'name_title_timestamp' );
                $oldtable = $db->tableName( 'old' );
 
index 09784db..1d36b39 100644 (file)
@@ -361,7 +361,7 @@ class Parser
                $id = $this->mTitle->getArticleID() ;
 
                # FIXME: add limits
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $cur = $dbr->tableName( 'cur' );
                $categorylinks = $dbr->tableName( 'categorylinks' );
 
@@ -425,7 +425,7 @@ class Parser
                $id = $this->mTitle->getArticleID() ;
 
                # FIXME: add limits
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $cur = $dbr->tableName( 'cur' );
                $categorylinks = $dbr->tableName( 'categorylinks' );
 
index e27c766..9998c45 100755 (executable)
@@ -151,7 +151,7 @@ class Profiler
 
        /* static */ function logToDB($name, $timeSum, $eventCount) 
        {
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $profiling = $dbw->tableName( 'profiling' );
 
                $name = $dbw->strencode( $name );
@@ -165,7 +165,7 @@ class Profiler
                if( $rc == 0) {
                        $sql = "INSERT IGNORE INTO $profiling (pf_name,pf_count,pf_time) ".
                                "VALUES ('{$name}', {$eventCount}, {$timeSum}) ";
-                       $dbw->query($sql , DB_WRITE);
+                       $dbw->query($sql , DB_MASTER);
                }
                // When we upgrade to mysql 4.1, the insert+update
                // can be merged into just a insert with this construct added:
index a79897d..4ed28cb 100644 (file)
@@ -66,8 +66,8 @@ class QueryPage {
                $sname = $this->getName();
                $fname = get_class($this) . "::doQuery";
                $sql = $this->getSQL();
-               $dbr =& wfGetDB( DB_READ );
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbr =& wfGetDB( DB_SLAVE );
+               $dbw =& wfGetDB( DB_MASTER );
                $querycache = $dbr->tableName( 'querycache' );
 
                $wgOut->setSyndicated( true );
@@ -161,7 +161,7 @@ class QueryPage {
                                $this->feedUrl() );
                        $feed->outHeader();
                        
-                       $dbr = wfGetDB( DB_READ );
+                       $dbr =& wfGetDB( DB_SLAVE );
                        $sql = $this->getSQL() . $this->getOrderLimit( 0, 50 );
                        $res = $dbr->query( $sql, "QueryPage::doFeed" );
                        while( $obj = $dbr->fetchObject( $res ) ) {
index 9179a5e..4a8c936 100644 (file)
@@ -64,7 +64,9 @@ class RawPage {
                $fname = 'RawPage::getrawtext';
                
                if( !$this->mTitle ) return '';
-               $dbr = wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
+               extract( $dbr->tableNames( 'cur', 'old' ) );
+
                $t = $dbr->strencode( $this->mTitle->getDBKey() );
                $ns = $this->mTitle->getNamespace();
                # special case
@@ -76,13 +78,12 @@ class RawPage {
                }
                # else get it from the DB
                if(!empty($this->mOldId)) {
-                       $oldtable = $dbr->tableName( 'old', DB_READ );
                        $sql = "SELECT old_text AS text,old_timestamp AS timestamp,".
-                                   "old_user AS user,old_flags AS flags FROM $oldtable " .
+                                   "old_user AS user,old_flags AS flags FROM $old " .
                        "WHERE old_id={$this->mOldId}";
                } else {
                        $sql = "SELECT cur_id as id,cur_timestamp as timestamp,cur_user as user,cur_user_text as user_text," .
-                       "cur_restrictions as restrictions,cur_comment as comment,cur_text as text FROM cur " .
+                       "cur_restrictions as restrictions,cur_comment as comment,cur_text as text FROM $cur " .
                        "WHERE cur_namespace=$ns AND cur_title='$t'";
                }
                $res = $dbr->query( $sql, $fname );
index ed64ee2..eb3aeb6 100644 (file)
@@ -88,6 +88,7 @@ class RecentChange
                global $wgUseRCQueue, $wgRCQueueID, $wgLocalInterwiki, $wgPutIPinRC;
                $fname = "RecentChange::save";
                
+               $dbw =& wfGetDB( DB_MASTER );
                if ( !is_array($this->mExtra) ) {
                        $this->mExtra = array();
                }
@@ -98,26 +99,31 @@ class RecentChange
                }
                
                # Insert new row
-               wfInsertArray( "recentchanges", $this->mAttribs, $fname );
+               $dbw->insertArray( "recentchanges", $this->mAttribs, $fname );
                
                # Update old rows, if necessary
                if ( $this->mAttribs['rc_type'] == RC_EDIT ) {
                        $oldid = $this->mAttribs['rc_last_oldid'];
                        $ns = $this->mAttribs['rc_namespace'];
-                       $title = wfStrencode($this->mAttribs['rc_title']);
+                       $title = $this->mAttribs['rc_title'];
                        $lastTime = $this->mExtra['lastTimestamp'];
                        $now = $this->mAttribs['rc_timestamp'];
                        $curId = $this->mAttribs['rc_cur_id'];
                        
                        # Update rc_this_oldid for the entries which were current
-                       $sql = "UPDATE recentchanges SET rc_this_oldid={$oldid} " .
-                               "WHERE rc_namespace=$ns AND rc_title='$title' AND rc_timestamp='$lastTime'";
-                       wfQuery( $sql, DB_WRITE, $fname );
+                       $dbw->updateArray( 'recentchanges', 
+                               array( /* SET */
+                                       'rc_this_oldid' => $oldid
+                               ), array( /* WHERE */ 
+                                       'rc_namespace' => $ns,
+                                       'rc_title' => $title,
+                                       'rc_timestamp' => $lastTime
+                               ), $fname
+                       );
 
                        # Update rc_cur_time
-                       $sql = "UPDATE recentchanges SET rc_cur_time='{$now}' " .
-                         "WHERE rc_cur_id=" . $curId;
-                       wfQuery( $sql, DB_WRITE, $fname );
+                       $dbw->updateArray( 'recentchanges', array( 'rc_cur_time' => $now ), 
+                               array( 'rc_cur_id' => $curId ), $fname );
                }
                
                # Notify external application
index bb2ed08..df71975 100644 (file)
@@ -180,23 +180,26 @@ class SearchEngine {
 
                $searchnamespaces = $this->queryNamespaces();
                $redircond = $this->searchRedirects();
-
+               $dbr =& wfGetDB( DB_SLAVE );
+               $searchindex = $dbr->tableName( 'searchindex' );
+               $cur = $dbr->tableName( 'cur' );
+               
                if ( $wgDisableTextSearch ) {
                        $wgOut->addHTML( wfMsg( "searchdisabled" ) );
                        $wgOut->addHTML( wfMsg( "googlesearch", htmlspecialchars( $search ), $GLOBALS['wgInputEncoding'] ) );
                } else {
                        $sql = "SELECT cur_id,cur_namespace,cur_title," .
-                         "cur_text FROM cur,searchindex " .
+                         "cur_text FROM $cur,$searchindex " .
                          "WHERE cur_id=si_page AND {$this->mTitlecond} " .
                          "{$searchnamespaces} {$redircond}" .
                          "LIMIT {$offset}, {$limit}";
-                       $res1 = wfQuery( $sql, DB_READ, $fname );
-                       $num = wfNumRows($res1);
+                       $res1 = $dbr->query( $sql, $fname );
+                       $num = $dbr->numRows($res1);
 
                        $sk = $wgUser->getSkin();
                        $text = "";
 
-                       $this->parseQuery();
+                       $this->parseQuery( $dbr );
                        if ( "" == $this->mTitlecond || "" == $this->mTextcond ) {
                                $wgOut->addHTML( "<h2>" . wfMsg( "badquery" ) . "</h2>\n" .
                                  "<p>" . wfMsg( "badquerytext" ) . "</p>\n" );
@@ -208,20 +211,20 @@ class SearchEngine {
                        $redircond = $this->searchRedirects();
        
                        $sql = "SELECT cur_id,cur_namespace,cur_title," .
-                         "cur_text FROM cur,searchindex " .
+                         "cur_text FROM $cur,$searchindex " .
                          "WHERE cur_id=si_page AND {$this->mTitlecond} " .
                          "{$searchnamespaces} {$redircond}" .
                          "LIMIT {$offset}, {$limit}";
-                       $res1 = wfQuery( $sql, DB_READ, $fname );
-                       $num = wfNumRows($res1);
+                       $res1 = $dbr->query( $sql, $fname );
+                       $num = $dbr->numRows($res1);
        
                        $sql = "SELECT cur_id,cur_namespace,cur_title," .
-                         "cur_text FROM cur,searchindex " .
+                         "cur_text FROM $cur,$searchindex " .
                          "WHERE cur_id=si_page AND {$this->mTextcond} " .
                          "{$searchnamespaces} {$redircond} " .
                          "LIMIT {$offset}, {$limit}";
-                       $res2 = wfQuery( $sql, DB_READ, $fname );
-                       $num = $num + wfNumRows($res2);
+                       $res2 = $dbr->query( $sql, $fname );
+                       $num = $num + $dbr->numRows($res2);
 
                        if ( $num == $limit ) {
                          $top = wfShowingResults( $offset, $limit);
@@ -244,7 +247,7 @@ class SearchEngine {
        
                        $foundsome = false;
        
-                       if ( 0 == wfNumRows( $res1 ) ) {
+                       if ( 0 == $dbr->numRows( $res1 ) ) {
                                $wgOut->addHTML( "<h2>" . wfMsg( "notitlematches" ) .
                                  "</h2>\n" );
                        } else {
@@ -253,14 +256,14 @@ class SearchEngine {
                                $wgOut->addHTML( "<h2>" . wfMsg( "titlematches" ) .
                                  "</h2>\n<ol start='{$off}'>" );
        
-                               while ( $row = wfFetchObject( $res1 ) ) {
+                               while ( $row = $dbr->fetchObject( $res1 ) ) {
                                        $this->showHit( $row );
                                }
-                               wfFreeResult( $res1 );
+                               $dbr->freeResult( $res1 );
                                $wgOut->addHTML( "</ol>\n" );
                        }
 
-                       if ( 0 == wfNumRows( $res2 ) ) {
+                       if ( 0 == $dbr->numRows( $res2 ) ) {
                                $wgOut->addHTML( "<h2>" . wfMsg( "notextmatches" ) .
                                  "</h2>\n" );
                        } else {
@@ -268,10 +271,10 @@ class SearchEngine {
                                $off = $offset + 1;
                                $wgOut->addHTML( "<h2>" . wfMsg( "textmatches" ) . "</h2>\n" .
                                  "<ol start='{$off}'>" );
-                               while ( $row = wfFetchObject( $res2 ) ) {
+                               while ( $row = $dbr->fetchObject( $res2 ) ) {
                                        $this->showHit( $row );
                                }
-                               wfFreeResult( $res2 );
+                               $dbr->freeResult( $res2 );
                                $wgOut->addHTML( "</ol>\n" );
                        }
                        if ( ! $foundsome ) {
@@ -288,13 +291,13 @@ class SearchEngine {
                return $lc;
        }
 
-       function parseQuery()
+       function parseQuery( &$db )
        {
                global $wgDBminWordLen, $wgLang, $wgDBmysql4;
 
                if( $wgDBmysql4 ) {
                        # Use cleaner boolean search if available
-                       return $this->parseQuery4();
+                       return $this->parseQuery4( $db );
                }
                # on non mysql4 database: get list of words we don't want to search for
                require_once( "FulltextStoplist.php" );
@@ -318,7 +321,7 @@ class SearchEngine {
                        } else {
                                if ( "" != $last ) { $cond .= " AND"; }
                                $cond .= " (MATCH (##field##) AGAINST ('" .
-                                 wfStrencode( $word ). "'))";
+                                 $db->strencode( $word ). "'))";
                                $last = $word;
                                array_push( $this->mSearchterms, "\\b" . $word . "\\b" );
                        }
@@ -332,7 +335,7 @@ class SearchEngine {
                  "si_text", $cond ) . " AND (cur_is_redirect=0) )";
        }
        
-       function parseQuery4()
+       function parseQuery4( &$db )
        {
                global $wgLang;
                $lc = SearchEngine::legalSearchChars();
@@ -362,7 +365,7 @@ class SearchEngine {
                        wfDebug( "Can't understand search query '$this->mUsertext'\n" );
                }
                
-               $searchon = wfStrencode( $searchon );
+               $searchon = $db->strencode( $searchon );
                $this->mTitlecond = " MATCH(si_title) AGAINST('$searchon' IN BOOLEAN MODE)";
                $this->mTextcond = " (MATCH(si_text) AGAINST('$searchon' IN BOOLEAN MODE) AND cur_is_redirect=0)";
        }
@@ -567,7 +570,8 @@ class SearchEngine {
 
        /* static */ function getTitlesByLength($aLength, $aNamespace = 0){
                global $wgMemc, $wgDBname;
-
+               $fname = 'SearchEngin::getTitlesByLength';
+               
                // to avoid multiple costly SELECTs in case of no memcached
                if( $this->all_titles ){ 
                        if( isset( $this->all_titles[$aLength][$aNamespace] ) ){
@@ -589,10 +593,11 @@ class SearchEngine {
                }
 
                $wgMemc->set( $mkeyts, time() );
-
-               $res = wfQuery("SELECT cur_title, cur_namespace FROM cur", DB_READ);
+               
+               $dbr =& wfGetDB( DB_SLAVE );
+               $res = $dbr->select( 'cur', array( 'cur_title', 'cur_namespace' ), false, $fname );
                $titles = array(); // length, ns, [titles]
-               while( $obj = wfFetchObject( $res ) ){
+               while( $obj = $dbr->fetchObject( $res ) ){
                        $title = $obj->cur_title;
                        $ns = $obj->cur_namespace;
                        $len = strlen( $title );
index 55bad79..9cbbb61 100644 (file)
@@ -31,13 +31,14 @@ class SearchUpdate {
                        return false;
                }
                $lc = SearchEngine::legalSearchChars() . "&#;";
-               $db =& wfGetDB( DB_WRITE );
+               $db =& wfGetDB( DB_MASTER );
+               $searchindex = $db->tableName( 'searchindex' );
                
                if( $this->mText == false ) {
                        # Just update the title
                        $lowpri = $db->lowPriorityOption();
-                       $sql = "UPDATE $lowpri searchindex SET si_title='" .
-                         wfStrencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) .
+                       $sql = "UPDATE $lowpri $searchindex SET si_title='" .
+                         $db->strencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) .
                          "' WHERE si_page={$this->mId}";
                        $db->query( $sql, "SearchUpdate::doUpdate" );
                        return;
@@ -79,9 +80,9 @@ class SearchUpdate {
                # Strip wiki '' and '''
                $text = preg_replace( "/''[']*/", " ", $text );
                
-               $sql = "REPLACE  INTO searchindex (si_page,si_title,si_text) VALUES ({$this->mId},'" .
-                 wfStrencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) . "','" .
-                 wfStrencode( $text ) . "')";
+               $sql = "REPLACE  INTO $searchindex (si_page,si_title,si_text) VALUES ({$this->mId},'" .
+                 $db->strencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) . "','" .
+                 $db->strencode( $text ) . "')";
                $db->query( $sql, "SearchUpdate::doUpdate" );
        }
 }
index 90be866..747d1c3 100644 (file)
@@ -74,6 +74,7 @@ global $wgMsgCacheExpiry, $wgCommandLineMode;
 global $wgBlockCache, $wgParserCache, $wgParser, $wgDBConnections;
 global $wgLoadBalancer, $wgDBservers;
 global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype;
+global $wgFullyInitialised;
 
 # Useful debug output
 if ( $wgCommandLineMode ) {
@@ -126,13 +127,6 @@ if( $wgUseMemCached ) {
        $wgMemc->set_servers( $wgMemCachedServers );
        $wgMemc->set_debug( $wgMemCachedDebug );
 
-       # Test it to see if it's working
-       # This is necessary because otherwise wfMsg would be extremely inefficient
-       if ( !$wgMemc->set( 'test', '', 0 ) ) {
-               wfDebug( "Memcached failed setup test - connection error?\n" );
-               $wgUseMemCached = false;
-               $wgMemc = new FakeMemCachedClient();
-       }
        $messageMemc = &$wgMemc;
 } else {
        $wgMemc = new FakeMemCachedClient();
@@ -144,6 +138,16 @@ if( $wgUseMemCached ) {
 }
 
 wfProfileOut( $fname.'-memcached' );
+wfProfileIn( $fname.'-SetupSession' );
+
+if( !$wgCommandLineMode && ( isset( $_COOKIE[ini_get('session.name')] ) || isset( $_COOKIE[$wgDBname.'Password'] ) ) ) {
+       User::SetupSession();
+       $wgSessionStarted = true;
+} else {
+       $wgSessionStarted = false;
+}
+
+wfProfileOut( $fname.'-SetupSession' );
 wfProfileIn( $fname.'-database' );
 
 if ( !$wgDBservers ) {
@@ -157,7 +161,7 @@ if ( !$wgDBservers ) {
        ));
 }
 $wgLoadBalancer = LoadBalancer::newFromParams( $wgDBservers );
-$wgLoadBalancer->force(0);
+$wgLoadBalancer->loadMasterPos();
 
 wfProfileOut( $fname.'-database' );
 wfProfileIn( $fname.'-language' );
@@ -205,13 +209,6 @@ if ( $wgUseDynamicDates ) {
 }
 
 wfProfileOut( $fname.'-DateFormatter' );
-wfProfileIn( $fname.'-SetupSession' );
-
-if( !$wgCommandLineMode && ( isset( $_COOKIE[ini_get('session.name')] ) || isset( $_COOKIE[$wgDBname.'Password'] ) ) ) {
-       User::SetupSession();
-}
-
-wfProfileOut( $fname.'-SetupSession' );
 wfProfileIn( $fname.'-BlockCache' );
 
 $wgBlockCache = new BlockCache( true );
@@ -238,6 +235,7 @@ $wgParserCache = new ParserCache();
 $wgParser = new Parser();
 $wgOut->setParserOptions( ParserOptions::newFromUser( $wgUser ) );
 $wgDBConnections = array();
+wfSeedRandom();
 
 # Placeholders in case of DB error
 $wgTitle = Title::newFromText( wfMsg( 'badtitle' ) );
@@ -254,6 +252,7 @@ foreach ( $wgExtensionFunctions as $func ) {
        $func();
 }
 
+$wgFullyInitialised = true;
 wfProfileOut( $fname.'-extensions' );
 wfProfileOut( $fname );
 
index f8a6bb5..247adab 100644 (file)
@@ -32,9 +32,11 @@ class SiteStatsUpdate {
                else $m = "";
                array_push( $a, "ss_good_articles=(ss_good_articles$m)" );
 
-               $db =& wfGetDB( DB_WRITE );
+               $db =& wfGetDB( DB_MASTER );
+               $site_stats = $db->tableName( 'site_stats' );
                $lowpri = $db->lowPriorityOption();
-               $sql = "UPDATE $lowpri site_stats SET " . implode ( ",", $a ) .
+
+               $sql = "UPDATE $lowpri $site_stats SET " . implode ( ",", $a ) .
                  " WHERE ss_row_id=1";
                $db->query( $sql, "SiteStatsUpdate::doUpdate" );
        }
index bf4efbb..bc67c38 100644 (file)
@@ -46,6 +46,7 @@ class Skin {
        var $rc_cache ; # Cache for Enhanced Recent Changes
        var $rcCacheIndex ; # Recent Changes Cache Counter for visibility toggle
        var $rcMoveIndex;
+       var $postParseLinkColour = true;
 
        function Skin()
        {
@@ -65,6 +66,11 @@ class Skin {
        function getSkinName() {
                return "standard";
        }
+       
+       # Get/set accessor for delayed link colouring
+       function postParseLinkColour( $setting = NULL ) {
+               return wfSetVar( $this->postParseLinkColour, $setting );
+       }
 
        function qbSetting()
        {
@@ -1440,7 +1446,6 @@ class Skin {
        function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
        {
                global $wgOut, $wgUser;
-               global $wgInternalLinks;
                $fname = 'Skin::makeLinkObj';
 
                if ( $nt->isExternal() ) {
@@ -1463,21 +1468,48 @@ class Skin {
                                ( Namespace::getImage() == $nt->getNamespace() ) ) {
                        $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
                } else {
-                       $inside = '';
-                       if ( '' != $trail ) {
-                               if ( preg_match( $this->linktrail, $trail, $m ) ) {
-                                       $inside = $m[1];
-                                       $trail = $m[2];
+                       if ( $this->postParseLinkColour() ) {
+                               $inside = '';
+                               if ( '' != $trail ) {
+                                       if ( preg_match( $this->linktrail, $trail, $m ) ) {
+                                               $inside = $m[1];
+                                               $trail = $m[2];
+                                       }
+                               }
+                               
+                               # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
+                               $retVal = "<tmp=" . implode( ' ', array( $nt->getNamespace(), $nt->getDBkey(), 
+                                       $query, $prefix . $text . $inside ) ) . ">{$trail}";
+                       } else {
+                               # Work out link colour immediately
+                               $aid = $nt->getArticleID() ;
+                               if ( 0 == $aid ) {
+                                       $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
+                               } else {
+                                       $threshold = $wgUser->getOption('stubthreshold') ;
+                                       if ( $threshold > 0 ) { 
+                                               $dbr =& wfGetDB( DB_SLAVE );
+                                               $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace', 
+                                                       'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
+                                               if ( $s !== false ) {
+                                                       $size = $s->x;
+                                                       if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
+                                                               $size = $threshold*2 ; # Really big
+                                                       }
+                                                       $dbr->freeResult( $res );
+                                               } else {
+                                                       $size = $threshold*2 ; # Really big
+                                               }
+                                       } else {
+                                               $size = 1 ;
+                                       }
+                                       if ( $size < $threshold ) {
+                                               $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
+                                       } else {
+                                               $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+                                       }
                                }
                        }
-                       
-                       # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
-                       $wgInternalLinks['obj'][] = $nt;
-                       $wgInternalLinks['text'][] = $text . $inside;
-                       $wgInternalLinks['query'][] = $query;
-                       $wgInternalLinks['prefix'][] = $prefix;
-                       $wgInternalLinks['ns'][] = $nt->getNamespace();
-                       $retVal = "<tmp=" . $nt->getDBkey() . ">{$trail}";
                }
                return $retVal;
        }
index 27b2b3b..32dcb6e 100644 (file)
@@ -30,43 +30,39 @@ function indexShowToplevel()
                $log->showAsDisabledPage();
                return;
        }
-
-       $fromwhere = "FROM cur WHERE cur_namespace=0";
-       $order = "ORDER BY cur_title";
+       
+       $dbr =& wfGetDB( DB_SLAVE );
+       $cur = $dbr->tableName( 'cur' );
+       $fromwhere = "FROM $cur WHERE cur_namespace=0";
+       $order = 'ORDER BY cur_title';
        $out = "";
+       $where = array( 'cur_namespace' => 0 );
 
-       $sql = "SELECT COUNT(*) AS count $fromwhere";
-       $res = wfQuery( $sql, DB_READ, $fname );
-       $s = wfFetchObject( $res );
-       $count = $s->count;
+       $count = $dbr->selectField( 'cur', 'COUNT(*)', $where, $fname );
        $sections = ceil( $count / $indexMaxperpage );
-
-       $sql = "SELECT cur_title $fromwhere $order LIMIT 1";
-       $res = wfQuery( $sql, DB_READ, $fname );
-       $s = wfFetchObject( $res );
-       $inpoint = $s->cur_title;
-
+       $inpoint = $dbr->selectField( 'cur', 'cur_title', $where, $fname, $order );
+       
        $out .= "<table>\n";
        # There's got to be a cleaner way to do this!
        for( $i = 1; $i < $sections; $i++ ) {
                $from = $i * $indexMaxperpage;
                $sql = "SELECT cur_title $fromwhere $order ".wfLimitResult(2,$from);
-               $res = wfQuery( $sql, DB_READ, $fname );
+               $res = $dbr->query( $sql, $fname );
 
-               $s = wfFetchObject( $res );
+               $s = $dbr->fetchObject( $res );
                $outpoint = $s->cur_title;
                $out .= indexShowline( $inpoint, $outpoint );
 
-               $s = wfFetchObject( $res );
+               $s = $dbr->fetchObject( $res );
                $inpoint = $s->cur_title;
 
-               wfFreeResult( $res );
+               $dbr->freeResult( $res );
        }
 
        $from = $i * $indexMaxperpage;
        $sql = "SELECT cur_title $fromwhere $order ".wfLimitResult(1,$count-1);
-       $res = wfQuery( $sql, DB_READ, $fname );
-       $s = wfFetchObject( $res );
+       $res = $dbr->query( $sql, $fname );
+       $s = $dbr->fetchObject( $res );
        $outpoint = $s->cur_title;
        $out .= indexShowline( $inpoint, $outpoint );
        $out .= "</table>\n";
@@ -81,13 +77,14 @@ function indexShowline( $inpoint, $outpoint )
 {
        global $wgOut, $wgLang, $wgUser;
        $sk = $wgUser->getSkin();
+       $dbr =& wfGetDB( DB_SLAVE );
 
        # Fixme: this is ugly
        $out = wfMsg(
                "alphaindexline",
                $sk->makeKnownLink( $wgLang->specialPage( "Allpages" ),
                        str_replace( "_", " ", $inpoint ),
-                       "from=" . wfStrencode( $inpoint ) ) . "</td><td>",
+                       "from=" . $dbr->strencode( $inpoint ) ) . "</td><td>",
                "</td><td align=\"left\">" .
                str_replace( "_", " ", $outpoint )
                );
@@ -101,15 +98,17 @@ function indexShowChunk( $from )
        $maxPlusOne = $indexMaxperpage + 1;
 
        $out = "";
-       $sql = "SELECT cur_title FROM cur WHERE cur_namespace=0 AND cur_title >= '"
-               . wfStrencode( $from ) . "' ORDER BY cur_title LIMIT " . $maxPlusOne;
-       $res = wfQuery( $sql, DB_READ, "indexShowChunk" );
+       $dbr =& wfGetDB( DB_SLAVE );
+       $cur = $dbr->tableName( 'cur' );
+       $sql = "SELECT cur_title FROM $cur WHERE cur_namespace=0 AND cur_title >= '"
+               . $dbr->strencode( $from ) . "' ORDER BY cur_title LIMIT " . $maxPlusOne;
+       $res = $dbr->query( $sql, "indexShowChunk" );
 
        ### FIXME: side link to previous
 
        $n = 0;
        $out = "<table border=\"0\" width=\"100%\">\n";
-       while( ($n < $indexMaxperpage) && ($s = wfFetchObject( $res )) ) {
+       while( ($n < $indexMaxperpage) && ($s = $dbr->fetchObject( $res )) ) {
                $t = Title::makeTitle( 0, $s->cur_title );
                if( $t ) {
                        $link = $sk->makeKnownLinkObj( $t );
@@ -133,11 +132,11 @@ function indexShowChunk( $from )
        $out2 = "<div style='text-align: right; font-size: smaller; margin-bottom: 1em;'>" .
                        $sk->makeKnownLink( $wgLang->specialPage( "Allpages" ),
                                wfMsg ( 'allpages' ) );
-       if ( ($n == $indexMaxperpage) && ($s = wfFetchObject( $res )) ) {
+       if ( ($n == $indexMaxperpage) && ($s = $dbr->fetchObject( $res )) ) {
                $out2 .= " | " . $sk->makeKnownLink(
                        $wgLang->specialPage( "Allpages" ),
                        wfMsg ( 'nextpage', $s->cur_title ),
-                       "from=" . wfStrencode( $s->cur_title ) );
+                       "from=" . $dbr->strencode( $s->cur_title ) );
        }
        $out2 .= "</div>";
 
index 69d2d43..6029f06 100644 (file)
@@ -13,14 +13,15 @@ class AncientPagesPage extends QueryPage {
        }
 
        function getSQL() {
-               $db = wfGetDB( DB_READ );
+               $db =& wfGetDB( DB_SLAVE );
+               $cur = $db->tableName( 'cur' );
                $use_index = $db->useIndexClause( 'cur_timestamp' );
                return
                        "SELECT 'Ancientpages' as type,
                                        cur_namespace as namespace,
                                cur_title as title,
                                UNIX_TIMESTAMP(cur_timestamp) as value
-                       FROM cur $use_index
+                       FROM $cur $use_index
                        WHERE cur_namespace=0 AND cur_is_redirect=0";
        }
        
index 8e7aa72..13994c4 100644 (file)
@@ -41,15 +41,11 @@ class BookSourceList {
                
                # First, see if we have a custom list setup in
                # [[Wikipedia:Book sources]] or equivalent.
-               $bstitle = Title::newFromText( wfmsg( "booksources" ) );
-               $sql = "SELECT cur_text FROM cur " .
-                       "WHERE cur_namespace=4 and cur_title='" .
-                       wfStrencode( $bstitle->getDBkey() ) . "'";
-               $res = wfQuery( $sql, DB_READ, $fname );
-               if( ( $s = wfFetchObject( $res ) ) and ( $s->cur_text != "" ) ) {       
-                       $bstext = $s->cur_text;
+               $bstitle = Title::makeTitle( NS_WIKIPEDIA, wfMsg( "booksources" ) );
+               $dbr =& wfGetDB( DB_SLAVE );
+               $bstext = $dbr->selectField( 'cur', 'cur_text', $bstitle->curCond(), $fname );
+               if( $bstext ) { 
                        $bstext = str_replace( "MAGICNUMBER", $this->mIsbn, $bstext );
-                       
                        $wgOut->addWikiText( $bstext );
                        return;
                }
index 6cc493e..4e06560 100644 (file)
@@ -14,11 +14,13 @@ class CategoriesPage extends QueryPage {
 
        function getSQL() {
                $NScat = NS_CATEGORY;
+               $dbr =& wfGetDB( DB_SLAVE );
+               $categorylinks = $dbr->tableName( 'categorylinks' );
                return "SELECT DISTINCT 'Categories' as type, 
                                {$NScat} as namespace,
                                cl_to as title,
                                1 as value
-                          FROM categorylinks";
+                          FROM $categorylinks";
        }
        
        function sortDescending() {
index 5fd831a..279f58c 100644 (file)
@@ -22,7 +22,7 @@ function wfSpecialContributions( $par = "" )
        $querylimit = $offlimit + 1;
        $hideminor = ($wgRequest->getVal( 'hideminor' ) ? 1 : 0);
        $sk = $wgUser->getSkin();
-
+       $dbr =& wfGetDB( DB_SLAVE );
        $userCond = "";
 
        $nt = Title::newFromURL( $target );
@@ -44,8 +44,8 @@ function wfSpecialContributions( $par = "" )
 
        if ( $target == 'newbies' ) {
                # View the contributions of all recently created accounts
-               $row = wfGetArray("user",array("max(user_id) as m"),false);
-               $userCond = ">" . ($row->m - $row->m / 100);
+               $max = $dbr->selectField( 'user', 'max(user_id)', false, $fname );
+               $userCond = ">" . ($max - $max / 100);
                $ul = "";
                $id = 0;
        }
@@ -65,28 +65,28 @@ function wfSpecialContributions( $par = "" )
                  "&offset={$offset}&limit={$limit}&hideminor=1" );
        }
 
-       $oldtable = wfTableName( 'old', DB_READ );
+       extract( $dbr->tableNames( 'old', 'cur' ) );
        if ( $userCond == "" ) {
-               $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new,cur_user_text FROM cur " .
-                 "WHERE cur_user_text='" . wfStrencode( $nt->getText() ) . "' {$cmq} " .
+               $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new,cur_user_text FROM $cur " .
+                 "WHERE cur_user_text='" . $dbr->strencode( $nt->getText() ) . "' {$cmq} " .
                  "ORDER BY inverse_timestamp LIMIT {$querylimit}";
-               $res1 = wfQuery( $sql, DB_READ, $fname );
+               $res1 = $dbr->query( $sql, $fname );
 
-               $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit,old_user_text FROM $oldtable " .
-                 "WHERE old_user_text='" . wfStrencode( $nt->getText() ) . "' {$omq} " .
+               $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit,old_user_text FROM $old " .
+                 "WHERE old_user_text='" . $dbr->strencode( $nt->getText() ) . "' {$omq} " .
                  "ORDER BY inverse_timestamp LIMIT {$querylimit}";
-               $res2 = wfQuery( $sql, DB_READ, $fname );
+               $res2 = $dbr->query( $sql, $fname );
        } else {
-               $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new,cur_user_text FROM cur " .
+               $sql = "SELECT cur_namespace,cur_title,cur_timestamp,cur_comment,cur_minor_edit,cur_is_new,cur_user_text FROM $cur " .
                  "WHERE cur_user {$userCond} {$cmq} ORDER BY inverse_timestamp LIMIT {$querylimit}";
-               $res1 = wfQuery( $sql, DB_READ, $fname );
+               $res1 = $dbr->query( $sql, $fname );
 
-               $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit,old_user_text FROM $oldtable " .
+               $sql = "SELECT old_namespace,old_title,old_timestamp,old_comment,old_minor_edit,old_user_text FROM $old " .
                  "WHERE old_user {$userCond} {$omq} ORDER BY inverse_timestamp LIMIT {$querylimit}";
-               $res2 = wfQuery( $sql, DB_READ, $fname );
+               $res2 = $dbr->query( $sql, $fname );
        }
-       $nCur = wfNumRows( $res1 );
-       $nOld = wfNumRows( $res2 );
+       $nCur = $dbr->numRows( $res1 );
+       $nOld = $dbr->numRows( $res2 );
 
        $top = wfShowingResults( $offset, $limit );
        $wgOut->addHTML( "<p>{$top}\n" );
@@ -104,8 +104,8 @@ function wfSpecialContributions( $par = "" )
                $wgOut->addHTML( "\n<p>" . wfMsg( "nocontribs" ) . "</p>\n" );
                return;
        }
-       if ( 0 != $nCur ) { $obj1 = wfFetchObject( $res1 ); }
-       if ( 0 != $nOld ) { $obj2 = wfFetchObject( $res2 ); }
+       if ( 0 != $nCur ) { $obj1 = $dbr->fetchObject( $res1 ); }
+       if ( 0 != $nOld ) { $obj2 = $dbr->fetchObject( $res2 ); }
 
        $wgOut->addHTML( "<ul>\n" );
        for( $n = 0; $n < $offlimit; $n++ ) {
@@ -122,7 +122,7 @@ function wfSpecialContributions( $par = "" )
                        $isnew = $obj1->cur_is_new;
                        $usertext = $obj1->cur_user_text;
                        
-                       $obj1 = wfFetchObject( $res1 );
+                       $obj1 = $dbr->fetchObject( $res1 );
                        $topmark = true;
                        --$nCur;
                } else {
@@ -133,7 +133,7 @@ function wfSpecialContributions( $par = "" )
                        $me = $obj2->old_minor_edit;
                        $usertext = $obj2->old_user_text;
 
-                       $obj2 = wfFetchObject( $res2 );
+                       $obj2 = $dbr->fetchObject( $res2 );
                        $topmark = false;
                        $isnew = false;
                        --$nOld;
index a571d68..24a3699 100644 (file)
@@ -19,8 +19,10 @@ class DeadendPagesPage extends PageQueryPage {
        }
     
        function getSQL() {
+               $dbr =& wfGetDB( DB_SLAVE );
+               extract( $dbr->tableNames( 'cur', 'links' ) );
                return "SELECT 'Deadendpages' as type, cur_namespace AS namespace, cur_title as title, cur_title AS value " . 
-       "FROM cur LEFT JOIN links ON cur_id = l_from " .
+       "FROM $cur LEFT JOIN $links ON cur_id = l_from " .
        "WHERE l_from IS NULL " .
        "AND cur_namespace = 0 " .
        "AND cur_is_redirect = 0";
index 06aa57d..a72904b 100644 (file)
@@ -65,15 +65,16 @@ function pages2xml( $pages, $curonly = false ) {
 
 function page2xml( $page, $curonly, $full = false ) {
        global $wgLang;
+       $fname = 'page2xml';
+       
        $title = Title::NewFromText( $page );
        if( !$title ) return "";
-       $t = wfStrencode( $title->getDBKey() );
-       $ns = $title->getNamespace();
-       $sql = "SELECT cur_id as id,cur_timestamp as timestamp,cur_user as user,cur_user_text as user_text," .
-               "cur_restrictions as restrictions,cur_comment as comment,cur_text as text FROM cur " .
-               "WHERE cur_namespace=$ns AND cur_title='$t'";
-       $res = wfQuery( $sql, DB_READ );
-       if( $s = wfFetchObject( $res ) ) {
+
+       $dbr =& wfGetDB( DB_SLAVE );
+       $s = $dbr->selectRow( 'cur', array( 'cur_id as id','cur_timestamp as timestamp','cur_user as user',
+               'cur_user_text as user_text', 'cur_restrictions as restrictions','cur_comment as comment',
+               'cur_text as text' ), $title->curCond(), $fname );
+       if( $s !== false ) {
                $tl = htmlspecialchars( $title->getPrefixedText() );
                $xml = "  <page>\n";
                $xml .= "    <title>$tl</title>\n";
@@ -84,12 +85,13 @@ function page2xml( $page, $curonly, $full = false ) {
                        $xml .= "    <restrictions>$s->restrictions</restrictions>\n";
                }
                if( !$curonly ) {
-                       $sql = "SELECT old_id as id,old_timestamp as timestamp, old_user as user, old_user_text as user_text," .
-                               "old_comment as comment, old_text as text, old_flags as flags FROM old " .
-                               "WHERE old_namespace=$ns AND old_title='$t' ORDER BY old_timestamp";
-                       $res = wfQuery( $sql, DB_READ );
+                       $res = $dbr->select( 'old', array( 'old_id as id','old_timestamp as timestamp', 
+                               'old_user as user', 'old_user_text as user_text', 'old_comment as comment', 
+                               'old_text as text', 'old_flags as flags' ), $title->curCond(), 
+                               array( 'ORDER BY' => 'old_timestamp' ), $fname
+                       );
 
-                       while( $s2 = wfFetchObject( $res ) ) {
+                       while( $s2 = $dbr->fetchObject( $res ) ) {
                                $xml .= revision2xml( $s2, $full, false );
                        }
                }
index f57f49a..c20c40f 100644 (file)
@@ -18,8 +18,8 @@
 # http://www.gnu.org/copyleft/gpl.html
 
 function wfSpecialGeo( $page = "" ) {
-       global $wgOut, $wgLang;
-       $coordinates = $_GET['coordinates'] ;
+       global $wgOut, $wgLang, $wgRequest;
+       $coordinates = $wgRequest->getText( 'coordinates' ) ;
        $coordinates = explode ( ":" , $coordinates ) ;
        $ns = array_shift ( $coordinates ) ;
        $ew = array_shift ( $coordinates ) ;
index 40e4dc9..0b4db55 100644 (file)
@@ -6,9 +6,10 @@ function wfSpecialImagelist()
        
        $sort = $wgRequest->getVal( 'sort' );
        $wpIlMatch = $wgRequest->getText( 'wpIlMatch' );
-
+       $dbr =& wfGetDB( DB_SLAVE );
+       $image = $dbr->tableName( 'image' );
        $sql = "SELECT img_size,img_name,img_user,img_user_text," .
-         "img_description,img_timestamp FROM image";
+         "img_description,img_timestamp FROM $image";
 
        $byname = wfMsg( "byname" );
        $bydate = wfMsg( "bydate" );
@@ -20,7 +21,7 @@ function wfSpecialImagelist()
        } else if ( "byname" == $sort ) {
                if ( $wpIlMatch ) {
                        $nt = Title::newFromUrl( $wpIlMatch );
-                       $m = wfStrencode( strtolower( $nt->getDBkey() ) );
+                       $m = $dbr->strencode( strtolower( $nt->getDBkey() ) );
                        $m = str_replace( "%", "\\%", $m );
                        $m = str_replace( "_", "\\_", $m );
                        $sql .= " WHERE LCASE(img_name) LIKE '%{$m}%'";
@@ -93,8 +94,8 @@ function wfSpecialImagelist()
        $text = wfMsg( "showlast", $fill, $bydate );
        $wgOut->addHTML( "{$text}</p>\n<p>" );
 
-       $res = wfQuery( $sql, DB_READ, "wfSpecialImagelist" );
-       while ( $s = wfFetchObject( $res ) ) {
+       $res = $dbr->query( $sql, "wfSpecialImagelist" );
+       while ( $s = $dbr->fetchObject( $res ) ) {
                $name = $s->img_name;
                $ut = $s->img_user_text;
                if ( 0 == $s->img_user ) { $ul = $ut; }
@@ -117,7 +118,7 @@ function wfSpecialImagelist()
                $wgOut->addHTML( "{$l}<br />\n" );
        }
        $wgOut->addHTML( "</p>" );
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
 }
 
 ?>
index 52de966..1536834 100644 (file)
@@ -95,40 +95,8 @@ function wfSpecialImport( $page = "" ) {
 }
 
 function wfImportOldRevision( &$revision ) {
-       global $wgOut;
-       $fname = "wfImportOldRevision";
-       
-       # Sneak a single revision into place
-       $ns = IntVal( $revision->title->getNamespace() );
-       $t = wfStrencode( $revision->title->getDBkey() );
-       $text = wfStrencode( $revision->getText() );
-       $ts = wfStrencode( $revision->timestamp );
-       $its = wfStrencode( wfInvertTimestamp( $revision->timestamp ) ) ;
-       $comment = wfStrencode( $revision->getComment() );
-       
-       $user = User::newFromName( $revision->getUser() );
-       $user_id = IntVal( $user->getId() );
-       $user_text = wfStrencode( $user->getName() );
-
-       $minor = 0; # ??
-       $flags = "";
-       
-       # Make sure it doesn't already exist
-       $sql = "SELECT 1 FROM old WHERE old_namespace=$ns AND old_title='$t' AND old_timestamp='$ts'";
-       $res = wfQuery( $sql, DB_WRITE, $fname );
-       $numrows = wfNumRows( $res );
-       wfFreeResult( $res );
-       if( $numrows > 0 ) {
-               return wfMsg( "importhistoryconflict" );
-       }
-       
-       $res = wfQuery( "INSERT INTO old " .
-         "(old_namespace,old_title,old_text,old_comment,old_user,old_user_text," .
-         "old_timestamp,inverse_timestamp,old_minor_edit,old_flags) " .
-         "VALUES ($ns,'$t','$text','$comment',$user_id,'$user_text','$ts','$its',$minor,'$flags')",
-         DB_WRITE, $fname );
-       
-       return wfMsg( "ok" );
+       $dbw =& wfGetDB( DB_MASTER );
+       $dbw->deadlockLoop( array( &$revision, 'importOldRevision' ) );
 }
 
 class WikiRevision {
@@ -486,6 +454,44 @@ class WikiImporter {
                }
                xml_set_element_handler( $parser, "in_revision", "out_revision" );
        }
+
+       function importOldRevision() {
+               $fname = "WikiImporter::importOldRevision";
+               $dbw =& wfGetDB( DB_MASTER );
+               
+               # Sneak a single revision into place
+               $user = User::newFromName( $this->getUser() );
+
+               $res = $dbw->select( 'old', 1, 
+                       $this->title->oldCond() + array( 'old_timestamp' => $this->timestamp ),
+                       $fname, 'FOR UPDATE'
+               );
+               
+               $numrows = $dbw->numRows( $res );
+               $dbw->freeResult( $res );
+               if( $numrows > 0 ) {
+                       return wfMsg( "importhistoryconflict" );
+               }
+               
+               # Insert the row
+               $oldIgnore = $dbw->setIgnoreErrors( true );
+               $success = $dbw->insert( 'old', 
+                       array( 
+                               'old_namespace' => intval( $this->title->getNamespace() ),
+                               'old_title' => $this->title->getDBkey(),
+                               'old_text' => $this->getText(),
+                               'old_comment' => $this->getComment(),
+                               'old_user' => intval( $user->getId() ),
+                               'old_user_text' => $user->getName(),
+                               'old_timestamp' => $this->timestamp
+                               'inverse_timestamp' => wfInvertTimestamp( $this->timestamp ),
+                               'old_minor_edit' => 0,
+                               'old_flags' => ''
+                       ), $fname
+               );
+               
+               return wfMsg( "ok" );
+       }
 }
 
 
index ba5a579..41588d9 100644 (file)
@@ -16,11 +16,12 @@ class ListAdminsPage extends PageQueryPage {
        }
 
        function getSQL() {
-               $usertable = wfTableName( 'user' );
+               $dbr =& wfGetDB( DB_SLAVE );
+               $user = $dbr->tableName( 'user' );
                $userspace = Namespace::getUser();
                return 'SELECT user_rights as type,'.$userspace.' as namespace,'.
                       'user_name as title, user_name as value '.
-                      "FROM $usertable ".
+                      "FROM $user ".
                           'WHERE user_rights LIKE "%sysop%"';
        }
 }
index 5a317f2..4a9f659 100644 (file)
@@ -13,9 +13,11 @@ class ListUsersPage extends QueryPage {
        }
 
        function getSQL() {
-               $usertable = wfTableName( 'user', DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
+               $usertable = $dbr->tableName( 'user' );
                $userspace = Namespace::getUser();
-               return "SELECT user_rights as type, $userspace as namespace, user_name as title, user_name as value FROM $usertable";
+               return "SELECT user_rights as type, $userspace as namespace, user_name as title, " .
+                       "user_name as value FROM $usertable";
        }
        
        function sortDescending() {
index ebb4f0b..0c026e2 100644 (file)
@@ -13,8 +13,11 @@ class LonelyPagesPage extends PageQueryPage {
        }
        
        function getSQL() {
+               $dbr =& wfGetDB( DB_SLAVE );
+               extract( $dbr->tableNames( 'cur', 'links' ) );
+
                return "SELECT 'Lonelypages' as type, cur_namespace AS namespace, cur_title AS title, cur_title AS value " .
-                       "FROM cur LEFT JOIN links ON cur_id=l_to ".
+                       "FROM $cur LEFT JOIN $links ON cur_id=l_to ".
                        "WHERE l_to IS NULL AND cur_namespace=0 AND cur_is_redirect=0";
        }
 }
index 6139fdb..36c1c75 100644 (file)
@@ -13,12 +13,15 @@ class LongPagesPage extends QueryPage {
        }
 
        function getSQL() {
+               $dbr =& wfGetDB( DB_SLAVE );
+               $cur = $dbr->tableName( 'cur' );
+
                return
                        "SELECT 'Longpages' as type,
                                        cur_namespace as namespace,
                                cur_title as title,
                                LENGTH(cur_text) AS value
-                       FROM cur
+                       FROM $cur
                        WHERE cur_namespace=0 AND cur_is_redirect=0";
        }
 
index 6e3f2d0..e294dea 100644 (file)
@@ -36,10 +36,10 @@ function wfSpecialMaintenance( $par=NULL )
        $ns = $wgLang->getNamespaces() ;
        $r = wfMsg("maintnancepagetext") ;
        $r .= "<UL>\n" ;
-       $r .= "<li>".getMPL("disambiguations")."</li>\n" ;
+       #$r .= "<li>".getMPL("disambiguations")."</li>\n" ; # Doesn't work
        $r .= "<li>".getMPL("doubleredirects")."</li>\n" ;
        $r .= "<li>".getMPL("brokenredirects")."</li>\n" ;
-       $r .= "<li>".getMPL("selflinks")."</li>\n" ;
+       #$r .= "<li>".getMPL("selflinks")."</li>\n" ; # Doesn't work
        $r .= "<li>".getMPL("mispeelings")."</li>\n" ;
 
        $r .= "<li>";
@@ -97,15 +97,17 @@ function wfSpecialDisambiguations()
        $fname = "wfSpecialDisambiguations";
 
        list( $limit, $offset ) = wfCheckLimits();
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'links', 'cur' ) );
 
-       $dp = wfStrencode( wfMsg("disambiguationspage") );
+       $dp = $dbr->strencode( wfMsg("disambiguationspage") );
        
        die( "wfSpecialDisambiguation is broken. Link tables have changed...\n" );
        
        $sql = "SELECT la.l_from,la.l_to,"
                . " lb.l_from AS source,lb.l_to AS dest,"
                . " c.cur_id, c.cur_title AS dt"
-               . " FROM links AS la, links AS lb, cur AS c, cur AS d"
+               . " FROM $links AS la, $links AS lb, $cur AS c, $cur AS d"
                . " WHERE la.l_from='{$dp}'"
                . " AND la.l_to=lb.l_to"
                . " AND la.l_from<>lb.l_from"
@@ -115,7 +117,7 @@ function wfSpecialDisambiguations()
                . " AND d.cur_namespace=0"
                . " LIMIT {$offset}, {$limit}";
 
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbr->query( $sql, $fname );
 
        $sk = $wgUser->getSkin();
 
@@ -129,13 +131,13 @@ function wfSpecialDisambiguations()
        $wgOut->addHTML( "<br>{$sl}\n" );
 
        $s = "<ol start=" . ( $offset + 1 ) . ">";
-       while ( $obj = wfFetchObject( $res ) ) {
+       while ( $obj = $dbr->fetchObject( $res ) ) {
                $l1 = $sk->makeKnownLink ( $obj->source , "" , "redirect=no" ) ;
                $l2 = $sk->makeKnownLink ( $obj->dt ) ;
                $l3 = $sk->makeBrokenLink ( $obj->source , "(".wfMsg("qbedit").")" , "redirect=no" ) ;
                $s .= "<li>{$l1} {$l3} => {$l2}</li>\n" ;
        }
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
        $s .= "</ol>";
        $wgOut->addHTML( $s );
        $wgOut->addHTML( "<p>{$sl}\n" );
@@ -147,15 +149,17 @@ function wfSpecialDoubleRedirects()
        $fname = "wfSpecialDoubleRedirects";
 
        list( $limit, $offset ) = wfCheckLimits();
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'cur', 'links' ) );
 
        $sql = "SELECT ca.cur_namespace as ns_a, ca.cur_title as title_a," . 
               "  cb.cur_namespace as ns_b, cb.cur_title as title_b," .
                   "  cb.cur_text AS rt " . 
-              "FROM links,cur AS ca,cur AS cb ". 
+              "FROM $links,$cur AS ca,$cur AS cb ". 
               "WHERE ca.cur_is_redirect=1 AND cb.cur_is_redirect=1 AND l_to=cb.cur_id " .
               "  AND l_from=ca.cur_id LIMIT {$offset}, {$limit}" ;
 
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbr->query( $sql, $fname );
 
        $top = getMaintenancePageBacklink( "doubleredirects" );
        $top .= "<p>".wfMsg("doubleredirectstext")."</p><br>\n";
@@ -168,7 +172,7 @@ function wfSpecialDoubleRedirects()
 
        $sk = $wgUser->getSkin();
        $s = "<ol start=" . ( $offset + 1 ) . ">";
-       while ( $obj = wfFetchObject( $res ) ) {
+       while ( $obj = $dbr->fetchObject( $res ) ) {
                $n = explode ( "\n" , $obj->rt ) ;
                $n = $n[0] ;
                $sourceTitle = Title::makeTitle( $obj->ns_a, $obj->title_a );
@@ -179,7 +183,7 @@ function wfSpecialDoubleRedirects()
                $l3 = $sk->makeBrokenLinkObj( $sourceTitle , "(".wfMsg("qbedit").")" , "redirect=no" ) ;
                $s .= "<li>{$l1} {$l3} => {$l2} (\"{$n}\")</li>\n" ;
        }
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
        $s .= "</ol>";
        $wgOut->addHTML( $s );
        $wgOut->addHTML( "<p>{$sl}\n" );
@@ -191,12 +195,15 @@ function wfSpecialBrokenRedirects()
        $fname = "wfSpecialBrokenRedirects";
 
        list( $limit, $offset ) = wfCheckLimits();
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'cur', 'brokenlinks' ) );
 
-       $sql = "SELECT bl_to,cur_title FROM brokenlinks,cur " .
+
+       $sql = "SELECT bl_to,cur_title FROM $brokenlinks,$cur " .
          "WHERE cur_is_redirect=1 AND cur_namespace=0 AND bl_from=cur_id " . 
          "LIMIT {$offset}, {$limit}" ;
 
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbr->query( $sql, $fname );
 
        $top = getMaintenancePageBacklink( "brokenredirects" );
        $top .= "<p>".wfMsg("brokenredirectstext")."</p><br>\n";
@@ -209,13 +216,13 @@ function wfSpecialBrokenRedirects()
 
        $sk = $wgUser->getSkin();
        $s = "<ol start=" . ( $offset + 1 ) . ">";
-       while ( $obj = wfFetchObject( $res ) ) {
+       while ( $obj = $dbr->fetchObject( $res ) ) {
                $l1 = $sk->makeKnownLink ( $obj->cur_title , "" , "redirect=no" ) ;
                $l2 = $sk->makeBrokenLink ( $obj->cur_title , "(".wfMsg("qbedit").")" , "redirect=no" ) ;
                $l3 = $sk->makeBrokenLink ( $obj->bl_to , "" , "redirect=no" ) ;
                $s .= "<li>{$l1} {$l2} => {$l3}</li>\n" ;
        }
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
        $s .= "</ol>";
        $wgOut->addHTML( $s );
        $wgOut->addHTML( "<p>{$sl}\n" );
@@ -234,7 +241,7 @@ function wfSpecialSelfLinks()
          "WHERE l_from=l_to AND l_to=cur_id " . 
          "LIMIT {$offset}, {$limit}";
 
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = wfQuery( $sql, DB_SLAVE, $fname );
 
        $top = getMaintenancePageBacklink( "selflinks" );
        $top .= "<p>".wfMsg("selflinkstext")."</p><br>\n";
@@ -264,18 +271,17 @@ function wfSpecialMispeelings ()
        $fname = "wfSpecialMispeelings";
 
        list( $limit, $offset ) = wfCheckLimits();
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'cur', 'searchindex' ) );
 
        # Determine page name
        $ms = wfMsg ( "mispeelingspage" ) ;
-       $mss = wfStrencode( str_replace ( " " , "_" , $ms ) );
+       $mss = str_replace ( " " , "_" , $ms );
        $msp = $wgLang->getNsText(4).":".$ms ;
        $msl = $sk->makeKnownLink ( $msp ) ;
 
        # Load list from database
-       $sql = "SELECT cur_text FROM cur WHERE cur_title='{$mss}' AND cur_namespace=4" ;
-       $res = wfQuery( $sql, DB_READ, $fname );
-       $obj = wfFetchObject ( $res ) ;
-       $l = $obj->cur_text ;
+       $l = $dbr->selectField( 'cur', 'cur_text', array( 'cur_title' => $mss, 'cur_namespace' => 4 ), $fname );
        $l = explode ( "\n" , $l ) ;
        $a = array () ;
        foreach ( $l as $x )
@@ -289,10 +295,11 @@ function wfSpecialMispeelings ()
                if ( $cnt < $offset+$limit && $x != "" ) {
                        $y = $x ;
                        $x = preg_replace( '/^(\S+).*$/', '$1', $x );
-                       #$sql = "SELECT DISTINCT cur_title FROM cur WHERE cur_namespace=0 AND cur_is_redirect=0 AND (MATCH(cur_ind_text) AGAINST ('" . wfStrencode( $wgLang->stripForSearch( $x ) ) . "'))" ;
-                       $sql = "SELECT DISTINCT cur_title FROM cur,searchindex WHERE cur_id=si_page AND cur_namespace=0 AND cur_is_redirect=0 AND (MATCH(si_text) AGAINST ('" . wfStrencode( $wgLang->stripForSearch( $x ) ) . "'))" ;
-                       $res = wfQuery( $sql, DB_READ, $fname );
-                       while ( $obj = wfFetchObject ( $res ) ) {
+                       $sql = "SELECT DISTINCT cur_title FROM $cur,$searchindex WHERE cur_id=si_page AND ".
+                               "cur_namespace=0 AND cur_is_redirect=0 AND " .
+                               "(MATCH(si_text) AGAINST ('" . $dbr->strencode( $wgLang->stripForSearch( $x ) ) . "'))" ;
+                       $res = $dbr->query( $sql, $fname );
+                       while ( $obj = $dbr->fetchObject ( $res ) ) {
                                if ( $cnt >= $offset AND $cnt < $offset+$limit ) {
                                        if ( $y != "" ) {
                                                if ( count ( $b ) > 0 ) $b[] = "</OL>\n" ;
@@ -334,13 +341,15 @@ function wfSpecialMissingLanguageLinks()
        if ( $thelang == "w" ) $thelang = "en" ; # Fix for international wikis
 
        list( $limit, $offset ) = wfCheckLimits();
+       $dbr =& wfGetDB( DB_SLAVE );
+       $cur = $dbr->tableName( 'cur' );
 
-       $sql = "SELECT cur_title FROM cur " .
+       $sql = "SELECT cur_title FROM $cur " .
          "WHERE cur_namespace=0 AND cur_is_redirect=0 " .
          "AND cur_title NOT LIKE '%/%' AND cur_text NOT LIKE '%[[{$thelang}:%' " .
          "LIMIT {$offset}, {$limit}";
 
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbr->query( $sql, $fname );
 
 
        $mll = wfMsg( "missinglanguagelinkstext", $wgLang->getLanguageName($thelang) );
@@ -356,9 +365,9 @@ function wfSpecialMissingLanguageLinks()
 
        $sk = $wgUser->getSkin();
        $s = "<ol start=" . ( $offset + 1 ) . ">";
-       while ( $obj = wfFetchObject( $res ) )
+       while ( $obj = $dbr->fetchObject( $res ) )
                $s .= "<li>".$sk->makeKnownLink ( $obj->cur_title )."</li>\n" ;
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
        $s .= "</ol>";
        $wgOut->addHTML( $s );
        $wgOut->addHTML( "<p>{$sl}\n" );
index a9564f1..622dd26 100644 (file)
@@ -123,40 +123,42 @@ class MakesysopForm {
        {
                global $wgOut, $wgUser, $wgLang;
                global $wgDBname, $wgMemc, $wgLocalDatabases;
-
+               
+               $dbw =& wfGetDB( DB_MASTER );
                $parts = explode( "@", $this->mUser );
-               if( count( $parts ) == 2 && $wgUser->isDeveloper() ){
-                       $username = wfStrencode( $parts[0] );
+               $usertable = $dbw->tableName( 'user' );
+
+               if( count( $parts ) == 2 && $wgUser->isDeveloper() && strpos( '.', $usertable ) === false ){
+                       $username = $dbw->strencode( $parts[0] );
                        if ( array_key_exists( $parts[1], $wgLocalDatabases ) ) {
                                $dbName = $wgLocalDatabases[$parts[1]];
-                               $usertable = $dbName . ".user";
+                               $usertable = $dbName . "." . $usertable;
                        } else {
                                $this->showFail();
                                return;
                        }
                } else {
                        $username = wfStrencode( $this->mUser );
-                       $usertable = "user";
                        $dbName = $wgDBname;
                }
                if ( $username{0} == "#" ) {
                        $id = intval( substr( $username, 1 ) );
-                       $sql = "SELECT user_id,user_rights FROM $usertable WHERE user_id=$id";
+                       $sql = "SELECT user_id,user_rights FROM $usertable WHERE user_id=$id FOR UPDATE";
                } else {
-                       $encName = wfStrencode( $username );
-                       $sql = "SELECT user_id, user_rights FROM $usertable WHERE user_name = '{$username}'";
+                       $encName = $dbw->strencode( $username );
+                       $sql = "SELECT user_id, user_rights FROM $usertable WHERE user_name = '{$username}' FOR UPDATE";
                }
                
-               $prev = wfIgnoreSQLErrors( TRUE );
-               $res = wfQuery( $sql, DB_WRITE );
-               wfIgnoreSQLErrors( $prev );
+               $prev = $dbw->setIgnoreErrors( TRUE );
+               $res = $dbw->query( $sql );
+               $dbw->setIgnoreSQLErrors( $prev );
 
-               if( wfLastErrno() || ! $username || wfNumRows( $res ) == 0 ){
+               if( $dbw->lastErrno() || ! $username || $dbw->numRows( $res ) == 0 ){
                        $this->showFail();
                        return;
                }
 
-               $row = wfFetchObject( $res );
+               $row = $dbw->fetchObject( $res );
                $id = intval( $row->user_id );
                $rightsNotation = array();
 
@@ -189,7 +191,7 @@ class MakesysopForm {
                        $this->showFail();
                } else {
                        $sql = "UPDATE $usertable SET user_rights = '{$newrights}' WHERE user_id = $id LIMIT 1";
-                       wfQuery($sql, DB_WRITE);
+                       $dbw->query($sql);
                        $wgMemc->delete( "$dbName:user:id:$id" );
                        
                        $bureaucratLog = wfMsg( "bureaucratlog" );
index 095bb7f..802e9f9 100644 (file)
@@ -15,6 +15,9 @@ class NewPagesPage extends QueryPage {
        }
 
        function getSQL() {
+               $dbr =& wfGetDB( DB_SLAVE );
+               extract( $dbr->tableNames( 'recentchanges', 'cur' ) );
+
                return
                        "SELECT 'Newpages' as type,
                                rc_namespace AS namespace,
@@ -27,7 +30,7 @@ class NewPagesPage extends QueryPage {
                                rc_timestamp AS timestamp,
                                length(cur_text) as length,
                                cur_text as text
-                       FROM recentchanges,cur
+                       FROM $recentchanges,$cur
                        WHERE rc_cur_id=cur_id AND rc_new=1
                          AND rc_namespace=0 AND cur_is_redirect=0";
        }
index e697433..23ad570 100644 (file)
@@ -14,12 +14,15 @@ class PopularPagesPage extends QueryPage {
        }
 
        function getSQL() {
+               $dbr =& wfGetDB( DB_SLAVE );
+               $cur = $dbr->tableName( 'cur' );
+
                return
                        "SELECT 'Popularpages' as type,
                                cur_namespace as namespace,
                                cur_title as title,
                                cur_counter as value
-                       FROM cur
+                       FROM $cur
                        WHERE cur_namespace=0 AND cur_is_redirect=0";
        }
 
index 0dd4b60..fa8c348 100644 (file)
@@ -6,19 +6,20 @@ function wfSpecialRandompage()
        global $wgOut, $wgTitle, $wgArticle, $wgExtraRandompageSQL;
        $fname = "wfSpecialRandompage";
 
-       wfSeedRandom();
        $rand = mt_rand() / mt_getrandmax();
        # interpolation and sprintf() can muck up with locale-specific decimal separator
        $randstr = number_format( $rand, 12, ".", "" );
-       $db =& wfGetDB( DB_READ );
+       $db =& wfGetDB( DB_SLAVE );
        $use_index = $db->useIndexClause( 'cur_random' );
+       $cur = $db->tableName( 'cur' );
+
        if ( $wgExtraRandompageSQL ) {
                $extra = "AND ($wgExtraRandompageSQL)";
        } else {
                $extra = '';
        }
        $sqlget = "SELECT cur_id,cur_title
-               FROM cur $use_index
+               FROM $cur $use_index
                WHERE cur_namespace=0 AND cur_is_redirect=0 $extra
                AND cur_random>$randstr
                ORDER BY cur_random
index 4470c76..2d378b2 100644 (file)
@@ -33,23 +33,24 @@ function wfSpecialRecentchanges( $par )
                if( in_array( "hideliu", $bits) ) $hideliu = 1;
        }
        
-       $sql = "SELECT MAX(rc_timestamp) AS lastmod FROM recentchanges";
-       $res = wfQuery( $sql, DB_READ, $fname );
-       $s = wfFetchObject( $res );
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'recentchanges', 'watchlist' ) );
+       
+       $lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, $fname );
        # 10 seconds server-side caching max
        $wgOut->setSquidMaxage( 10 );
-       if( $wgOut->checkLastModified( $s->lastmod ) ){
+       if( $wgOut->checkLastModified( $lastmod ) ){
                # Client cache fresh and headers sent, nothing more to do.
                return;
        }
 
-       $rctext = wfMsg( "recentchangestext" );
-       
        # The next few lines can probably be commented out now that wfMsg can get text from the DB
-       $sql = "SELECT cur_text FROM cur WHERE cur_namespace=4 AND cur_title='Recentchanges'";
-       $res = wfQuery( $sql, DB_READ, $fname );
-       if( ( $s = wfFetchObject( $res ) ) and ( $s->cur_text != "" ) ) {
-               $rctext = $s->cur_text;
+       $rctext = $dbr->selectField( 'cur', 'cur_text', 
+               array( 'cur_namespace' => NS_WIKIPEDIA, 'cur_title' => 'Recentchanges' ),
+               $fname
+       );
+       if( !$rctext ) {
+               $rctext = wfMsg( "recentchangestext" );
        }
        
        $wgOut->addWikiText( $rctext );
@@ -94,17 +95,18 @@ function wfSpecialRecentchanges( $par )
          $showhide[1-$hideliu], wfArrayToCGI( array( "hideliu" => 1-$hideliu ), $urlparams ) );
 
        $uid = $wgUser->getID();
-       $sql2 = "SELECT recentchanges.*" . ($uid ? ",wl_user" : "") . " FROM recentchanges " .
-         ($uid ? "LEFT OUTER JOIN watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace & 65534 " : "") .
+       $sql2 = "SELECT $recentchanges.*" . ($uid ? ",wl_user" : "") . " FROM $recentchanges " .
+         ($uid ? "LEFT OUTER JOIN $watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace & 65534 " : "") .
          "WHERE rc_timestamp > '{$cutoff}' {$hidem} " .
          "ORDER BY rc_timestamp DESC LIMIT {$limit}";
 
-       $res = wfQuery( $sql2, DB_READ, $fname );
+       $res = $dbr->query( $sql2, DB_SLAVE, $fname );
        $rows = array();
-       while( $row = wfFetchObject( $res ) ){ 
+       while( $row = $dbr->fetchObject( $res ) ){ 
                $rows[] = $row; 
        }
-
+       $dbr->freeResult( $res );
+       
        if(isset($from)) {
                $note = wfMsg( "rcnotefrom", $wgLang->formatNum( $limit ),
                        $wgLang->timeanddate( $from, true ) );
@@ -160,7 +162,6 @@ function wfSpecialRecentchanges( $par )
                $s .= $sk->endRecentChangesList();
                $wgOut->addHTML( $s );
        }
-       wfFreeResult( $res );
 }
 
 function rcCountLink( $lim, $d, $page="Recentchanges", $more="" )
index 88cd478..53bb972 100644 (file)
@@ -51,11 +51,14 @@ function wfSpecialRecentchangeslinked( $par = NULL )
                $cmq = "AND cur_minor_edit=0";
        } else { $cmq = ""; }
 
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'cur', 'links' ) );
+
        $sql = "SELECT cur_id,cur_namespace,cur_title,cur_user,cur_comment," .
-         "cur_user_text,cur_timestamp,cur_minor_edit,cur_is_new FROM links, cur " .
+         "cur_user_text,cur_timestamp,cur_minor_edit,cur_is_new FROM $links, $cur " .
          "WHERE cur_timestamp > '{$cutoff}' {$cmq} AND l_to=cur_id AND l_from=$id " .
       "GROUP BY cur_id ORDER BY inverse_timestamp LIMIT {$limit}";
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbr->query( $sql, $fname );
 
        $wgOut->addHTML("&lt; ".$sk->makeKnownLinkObj($nt, "", "redirect=no" )."<br />\n");
        $note = wfMsg( "rcnote", $limit, $days );
@@ -68,12 +71,12 @@ function wfSpecialRecentchangeslinked( $par = NULL )
        $wgOut->addHTML( "{$note}\n" );
 
        $s = $sk->beginRecentChangesList();
-       $count = wfNumRows( $res );
+       $count = $dbr->numRows( $res );
        
        $counter = 1;
        while ( $limit ) {
                if ( 0 == $count ) { break; }
-               $obj = wfFetchObject( $res );
+               $obj = $dbr->fetchObject( $res );
                --$count;
 
                $rc = RecentChange::newFromCurRow( $obj );
@@ -83,7 +86,7 @@ function wfSpecialRecentchangeslinked( $par = NULL )
        }
        $s .= $sk->endRecentChangesList();
 
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
        $wgOut->addHTML( $s );
 }
 
index c3eafc4..4feb514 100644 (file)
@@ -17,12 +17,15 @@ class ShortPagesPage extends QueryPage {
        }
 
        function getSQL() {
+               $dbr =& wfGetDB( DB_SLAVE );
+               $cur = $dbr->tableName( 'cur' );
+               
                return
                        "SELECT 'Shortpages' as type,
                                        cur_namespace as namespace,
                                cur_title as title,
                                LENGTH(cur_text) AS value
-                       FROM cur
+                       FROM $cur
                        WHERE cur_namespace=0 AND cur_is_redirect=0";
        }
        
index 883ef0f..6995c03 100644 (file)
@@ -7,17 +7,18 @@ function wfSpecialStatistics()
 
        $wgOut->addHTML( "<h2>" . wfMsg( "sitestats" ) . "</h2>\n" );
        
-       $db =& wfGetDB( DB_READ );
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'cur', 'site_stats', 'user' ) );
 
-       $sql = "SELECT COUNT(cur_id) AS total FROM cur";
-       $res = $db->query( $sql, $fname );
-       $row = $db->fetchObject( $res );
+       $sql = "SELECT COUNT(cur_id) AS total FROM $cur";
+       $res = $dbr->query( $sql, $fname );
+       $row = $dbr->fetchObject( $res );
        $total = $row->total;
 
        $sql = "SELECT ss_total_views, ss_total_edits, ss_good_articles " .
-         "FROM site_stats WHERE ss_row_id=1";
-       $res = $db->query( $sql, $fname );
-       $row = $db->fetchObject( $res );
+         "FROM $site_stats WHERE ss_row_id=1";
+       $res = $dbr->query( $sql, $fname );
+       $row = $dbr->fetchObject( $res );
        $views = $row->ss_total_views;
        $edits = $row->ss_total_edits;
        $good = $row->ss_good_articles;
@@ -33,16 +34,15 @@ function wfSpecialStatistics()
        $wgOut->addWikiText( $text );
        $wgOut->addHTML( "<h2>" . wfMsg( "userstats" ) . "</h2>\n" );
 
-       $usertable = $db->tableName( 'user' );
-       $sql = "SELECT COUNT(user_id) AS total FROM $usertable";
-       $res = $db->query( $sql, $fname );
-       $row = $db->fetchObject( $res );
+       $sql = "SELECT COUNT(user_id) AS total FROM $user";
+       $res = $dbr->query( $sql, $fname );
+       $row = $dbr->fetchObject( $res );
        $total = $row->total;
 
-       $sql = "SELECT COUNT(user_id) AS total FROM $usertable " .
+       $sql = "SELECT COUNT(user_id) AS total FROM $user " .
          "WHERE user_rights LIKE '%sysop%'";
-       $res = $db->query( $sql, $fname );
-       $row = $db->fetchObject( $res );
+       $res = $dbr->query( $sql, $fname );
+       $row = $dbr->fetchObject( $res );
        $admins = $row->total;
 
        $sk = $wgUser->getSkin();
index e504b31..c226aff 100644 (file)
@@ -47,9 +47,13 @@ class UndeleteForm {
                $fname = "UndeleteForm::showList";
                
                # List undeletable articles    
-               $sql = "SELECT ar_namespace,ar_title, COUNT(*) AS count FROM archive " . 
+               $dbr =& wfGetDB( DB_SLAVE );
+               $archive = $dbr->tableName( 'archive' );
+
+               $sql = "SELECT ar_namespace,ar_title, COUNT(*) AS count FROM $archive " . 
                  "GROUP BY ar_namespace,ar_title ORDER BY ar_namespace,ar_title";
-               $res = wfQuery( $sql, DB_READ, $fname );
+
+               $res = $dbr->query( $sql, $fname );
                
                $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
                $wgOut->addWikiText( wfMsg( "undeletepagetext" ) );
@@ -57,7 +61,7 @@ class UndeleteForm {
                $special = $wgLang->getNsText( Namespace::getSpecial() );
                $sk = $wgUser->getSkin();
                $wgOut->addHTML( "<ul>\n" );
-               while ($row = wfFetchObject( $res )) {
+               while ($row = $dbr->fetchObject( $res )) {
                        $n = ($row->ar_namespace ? 
                                ($wgLang->getNsText( $row->ar_namespace ) . ":") : "").
                                $row->ar_title;
@@ -77,12 +81,14 @@ class UndeleteForm {
                $fname = "UndeleteForm::showRevision";
 
                if(!preg_match("/[0-9]{14}/",$timestamp)) return 0;
-               
-               $sql = "SELECT ar_text,ar_flags FROM archive ". 
+
+               $dbr =& wfGetDB( DB_SLAVE );
+               $archive = $dbr->tableName( 'archive' );
+               $sql = "SELECT ar_text,ar_flags FROM $archive ". 
                  "WHERE ar_namespace={$namespace} AND ar_title='" .
-                 wfStrencode( $title ) . "' AND ar_timestamp='" . wfStrencode( $timestamp ) ."'";
-               $ret = wfQuery( $sql, DB_READ, $fname );
-               $row = wfFetchObject( $ret );
+                 $dbr->strencode( $title ) . "' AND ar_timestamp='" . $dbr->strencode( $timestamp ) ."'";
+               $ret = $dbr->query( $sql, $fname );
+               $row = $dbr->fetchObject( $ret );
                
                $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
                $wgOut->addWikiText( "(" . wfMsg( "undeleterevision", $wgLang->date($timestamp, true) )
@@ -96,26 +102,28 @@ class UndeleteForm {
                
                $sk = $wgUser->getSkin();
                $wgOut->setPagetitle( wfMsg( "undeletepage" ) );
+               $dbr =& wfGetDB( DB_SLAVE );
+               $archive = $dbr->tableName( 'archive' );
                
                # Get text of first revision
-               $sql = "SELECT ar_text FROM archive WHERE ar_namespace={$namespace} AND ar_title='" .
-                 wfStrencode( $title ) . "' ORDER BY ar_timestamp DESC LIMIT 1";
-               $ret = wfQuery( $sql, DB_READ );
+               $sql = "SELECT ar_text FROM $archive WHERE ar_namespace={$namespace} AND ar_title='" .
+                 $dbr->strencode( $title ) . "' ORDER BY ar_timestamp DESC LIMIT 1";
+               $ret = $dbr->query( $sql );
 
-               if( wfNumRows( $ret ) == 0 ) {
+               if( $dbr->numRows( $ret ) == 0 ) {
                        $wgOut->addWikiText( wfMsg( "nohistory" ) );
                        return 0;
                }
-               $row = wfFetchObject( $ret );
+               $row = $dbr->fetchObject( $ret );
                $wgOut->addWikiText( wfMsg( "undeletehistory" ) . "\n<hr>\n" . $row->ar_text );
 
                # Get remaining revisions
                $sql = "SELECT ar_minor_edit,ar_timestamp,ar_user,ar_user_text,ar_comment
-                 FROM archive WHERE ar_namespace={$namespace} AND ar_title='" . wfStrencode( $title ) .
+                 FROM archive WHERE ar_namespace={$namespace} AND ar_title='" . $dbr->strencode( $title ) .
                  "' ORDER BY ar_timestamp DESC";
-               $ret = wfQuery( $sql, DB_READ );
+               $ret = $dbr->query( $sql );
                # Ditch first row
-               $row = wfFetchObject( $ret );
+               $row = $dbr->fetchObject( $ret );
 
                $titleObj = Title::makeTitle( NS_SPECIAL, "Undelete" );
                $action = $titleObj->escapeLocalURL( "action=submit" );
@@ -127,8 +135,8 @@ class UndeleteForm {
        <input type=submit name=\"restore\" value=\"".wfMsg("undeletebtn")."\">
        </form>");
 
-               $log = wfGetSQL("cur", "cur_text", "cur_namespace=4 AND cur_title='".
-                 wfStrencode( wfMsg("dellogpage") ) . "'" );
+               $log = $dbr->selectField( "cur", "cur_text", 
+                       array( 'cur_namespace' => NS_WIKIPEDIA, 'cur_title' => wfMsg("dellogpage") ) );
                if(preg_match("/^(.*".
                        preg_quote( ($namespace ? ($wgLang->getNsText($namespace) . ":") : "")
                        . str_replace("_", " ", $title), "/" ).".*)$/m", $log, $m)) {
@@ -137,7 +145,7 @@ class UndeleteForm {
                
                $special = $wgLang->getNsText( Namespace::getSpecial() );
                $wgOut->addHTML("<ul>");
-               while( $row = wfFetchObject( $ret ) ) {
+               while( $row = $dbr->fetchObject( $ret ) ) {
                        $wgOut->addHTML( "<li>" .
                          $sk->makeKnownLink( $wgLang->specialPage( "Undelete" ),
                          $wgLang->timeanddate( $row->ar_timestamp, true ),
@@ -154,7 +162,7 @@ class UndeleteForm {
        /* private */ function undelete( $namespace, $title )
        {
                global $wgUser, $wgOut, $wgLang, $wgDeferredUpdateList;
-               global  $wgUseSquid, $wgInternalServer;
+               global  $wgUseSquid, $wgInternalServer, $wgLinkCache;
 
                $fname = "doUndeleteArticle";
 
@@ -162,30 +170,35 @@ class UndeleteForm {
                        $wgOut->fatalError( wfMsg( "cannotundelete" ) );
                        return;
                }
-               $t = wfStrencode($title);
+               $dbw =& wfGetDB( DB_MASTER );
+               extract( $dbw->tableNames( 'cur', 'archive' ) );
+               $t = $dbw->strencode($title);
 
                # Move article and history from the "archive" table
-               $sql = "SELECT COUNT(*) AS count FROM cur WHERE cur_namespace={$namespace} AND cur_title='{$t}'";
-               $res = wfQuery( $sql, DB_READ );
-               $row = wfFetchObject( $res );
+               $sql = "SELECT COUNT(*) AS count FROM $cur WHERE cur_namespace={$namespace} AND cur_title='{$t}' FOR UPDATE";
+               $res = $dbw->query( $sql, $fname );
+               $row = $dbw->fetchObject( $res );
                $now = wfTimestampNow();
 
                if( $row->count == 0) {
                        # Have to create new article...
-                       $sql = "SELECT ar_text,ar_timestamp,ar_flags FROM archive WHERE ar_namespace={$namespace} AND ar_title='{$t}' ORDER BY ar_timestamp DESC LIMIT 1";
-                       $res = wfQuery( $sql, DB_READ, $fname );
-                       $s = wfFetchObject( $res );
+                       $sql = "SELECT ar_text,ar_timestamp,ar_flags FROM $archive WHERE ar_namespace={$namespace} AND ar_title='{$t}' " .
+                               "ORDER BY ar_timestamp DESC LIMIT 1 FOR UPDATE";
+                       $res = $dbw->query( $sql, $fname );
+                       $s = $dbw->fetchObject( $res );
                        $max = $s->ar_timestamp;
                        $redirect = MagicWord::get( MAG_REDIRECT );
                        $redir = $redirect->matchStart( $s->ar_text ) ? 1 : 0;
                        
-                       $sql = "INSERT INTO cur (cur_namespace,cur_title,cur_text," .
+                       $seqVal = addQuotes( $dbw->nextSequenceValue( 'cur_cur_id_seq' ) );
+
+                       $sql = "INSERT INTO $cur (cur_id,cur_namespace,cur_title,cur_text," .
                          "cur_comment,cur_user,cur_user_text,cur_timestamp,inverse_timestamp,cur_minor_edit,cur_is_redirect,cur_random,cur_touched)" .
-                         "SELECT ar_namespace,ar_title,ar_text,ar_comment," .
-                         "ar_user,ar_user_text,ar_timestamp,99999999999999-ar_timestamp,ar_minor_edit,{$redir},RAND(),'{$now}' FROM archive " .
+                         "SELECT $seqVal,ar_namespace,ar_title,ar_text,ar_comment," .
+                         "ar_user,ar_user_text,ar_timestamp,99999999999999-ar_timestamp,ar_minor_edit,{$redir},RAND(),'{$now}' FROM $archive " .
                          "WHERE ar_namespace={$namespace} AND ar_title='{$t}' AND ar_timestamp={$max}";
-                       wfQuery( $sql, DB_WRITE, $fname );
-                       $newid = wfInsertId();
+                       $dbw->query( $sql, $fname );
+                       $newid = $dbw->insertId();
                        $oldones = "AND ar_timestamp<{$max}";
                } else {
                        # If already exists, put history entirely into old table
@@ -193,45 +206,46 @@ class UndeleteForm {
                        $newid = 0;
                        
                        # But to make the history list show up right, we need to touch it.
-                       $sql = "UPDATE cur SET cur_touched='{$now}' WHERE cur_namespace={$namespace} AND cur_title='{$t}'";
-                       wfQuery( $sql, DB_WRITE, $fname );
+                       $sql = "UPDATE $cur SET cur_touched='{$now}' WHERE cur_namespace={$namespace} AND cur_title='{$t}'";
+                       $dbw->query( $sql, $fname );
                        
                        # FIXME: Sometimes restored entries will be _newer_ than the current version.
                        # We should merge.
                }
                
-               $sql = "INSERT INTO old (old_namespace,old_title,old_text," .
+               $sql = "INSERT INTO $old (old_namespace,old_title,old_text," .
                  "old_comment,old_user,old_user_text,old_timestamp,inverse_timestamp,old_minor_edit," .
                  "old_flags) SELECT ar_namespace,ar_title,ar_text,ar_comment," .
                  "ar_user,ar_user_text,ar_timestamp,99999999999999-ar_timestamp,ar_minor_edit,ar_flags " .
-                 "FROM archive WHERE ar_namespace={$namespace} AND ar_title='{$t}' {$oldones}";
-               wfQuery( $sql, DB_WRITE, $fname );
+                 "FROM $archive WHERE ar_namespace={$namespace} AND ar_title='{$t}' {$oldones}";
+               $dbw->query( $sql, $fname );
 
                # Finally, clean up the link tables 
                if( $newid ) {
+                       $wgLinkCache = new LinkCache();
+                       # Select for update
+                       $wgLinkCache->forUpdate( true );
                        # Create a dummy OutputPage to update the outgoing links
-                       # This works at the moment due to good luck. It may stop working in the 
-                       # future. Damn globals.
                        $dummyOut = new OutputPage();
-                       $res = wfQuery( "SELECT cur_text FROM cur WHERE cur_id={$newid} " .
-                         "AND cur_namespace={$namespace}", DB_READ, $fname );
-                       $row = wfFetchObject( $res );
-                       $text = $row->cur_text;
+                       # Get the text
+                       $text = $dbw->selectField( 'cur', 'cur_text', 
+                               array( 'cur_id' => $newid, 'cur_namespace' => $namespace ), 
+                               $fname, 'FOR UPDATE' 
+                       );
                        $dummyOut->addWikiText( $text );
-                       wfFreeResult( $res );
 
                        $u = new LinksUpdate( $newid, $this->mTargetObj->getPrefixedDBkey() );
                        array_push( $wgDeferredUpdateList, $u );
-                               
+                       
                        Article::onArticleCreate( $this->mTargetObj );
 
                        #TODO: SearchUpdate, etc.
                }
 
                # Now that it's safely stored, take it out of the archive
-               $sql = "DELETE FROM archive WHERE ar_namespace={$namespace} AND " .
+               $sql = "DELETE FROM $archive WHERE ar_namespace={$namespace} AND " .
                  "ar_title='{$t}'";
-               wfQuery( $sql, DB_WRITE, $fname );
+               $dbw->query( $sql, $fname );
 
                
                # Touch the log?
index 4bc8d7b..1807e41 100644 (file)
@@ -5,11 +5,13 @@ function wfSpecialUnusedimages() {
        $fname = "wfSpecialUnusedimages";
 
        list( $limit, $offset ) = wfCheckLimits();
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'image','imagelinks' ) );
 
        $sql = "SELECT img_name,img_user,img_user_text,img_timestamp,img_description " .
-         "FROM image LEFT JOIN imagelinks ON img_name=il_to WHERE il_to IS NULL " .
+         "FROM $image LEFT JOIN $imagelinks ON img_name=il_to WHERE il_to IS NULL " .
          "ORDER BY img_timestamp ".wfLimitResult($limit,$offset);
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbr->query( $sql, $fname );
 
        $sk = $wgUser->getSkin();
 
@@ -23,7 +25,7 @@ function wfSpecialUnusedimages() {
 
        $ins = $wgLang->getNsText ( 6 ) ;
        $s = "<ol start='" . ( $offset + 1 ) . "'>";
-       while ( $obj = wfFetchObject( $res ) ) {
+       while ( $obj = $dbr->fetchObject( $res ) ) {
                $name = $obj->img_name;
                $dlink = $sk->makeKnownLink( "{$ins}:{$name}", wfMsg( "imgdesc" ) );
                $ilink = "<a href=\"" . Image::wfImageUrl( $name ) . "\">{$name}</a>";
@@ -41,7 +43,7 @@ function wfSpecialUnusedimages() {
                if ( "" != $c && "*" != $c ) { $s .= " <em>({$c})</em>"; }
                $s .= "</li>\n";
        }
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
        $s .= "</ol>\n\n";
        $wgOut->addHTML( $s );
        $wgOut->addHTML( "<p>{$sl}</p>\n" );
index bf2d630..95e65b6 100644 (file)
@@ -13,6 +13,9 @@ class WantedPagesPage extends QueryPage {
        }
 
        function getSQL() {
+               $dbr =& wfGetDB( DB_SLAVE );
+               $brokenlinks = $dbr->tableName( 'brokenlinks' );
+
                # We cheat and return the full-text from bl_to in the title.
                # In the future, a pre-parsed name will be available.
                return
@@ -20,7 +23,7 @@ class WantedPagesPage extends QueryPage {
                                0 as namespace,
                                bl_to as title,
                                COUNT(DISTINCT bl_from) as value
-                       FROM brokenlinks
+                       FROM $brokenlinks
                        GROUP BY bl_to
                        HAVING value > 1";
        }
index ba93309..b80dd24 100644 (file)
@@ -51,9 +51,12 @@ function wfSpecialWatchlist()
                }
        }
        
-       $sql = "SELECT COUNT(*) AS n FROM watchlist WHERE wl_user=$uid";
-       $res = wfQuery( $sql, DB_READ );
-       $s = wfFetchObject( $res );
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'cur', 'watchlist', 'recentchanges' ) );
+
+       $sql = "SELECT COUNT(*) AS n FROM $watchlist WHERE wl_user=$uid";
+       $res = $dbr->query( $sql );
+       $s = $dbr->fetchObject( $res );
        $nitems = $s->n;
        if($nitems == 0) {
         $wgOut->addHTML( wfMsg( "nowatchlist" ) );
@@ -80,9 +83,9 @@ function wfSpecialWatchlist()
                $docutoff = "AND cur_timestamp > '" .
                  ( $cutoff = wfUnix2Timestamp( time() - intval( $days * 86400 ) ) )
                  . "'";
-               $sql = "SELECT COUNT(*) AS n FROM cur WHERE cur_timestamp>'$cutoff'";
-               $res = wfQuery( $sql, DB_READ );
-               $s = wfFetchObject( $res );
+               $sql = "SELECT COUNT(*) AS n FROM $cur WHERE cur_timestamp>'$cutoff'";
+               $res = $dbr->query( $sql );
+               $s = $dbr->fetchObject( $res );
                $npages = $s->n;
                
        }
@@ -95,11 +98,11 @@ function wfSpecialWatchlist()
                        $specialTitle->escapeLocalUrl( "action=submit" ) .
                        "' method='post'>\n" .
                        "<ul>\n" );
-               $sql = "SELECT wl_namespace,wl_title FROM watchlist WHERE wl_user=$uid";
-               $res = wfQuery( $sql, DB_READ );
+               $sql = "SELECT wl_namespace,wl_title FROM $watchlist WHERE wl_user=$uid";
+               $res = $dbr->query( $sql );
                global $wgUser, $wgLang;
                $sk = $wgUser->getSkin();
-               while( $s = wfFetchObject( $res ) ) {
+               while( $s = $dbr->fetchObject( $res ) ) {
                        $t = Title::makeTitle( $s->wl_namespace, $s->wl_title );
                        if( is_null( $t ) ) {
                                $wgOut->addHTML( '<!-- bad title "' . htmlspecialchars( $s->wl_title ) . '" in namespace ' . IntVal( $s->wl_namespace ) . " -->\n" );
@@ -140,11 +143,11 @@ function wfSpecialWatchlist()
                $wgLang->formatNum( $nitems ), $wgLang->formatNum( $npages ), $y,
                $specialTitle->escapeLocalUrl( "magic=yes" ) ) . "</i><br />\n" );
         
-       $use_index = wfUseIndexClause( $x, DB_READ );
+       $use_index = $dbr->useIndexClause( $x );
        $sql = "SELECT
   cur_namespace,cur_title,cur_comment, cur_id,
   cur_user,cur_user_text,cur_timestamp,cur_minor_edit,cur_is_new
-  FROM watchlist,cur $use_index
+  FROM $watchlist,$cur $use_index
   WHERE wl_user=$uid
   AND $z
   AND wl_title=cur_title
@@ -152,7 +155,7 @@ function wfSpecialWatchlist()
   ORDER BY cur_timestamp DESC";
 
 
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbr->query( $sql, $fname );
 
        if($days >= 1)
                $note = wfMsg( "rcnote", $wgLang->formatNum( $limit ), $wgLang->formatNum( $days ) );
@@ -164,7 +167,7 @@ function wfSpecialWatchlist()
        $note = wlCutoffLinks( $days, $limit );
        $wgOut->addHTML( "{$note}\n" );
 
-       if ( wfNumRows( $res ) == 0 ) {
+       if ( $dbr->numRows( $res ) == 0 ) {
                $wgOut->addHTML( "<p><i>" . wfMsg( "watchnochange" ) . "</i></p>" );
                return;
        }
@@ -172,7 +175,7 @@ function wfSpecialWatchlist()
        $sk = $wgUser->getSkin();
        $s = $sk->beginRecentChangesList();
        $counter = 1;
-       while ( $obj = wfFetchObject( $res ) ) {
+       while ( $obj = $dbr->fetchObject( $res ) ) {
                # Make fake RC entry
                $rc = RecentChange::newFromCurRow( $obj );
                $rc->counter = $counter++;
@@ -180,7 +183,7 @@ function wfSpecialWatchlist()
        }
        $s .= $sk->endRecentChangesList();
 
-       wfFreeResult( $res );
+       $dbr->freeResult( $res );
        $wgOut->addHTML( $s );
 
        if ( $wgUseWatchlistCache ) {
index d8770bb..92a4931 100644 (file)
@@ -28,19 +28,21 @@ function wfSpecialWhatlinkshere($par = NULL)
        $isredir = " (" . wfMsg( "isredirect" ) . ")\n";
 
        $wgOut->addHTML("&lt; ".$sk->makeKnownLinkObj($nt, "", "redirect=no" )."<br />\n");
-       
+       $dbr =& wfGetDB( DB_SLAVE );
+       extract( $dbr->tableNames( 'cur', 'brokenlinks', 'links' ) );
+
        if ( 0 == $id ) {
-               $sql = "SELECT cur_id,cur_namespace,cur_title,cur_is_redirect FROM brokenlinks,cur WHERE bl_to='" .
-                 wfStrencode( $nt->getPrefixedDBkey() ) . "' AND bl_from=cur_id LIMIT $limit";
-               $res = wfQuery( $sql, DB_READ, $fname );
+               $sql = "SELECT cur_id,cur_namespace,cur_title,cur_is_redirect FROM $brokenlinks,$cur WHERE bl_to='" .
+                 $dbr->strencode( $nt->getPrefixedDBkey() ) . "' AND bl_from=cur_id LIMIT $limit";
+               $res = $dbr->query( $sql, $fname );
 
-               if ( 0 == wfNumRows( $res ) ) {
+               if ( 0 == $dbr->numRows( $res ) ) {
                        $wgOut->addHTML( wfMsg( "nolinkshere" ) );
                } else {
                        $wgOut->addHTML( wfMsg( "linkshere" ) );
                        $wgOut->addHTML( "\n<ul>" );
 
-                       while ( $row = wfFetchObject( $res ) ) {
+                       while ( $row = $dbr->fetchObject( $res ) ) {
                                $nt = Title::makeTitle( $row->cur_namespace, $row->cur_title );
                                if( !$nt ) {
                                        continue;
@@ -55,7 +57,7 @@ function wfSpecialWhatlinkshere($par = NULL)
                                $wgOut->addHTML( "</li>\n" );
                        }
                        $wgOut->addHTML( "</ul>\n" );
-                       wfFreeResult( $res );
+                       $dbr->freeResult( $res );
                }
        } else {
                wfShowIndirectLinks( 0, $id, $limit );
@@ -67,10 +69,13 @@ function wfShowIndirectLinks( $level, $lid, $limit )
        global $wgOut, $wgUser;
        $fname = "wfShowIndirectLinks";
 
-       $sql = "SELECT cur_id,cur_namespace,cur_title,cur_is_redirect FROM links,cur WHERE l_to={$lid} AND l_from=cur_id LIMIT $limit";
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $dbr =& wfGetDB( DB_READ );
+       extract( $dbr->tableNames( 'links','cur' ) );
+
+       $sql = "SELECT cur_id,cur_namespace,cur_title,cur_is_redirect FROM $links,$cur WHERE l_to={$lid} AND l_from=cur_id LIMIT $limit";
+       $res = $dbr->query( $sql, $fname );
 
-       if ( 0 == wfNumRows( $res ) ) {
+       if ( 0 == $dbr->numRows( $res ) ) {
                if ( 0 == $level ) {
                        $wgOut->addHTML( wfMsg( "nolinkshere" ) );
                }
@@ -83,27 +88,27 @@ function wfShowIndirectLinks( $level, $lid, $limit )
        $isredir = " (" . wfMsg( "isredirect" ) . ")\n";
 
        $wgOut->addHTML( "<ul>" );
-       while ( $row = wfFetchObject( $res ) ) {
+       while ( $row = $dbr->fetchObject( $res ) ) {
                $nt = Title::makeTitle( $row->cur_namespace, $row->cur_title );
                if( !$nt ) {
                        $wgOut->addHTML( "<!-- bad backlink: " . htmlspecialchars( $row->l_from ) . " -->\n" );
                        continue;
                }
-               
+
                if ( $row->cur_is_redirect ) {
-                   $extra = "redirect=no";
+                       $extra = "redirect=no";
                } else {
-                   $extra = "";
+                       $extra = "";
                }
-           
+
                $link = $sk->makeKnownLinkObj( $nt, "", $extra );
                $wgOut->addHTML( "<li>{$link}" );
 
                if ( $row->cur_is_redirect ) {
-                   $wgOut->addHTML( $isredir );
-                   if ( $level < 2 ) {
-                       wfShowIndirectLinks( $level + 1, $row->cur_id, $limit );
-                   }
+                       $wgOut->addHTML( $isredir );
+                       if ( $level < 2 ) {
+                               wfShowIndirectLinks( $level + 1, $row->cur_id, $limit );
+                       }
                }
                $wgOut->addHTML( "</li>\n" );
        }
index 154b3d5..d78bdca 100644 (file)
@@ -18,36 +18,54 @@ class SquidUpdate {
        }
 
        /* static */ function newFromLinksTo( &$title ) {
+               $fname = 'SquidUpdate::newFromLinksTo';
+               wfProfileIn( $fname );
+
                # Get a list of URLs linking to this page
                $id = $title->getArticleID();
-               $sql = "SELECT cur_namespace,cur_title FROM links,cur WHERE l_to={$id} and l_from=cur_id" ;
-               $res = wfQuery ( $sql, DB_READ ) ;
+
+               $dbr =& wfGetDB( DB_SLAVE );
+               $links = $dbr->tableName( 'links' );
+               $cur = $dbr->tableName( 'cur' );
+
+               $sql = "SELECT cur_namespace,cur_title FROM $links,$cur WHERE l_to={$id} and l_from=cur_id" ;
+               $res = $dbr->query( $sql, $fname ) ;
                $blurlArr = $title->getSquidURLs();
-               if ( wfNumRows( $res ) <= $this->mMaxTitles ) {
-                       while ( $BL = wfFetchObject ( $res ) )
+               if ( $dbr->numRows( $res ) <= $this->mMaxTitles ) {
+                       while ( $BL = $dbr->fetchObject ( $res ) )
                        {
                                $tobj = Title::makeTitle( $BL->cur_namespace, $BL->cur_title ) ; 
                                $blurlArr[] = $tobj->getInternalURL();
                        }
                }
-               wfFreeResult ( $res ) ;
+               $dbr->freeResult ( $res ) ;
+
+               wfProfileOut( $fname );
                return new SquidUpdate( $blurlArr );
        }
 
        /* static */ function newFromBrokenLinksTo( &$title ) {
+               $fname = 'SquidUpdate::newFromBrokenLinksTo';
+               wfProfileIn( $fname );
+
                # Get a list of URLs linking to this (currently non-existent) page
-               $encTitle = $title->getPrefixedDBkey();
-               $sql = "SELECT cur_namespace,cur_title FROM brokenlinks,cur WHERE bl_to={$encTitle} AND bl_from=cur_id";
-               $res = wfQuery( $sql, DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
+               $brokenlinks = $dbr->tableName( 'brokenlinks' );
+               $cur = $dbr->tableName( 'cur' );
+               $encTitle = $dbr->addQuotes( $title->getPrefixedDBkey() );
+
+               $sql = "SELECT cur_namespace,cur_title FROM $brokenlinks,$cur WHERE bl_to={$encTitle} AND bl_from=cur_id";
+               $res = $dbr->query( $sql, $fname );
                $blurlArr = array();
-               if ( wfNumRows( $res ) <= $this->mMaxTitles ) {
-                       while ( $BL = wfFetchObject( $res ) )
+               if ( $dbr->numRows( $res ) <= $this->mMaxTitles ) {
+                       while ( $BL = $dbr->fetchObject( $res ) )
                        {
                                $tobj = Title::makeTitle( $BL->cur_namespace, $BL->cur_title );
                                $blurlArr[] = $tobj->getInternalURL();
                        }
                }
-               wfFreeResult( $res );
+               $dbr->freeResult( $res );
+               wfProfileOut( $fname );
                return new SquidUpdate( $blurlArr );
        }
 
@@ -73,6 +91,9 @@ class SquidUpdate {
                        return;
                }
 
+               $fname = 'SquidUpdate::purge';
+               wfProfileIn( $fname );
+               
                $maxsocketspersquid = 8; //  socket cap per Squid
                $urlspersocket = 400; // 400 seems to be a good tradeoff, opening a socket takes a while
                $firsturl = $urlArr[0];
@@ -169,6 +190,7 @@ class SquidUpdate {
                        @fclose($socket);
                }
                #$this->debug("\n");
+               wfProfileOut( $fname );
        }
 
        function debug( $text ) {
index 14728c8..b2f39bc 100644 (file)
@@ -110,7 +110,7 @@ class Title {
                $t->mDbkeyform = str_replace( " ", "_", $s );
                if( $t->secureAndSplit() ) {
                        # check that length of title is < cur_title size
-                       $dbr =& wfGetDB( DB_READ );
+                       $dbr =& wfGetDB( DB_SLAVE );
                        $maxSize = $dbr->textFieldSize( 'cur', 'cur_title' );
                        if ( $maxSize != -1 && strlen( $t->mDbkeyform ) > $maxSize ) {
                                return NULL;
@@ -128,7 +128,7 @@ class Title {
        /* static */ function newFromID( $id ) 
        {
                $fname = "Title::newFromID";
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $row = $dbr->getArray( "cur", array( "cur_namespace", "cur_title" ), 
                        array( "cur_id" => $id ), $fname );
                if ( $row !== false ) {
@@ -164,7 +164,7 @@ class Title {
        /* static */ function nameOf( $id )
        {
                $fname = 'Title::nameOf';
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                
                $s = $dbr->getArray( 'cur', array( 'cur_namespace','cur_title' ),  array( 'cur_id' => $id ), $fname );
                if ( $s === false ) { return NULL; }
@@ -247,7 +247,7 @@ class Title {
                        $wgTitleInterwikiCache[$k] = $s;
                        return $s->iw_url;
                }
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $res = $dbr->select( 'interwiki', array( 'iw_url', 'iw_local' ), array( 'iw_prefix' => $key ), $fname );
                 if(!$res) return "";
                
@@ -285,7 +285,7 @@ class Title {
                if ( $timestamp == "" ) {
                        $timestamp = wfTimestampNow();
                }
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $cur = $dbw->tableName( 'cur' );
                $sql = "UPDATE $cur SET cur_touched='{$timestamp}' WHERE cur_id IN (";
                $first = true;
@@ -558,7 +558,7 @@ class Title {
                if ( 0 == $id ) { return array(); }
 
                if ( ! $this->mRestrictionsLoaded ) {
-                       $dbr =& wfGetDB( DB_READ );
+                       $dbr =& wfGetDB( DB_SLAVE );
                        $res = $dbr->getField( "cur", "cur_restrictions", "cur_id=$id" );
                        $this->mRestrictions = explode( ",", trim( $res ) );
                        $this->mRestrictionsLoaded = true;
@@ -570,7 +570,7 @@ class Title {
        # Returns the number of archived revisions
        function isDeleted() {
                $fname = 'Title::isDeleted';
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $n = $dbr->getField( 'archive', 'COUNT(*)', array( 'ar_namespace' => $this->getNamespace(), 
                        'ar_title' => $this->getDBkey() ), $fname );
                return (int)$n;
@@ -605,7 +605,7 @@ class Title {
        # Called from LinksUpdate.php
        function invalidateCache() {
                $now = wfTimestampNow();
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $success = $dbw->updateArray( 'cur', 
                        array( /* SET */ 
                                'cur_touched' => wfTimestampNow()
@@ -776,9 +776,9 @@ class Title {
                $id = $this->getArticleID();
                
                if ( $options ) {
-                       $db =& wfGetDB( DB_WRITE );
+                       $db =& wfGetDB( DB_MASTER );
                } else {
-                       $db =& wfGetDB( DB_READ );
+                       $db =& wfGetDB( DB_SLAVE );
                }
                $cur = $db->tableName( 'cur' );
                $links = $db->tableName( 'links' );
@@ -804,9 +804,9 @@ class Title {
                global $wgLinkCache;
                
                if ( $options ) {
-                       $db =& wfGetDB( DB_WRITE );
+                       $db =& wfGetDB( DB_MASTER );
                } else {
-                       $db =& wfGetDB( DB_READ );
+                       $db =& wfGetDB( DB_SLAVE );
                }
                $cur = $db->tableName( 'cur' );
                $brokenlinks = $db->tableName( 'brokenlinks' );
@@ -912,7 +912,7 @@ class Title {
         $won = wfInvertTimestamp( $now );
                $newid = $nt->getArticleID();
                $oldid = $this->getArticleID();
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $links = $dbw->tableName( 'links' );
 
                # Change the name of the target page:
@@ -1008,7 +1008,7 @@ class Title {
                                $sql .= "($id, $oldid)";
                        }
 
-                       $dbw->query( $sql, DB_WRITE, $fname );
+                       $dbw->query( $sql, DB_MASTER, $fname );
                }
 
                # Now, we record the link from the redirect to the new title.
@@ -1041,7 +1041,7 @@ class Title {
                $won = wfInvertTimestamp( $now );
                $newid = $nt->getArticleID();
                $oldid = $this->getArticleID();
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
 
                # Rename cur entry
                $dbw->updateArray( 'cur',
@@ -1122,7 +1122,7 @@ class Title {
        function isValidMoveTarget( $nt )
        {
                $fname = "Title::isValidMoveTarget";
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
 
                # Is it a redirect?
                $id  = $nt->getArticleID();
@@ -1163,7 +1163,7 @@ class Title {
                }
                
                $fname = "Title::createRedirect";
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $now = wfTimestampNow();
                $won = wfInvertTimestamp( $now );
                $seqVal = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
@@ -1216,7 +1216,7 @@ class Title {
                $cns = Namespace::getCategory();
                $sk =& $wgUser->getSkin();
                $parents = array();
-               $dbr =& wfGetDB( DB_READ );
+               $dbr =& wfGetDB( DB_SLAVE );
                $cur = $dbr->tableName( 'cur' );
                $categorylinks = $dbr->tableName( 'categorylinks' );
 
@@ -1286,6 +1286,13 @@ class Title {
                else { return ''; };
        }
        
-       
+       # Returns an associative array for selecting this title from cur
+       function curCond() {
+               return array( 'cur_namespace' => $this->mNamespace, 'cur_title' => $this->mDbkeyform );
+       }
+
+       function oldCond() {
+               return array( 'old_namespace' => $this->mNamespace, 'old_title' => $this->mDbkeyform );
+       }
 }
 ?>
index 322ae18..9170ce7 100644 (file)
@@ -11,7 +11,8 @@ class User {
        /* private */ var $mBlockedby, $mBlockreason;
        /* private */ var $mTouched;
        /* private */ var $mCookiePassword;
-        /* private */ var $mRealName;
+       /* private */ var $mRealName;
+       /* private */ var $mHash;
 
        function User() {
                $this->loadDefaults();
@@ -30,28 +31,29 @@ class User {
        }
 
        /* static */ function whoIs( $id )      {
-               return wfGetSQL( 'user', 'user_name', 'user_id='.$id );
+               $dbr =& wfGetDB( DB_SLAVE );
+               return $dbr->getField( 'user', 'user_name', array( 'user_id' => $id ) );
        }
 
        /* static */ function whoIsReal( $id )  {
-               return wfGetSQL( 'user', 'user_real_name', 'user_id='.$id );
+               $dbr =& wfGetDB( DB_SLAVE );
+               return $dbr->getField( 'user', 'user_real_name', array( 'user_id' => $id ) );
        }
 
        /* static */ function idFromName( $name ) {
+               $fname = "User::idFromName";
+
                $nt = Title::newFromText( $name );
                if( is_null( $nt ) ) {
                        # Illegal name
                        return null;
                }
-               $sql = "SELECT user_id FROM user WHERE user_name='" .
-                 wfStrencode( $nt->getText() ) . "'";
-               $res = wfQuery( $sql, DB_READ, 'User::idFromName' );
+               $dbr =& wfGetDB( DB_SLAVE );
+               $s = $dbr->getArray( 'user', array( 'user_id' ), array( 'user_name' => $nt->getText() ), $fname );
 
-               if ( 0 == wfNumRows( $res ) ) {
+               if ( $s === false ) {
                        return 0;
                } else {
-                       $s = wfFetchObject( $res );
-                       wfFreeResult( $res );
                        return $s->user_id;
                }
        }
@@ -66,7 +68,6 @@ class User {
                $pwchars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz';
                $l = strlen( $pwchars ) - 1;
 
-               wfSeedRandom();
                $np = $pwchars{mt_rand( 0, $l )} . $pwchars{mt_rand( 0, $l )} .
                  $pwchars{mt_rand( 0, $l )} . chr( mt_rand(48, 57) ) .
                  $pwchars{mt_rand( 0, $l )} . $pwchars{mt_rand( 0, $l )} .
@@ -95,6 +96,7 @@ class User {
                $this->mBlockedby = -1; # Unset
                $this->mTouched = '0'; # Allow any pages to be cached
                $this->cookiePassword = '';
+               $this->mHash = false;
        }
 
        /* private */ function getBlockedStatus()
@@ -221,6 +223,7 @@ class User {
        function loadFromDatabase()
        {
                global $wgCommandLineMode;
+               $fname = "User::loadFromDatabase";
                if ( $this->mDataLoaded || $wgCommandLineMode ) {
                        return;
                }
@@ -230,24 +233,23 @@ class User {
 
                # check in separate table if there are changes to the talk page
                $this->mNewtalk=0; # reset talk page status
+               $dbr =& wfGetDB( DB_SLAVE );
                if($this->mId) {
-                       $sql = "SELECT 1 FROM user_newtalk WHERE user_id={$this->mId}";
-                       $res = wfQuery ($sql, DB_READ, "User::loadFromDatabase" );
+                       $res = $dbr->select( 'user_newtalk', 1, array( 'user_id' => $this->mId ), $fname );
 
-                       if (wfNumRows($res)>0) {
+                       if ( $dbr->numRows($res)>0 ) {
                                $this->mNewtalk= 1;
                        }
-                       wfFreeResult( $res );
+                       $dbr->freeResult( $res );
                } else {
                        global $wgDBname, $wgMemc;
                        $key = "$wgDBname:newtalk:ip:{$this->mName}";
                        $newtalk = $wgMemc->get( $key );
                        if( ! is_integer( $newtalk ) ){
-                               $sql = "SELECT 1 FROM user_newtalk WHERE user_ip='{$this->mName}'";
-                               $res = wfQuery ($sql, DB_READ, "User::loadFromDatabase" );
+                               $res = $dbr->select( 'user_newtalk', 1, array( 'user_ip' => $this->mName ), $fname );
 
-                               $this->mNewtalk = (wfNumRows($res)>0) ? 1 : 0;
-                               wfFreeResult( $res );
+                               $this->mNewtalk = $dbr->numRows( $res ) > 0 ? 1 : 0;
+                               $dbr->freeResult( $res );
 
                                $wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 );
                        } else {
@@ -259,13 +261,11 @@ class User {
                        return;
                } # the following stuff is for non-anonymous users only
 
-               $sql = "SELECT user_name,user_password,user_newpassword,user_email," .
-                 "user_real_name,user_options,user_rights,user_touched " . 
-                  " FROM user WHERE user_id=" . $this->mId;
-               $res = wfQuery( $sql, DB_READ, "User::loadFromDatabase" );
+               $s = $dbr->getArray( 'user', array( 'user_name','user_password','user_newpassword','user_email',
+                 'user_real_name','user_options','user_rights','user_touched' ), 
+                 array( 'user_id' => $this->mId ), $fname );
 
-               if ( wfNumRows( $res ) > 0 ) {
-                       $s = wfFetchObject( $res );
+               if ( $s !== false ) {
                        $this->mName = $s->user_name;
                        $this->mEmail = $s->user_email;
                        $this->mRealName = $s->user_real_name;
@@ -276,7 +276,6 @@ class User {
                        $this->mTouched = $s->user_touched;
                }
 
-               wfFreeResult( $res );
                $this->mDataLoaded = true;
        }
 
@@ -514,7 +513,7 @@ class User {
                        array_push( $a, $oname.'='.$oval );
                }
                $s = implode( "\n", $a );
-               return wfStrencode( $s );
+               return $s;
        }
 
        /* private */ function decodeOptions( $str ) {
@@ -558,65 +557,71 @@ class User {
 
        function saveSettings() {
                global $wgMemc, $wgDBname;
+               $fname = 'User::saveSettings';
 
+               $dbw =& wfGetDB( DB_MASTER );
                if ( ! $this->mNewtalk ) {
+                       # Delete user_newtalk row
                        if( $this->mId ) {
-                               $sql="DELETE FROM user_newtalk WHERE user_id={$this->mId}";
-                               wfQuery ($sql, DB_WRITE, "User::saveSettings");
+                               $dbw->delete( 'user_newtalk', array( 'user_id' => $this->mId ), $fname );
                        } else {
-                               $sql="DELETE FROM user_newtalk WHERE user_ip='{$this->mName}'";
-                               wfQuery ($sql, DB_WRITE, "User::saveSettings");
+                               $dbw->delete( 'user_newtalk', array( 'user_ip' => $this->mName ), $fname );
                                $wgMemc->delete( "$wgDBname:newtalk:ip:{$this->mName}" );
                        }
                }
                if ( 0 == $this->mId ) { return; }
 
-               $sql = "UPDATE user SET " .
-                 "user_name= '" . wfStrencode( $this->mName ) . "', " .
-                 "user_password= '" . wfStrencode( $this->mPassword ) . "', " .
-                 "user_newpassword= '" . wfStrencode( $this->mNewpassword ) . "', " .
-                 "user_real_name= '" . wfStrencode( $this->mRealName ) . "', " .
-                 "user_email= '" . wfStrencode( $this->mEmail ) . "', " .
-                 "user_options= '" . $this->encodeOptions() . "', " .
-                 "user_rights= '" . wfStrencode( implode( ",", $this->mRights ) ) . "', " .
-                 "user_touched= '" . wfStrencode( $this->mTouched ) .
-                 "' WHERE user_id={$this->mId}";
-               wfQuery( $sql, DB_WRITE, "User::saveSettings" );
+               $dbw->update( 'user', 
+                       array( /* SET */
+                               'user_name' => $this->mName,
+                               'user_password' => $this->mPassword,
+                               'user_newpassword' => $this->mNewpassword,
+                               'user_real_name' => $this->mRealName,
+                               'user_email' => $this->mEmail,
+                               'user_options' => $this->encodeOptions(),
+                               'user_rights' => implode( ",", $this->mRights ),
+                               'user_touched' => $this->mTouched
+                       ), array( /* WHERE */
+                               'user_id' => $this->mId
+                       ), $fname
+               );
                $wgMemc->delete( "$wgDBname:user:id:$this->mId" );
        }
 
-       # Checks if a user with the given name exists
+       # Checks if a user with the given name exists, returns the ID
        #
        function idForName() {
+               $fname = 'User::idForName';
+
                $gotid = 0;
                $s = trim( $this->mName );
                if ( 0 == strcmp( '', $s ) ) return 0;
-
-               $sql = "SELECT user_id FROM user WHERE user_name='" .
-                 wfStrencode( $s ) . "'";
-               $res = wfQuery( $sql, DB_READ, "User::idForName" );
-               if ( 0 == wfNumRows( $res ) ) { return 0; }
-
-               $s = wfFetchObject( $res );
-               if ( '' == $s ) return 0;
-
-               $gotid = $s->user_id;
-               wfFreeResult( $res );
-               return $gotid;
+               
+               $dbr =& wfGetDB( DB_SLAVE );
+               $id = $dbr->selectField( 'user', 'user_id', array( 'user_name' => $s ), $fname );
+               if ( $id === false ) {
+                       $id = 0;
+               }
+               return $id;
        }
 
        function addToDatabase() {
-               $sql = "INSERT INTO user (user_name,user_password,user_newpassword," .
-                 "user_email, user_real_name, user_rights, user_options) " .
-                 " VALUES ('" . wfStrencode( $this->mName ) . "', '" .
-                 wfStrencode( $this->mPassword ) . "', '" .
-                 wfStrencode( $this->mNewpassword ) . "', '" .
-                 wfStrencode( $this->mEmail ) . "', '" .
-                 wfStrencode( $this->mRealName ) . "', '" .
-                 wfStrencode( implode( ',', $this->mRights ) ) . "', '" .
-                 $this->encodeOptions() . "')";
-               wfQuery( $sql, DB_WRITE, "User::addToDatabase" );
-               $this->mId = $this->idForName();
+               $fname = 'User::addToDatabase';
+               $dbw =& wfGetDB( DB_MASTER );
+               $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+               $dbw->insert( 'user', 
+                       array(
+                               'user_id' => $seqVal,
+                               'user_name' => $this->mName,
+                               'user_password' => $this->mPassword,
+                               'user_newpassword' => $this->mNewpassword,
+                               'user_email' => $this->mEmail,
+                               'user_real_name' => $this->mRealName,
+                               'user_rights' => implode( ',', $this->mRights ),
+                               'user_options' => $this->encodeOptions()
+                       ), $fname
+               );
+               $this->mId = $dbw->insertId();
        }
 
        function spreadBlock()
@@ -666,19 +671,14 @@ class User {
        }
 
        function getPageRenderingHash(){
-               static $hash = false;
-               if( $hash ){
-                       return $hash;
+               if( $this->mHash ){
+                       return $this->mHash;
                }
 
                // stubthreshold is only included below for completeness, 
                // it will always be 0 when this function is called by parsercache.
 
-               $confstr =        $this->getOption( 'quickbar' );
-               $confstr .= '!' . $this->getOption( 'underline' );
-               $confstr .= '!' . $this->getOption( 'hover' );
-               $confstr .= '!' . $this->getOption( 'skin' );
-               $confstr .= '!' . $this->getOption( 'math' );
+               $confstr =        $this->getOption( 'math' );
                $confstr .= '!' . $this->getOption( 'highlightbroken' );
                $confstr .= '!' . $this->getOption( 'stubthreshold' ); 
                $confstr .= '!' . $this->getOption( 'editsection' );
@@ -686,11 +686,8 @@ class User {
                $confstr .= '!' . $this->getOption( 'showtoc' );
                $confstr .= '!' . $this->getOption( 'date' );
 
-               if(strlen($confstr) > 32)
-                       $hash = md5($confstr);
-               else
-                       $hash = $confstr;
-               return $hash;
+               $this->mHash = $confstr;
+               return $confstr ;
        }
 
        function isAllowedToCreateAccount() {
@@ -709,7 +706,7 @@ class User {
        # Use this to prevent DB access in command-line scripts or similar situations
        function setLoaded( $loaded ) 
        {
-               wfSetVar( $this->mDataLoaded, $loaded );
+               return wfSetVar( $this->mDataLoaded, $loaded );
        }
        
        function getUserPage() {
@@ -717,8 +714,8 @@ class User {
        }
 
        /* static */ function getMaxID() {
-               $row = wfGetArray( 'user', array('max(user_id) as m'), false );
-               return $row->m;
+               $dbr =& wfGetDB( DB_SLAVE );
+               return $dbr->selectField( 'user', 'max(user_id)', false );
        }
 
        function isNewbie() {
index 66ea7a9..95cfa7e 100644 (file)
@@ -34,22 +34,25 @@ class UserTalkUpdate {
                        # Not ours.  If writing, mark it as modified.
 
                        $sql = false;
+                       $dbw =& wfGetDB( DB_MASTER );
+                       $user_newtalk = $dbw->tableName( 'user_newtalk' );
+
                        if ( 1 == $this->mAction ) {
                                $user = new User();                             
                                $user->setID(User::idFromName($this->mTitle));
                                if ($id=$user->getID()) {                                                                       
-                                       $sql = "INSERT INTO user_newtalk (user_id) values ({$id})";
+                                       $sql = "INSERT INTO $user_newtalk (user_id) values ({$id})";
                                        $wgMemc->delete( "$wgDBname:user:id:$id" );
                                } else {
                                        #anon
                                        if(preg_match("/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/",$this->mTitle)) { #real anon (user:xxx.xxx.xxx.xxx)
-                                               $sql = "INSERT INTO user_newtalk (user_id,user_ip) values (0,\"{$this->mTitle}\")";             
+                                               $sql = "INSERT INTO $user_newtalk (user_id,user_ip) values (0,\"{$this->mTitle}\")";            
                                                $wgMemc->delete( "$wgDBname:newtalk:ip:$this->mTitle" );
                                        }
                                }
                                
                                if($sql && !$user->getNewtalk()) { # only insert if real user and it's not already there
-                                       wfQuery( $sql, DB_WRITE, $fname );
+                                       $dbw->query( $sql, $fname );
                                }
                        }
                }
index 470fa69..9b1c7ec 100644 (file)
@@ -14,7 +14,7 @@ class ViewCountUpdate {
        {
                global $wgDisableCounters;
                if ( $wgDisableCounters ) { return; }
-               $db =& wfGetDB( DB_WRITE );
+               $db =& wfGetDB( DB_MASTER );
                $lowpri = $db->lowPriorityOption();
                $sql = "UPDATE $lowpri cur SET cur_counter=(1+cur_counter)," .
                  "cur_timestamp=cur_timestamp WHERE cur_id={$this->mPageID}";
index e2d9506..4342fc7 100644 (file)
@@ -1,7 +1,9 @@
 <?php
 
 class WatchedItem {
+       var $mTitle, $mUser;
 
+       # Create a WatchedItem object with the given user and title
        /* static */ function &fromUserTitle( &$user, &$title ) {
                $wl = new WatchedItem;
                $wl->mUser =& $user;
@@ -9,27 +11,31 @@ class WatchedItem {
                $wl->id = $user->getId();
                $wl->ns = $title->getNamespace() & ~1;
                $wl->ti = $title->getDBkey();
-               $wl->eti = wfStrencode( $wl->ti );
                return $wl;
        }
 
+       # Returns the memcached key for this item
        function watchKey() {
                global $wgDBname;
                return "$wgDBname:watchlist:user:$this->id:page:$this->ns:$this->ti";
        }
        
+       # Is mTitle being watched by mUser?
        function isWatched()
        {
                # Pages and their talk pages are considered equivalent for watching;
                # remember that talk namespaces are numbered as page namespace+1.
                global $wgMemc;
+               $fname = 'WatchedItem::isWatched';
+
                $key = $this->watchKey();
                $iswatched = $wgMemc->get( $key );
                if( is_integer( $iswatched ) ) return $iswatched;
                
-               $sql = "SELECT 1 FROM watchlist WHERE wl_user=$this->id AND wl_namespace=$this->ns AND wl_title='$this->eti'";
-               $res = wfQuery( $sql, DB_READ );
-               $iswatched = (wfNumRows( $res ) > 0) ? 1 : 0;
+               $dbr =& wfGetDB( DB_SLAVE );
+               $res = $dbr->select( 'watchlist', 1, array( 'wl_user' => $this->id, 'wl_namespace' => $this->ns, 
+                       'wl_title' => $this->ti ), $fname );
+               $iswatched = ($dbr->numRows( $res ) > 0) ? 1 : 0;
                $wgMemc->set( $key, $iswatched );
                return $iswatched;
        }
@@ -39,12 +45,12 @@ class WatchedItem {
                $fname = "WatchedItem::addWatch";
                # REPLACE instead of INSERT because occasionally someone
                # accidentally reloads a watch-add operation.
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $dbw->replace( 'watchlist', array(array('wl_user', 'wl_namespace', 'wl_title')),
                  array( 
                    'wl_user' => $this->id,
                        'wl_namespace' => $this->ns,
-                       'wl_title' => $this->eti,
+                       'wl_title' => $this->ti,
                  ), $fname );
 
                global $wgMemc;
@@ -54,13 +60,22 @@ class WatchedItem {
 
        function removeWatch()
        {
-               $sql = "DELETE FROM watchlist WHERE wl_user=$this->id AND wl_namespace=$this->ns AND wl_title='$this->eti'";
-               $res = wfQuery( $sql, DB_WRITE );
-               if( $res === false ) return false;
+               $dbw =& wfGetDB( DB_MASTER );
+               $dbw->delete( 'watchlist', 
+                       array( 
+                               'wl_user' => $this->id, 
+                               'wl_namespace' => $this->ns,  
+                               'wl_title' => $this->ti
+                       ), $fname
+               );
                
-               global $wgMemc;
-               $wgMemc->set( $this->watchkey(), 0 );
-               return true;
+               if ( $dbw->affectedRows() ) {
+                       global $wgMemc;
+                       $wgMemc->set( $this->watchkey(), 0 );
+                       return true;
+               } else {
+                       return false;
+               }
        }
 
        /* static */ function duplicateEntries( $ot, $nt ) {
@@ -70,25 +85,29 @@ class WatchedItem {
                $newnamespace = $nt->getNamespace() & ~1;
                $oldtitle = $ot->getDBkey();
                $newtitle = $nt->getDBkey();
-               $eoldtitle = wfStrencode( $oldtitle );
-               $enewtitle = wfStrencode( $newtitle );
 
-               $sql = "SELECT wl_user FROM watchlist
-                       WHERE wl_namespace={$oldnamespace} AND wl_title='{$eoldtitle}'";
-               $res = wfQuery( $sql, DB_READ, $fname );
-               if( $s = wfFetchObject( $res ) ) {
-                       $sql = "REPLACE INTO watchlist (wl_user,wl_namespace,wl_title)
-                               VALUES ({$s->wl_user},{$newnamespace},'{$enewtitle}')";
-                       $key = "$wgDBname:watchlist:user:$s->wl_user:page:$newnamespace:$newtitle";
-                       $wgMemc->set( $key, 1 );
-                       while( $s = wfFetchObject( $res ) ) {
-                               $sql .= ",({$s->wl_user},{$newnamespace},'{$enewtitle}')";
-                               $key = "$wgDBname:watchlist:user:$s->wl_user:page:$newnamespace:$newtitle";
-                               $wgMemc->set( $key, 1 );
-                       }
-                       $res = wfQuery( $sql, DB_WRITE, $fname );
-                       if( $res === false ) return false; # db error?
+               $dbw =& wfGetDB( DB_MASTER );
+               $watchlist = $dbw->tableName( 'watchlist' );
+               
+               $res = $dbw->select( 'watchlist', 'wl_user', 
+                       array( 'wl_namespace' => $oldnamespace, 'wl_title' => $oldtitle ),
+                       $fname, 'FOR UPDATE'
+               );
+               # Construct array to replace into the watchlist
+               $values = array();
+               while ( $s = $dbw->fetchObject( $res ) ) {
+                       $values[] = array(
+                               'wl_user' => $s->wl_user,
+                               'wl_namespace' => $newnamespace,
+                               'wl_title' => $newtitle
+                       );
                }
+               $dbw->freeResult( $res );
+
+               # Perform replace
+               # Note that multi-row replace is very efficient for MySQL but may be inefficient for
+               # some other DBMSes, mostly due to poor simulation by us
+               $dbw->replace( 'watchlist', array(array( 'wl_user', 'wl_namespace', 'wl_title')), $values, $fname );
                return true;
        }
 
index 075e721..803a548 100644 (file)
--- a/index.php
+++ b/index.php
@@ -54,6 +54,8 @@ if ( !is_null( $wgTitle ) && !$wgTitle->userCanRead() ) {
        exit;
 }
 
+$db =& wfGetDB( DB_MASTER );
+
 if ( $search = $wgRequest->getText( 'search' ) ) {
        $wgTitle = Title::makeTitle( NS_SPECIAL, "Search" );
        if( $wgRequest->getVal( 'fulltext' ) || !is_null( $wgRequest->getVal( 'offset' ) ) ) {
@@ -95,8 +97,7 @@ if ( $search = $wgRequest->getText( 'search' ) ) {
                $wgArticle = new Article( $wgTitle );
        }
 
-       $db =& wfGetDB( DB_WRITE );
-       $db->query("BEGIN", DB_WRITE);
+       $db->query("BEGIN");
        switch( $action ) {
                case "view":
                        $wgOut->setSquidMaxage( $wgSquidMaxage );
@@ -169,12 +170,13 @@ if ( $search = $wgRequest->getText( 'search' ) ) {
        $db->query("COMMIT");
 }
 
+$wgLoadBalancer->saveMasterPos();
 $wgOut->output();
 
 foreach ( $wgDeferredUpdateList as $up ) {
-       wfQuery("BEGIN", DB_WRITE);
+       $db->query("BEGIN");
        $up->doUpdate();
-       wfQuery("COMMIT", DB_WRITE);
+       $db->query("COMMIT");
 }
 logProfilingData();
 wfDebug( "Request ended normally\n" );
index 2ee841f..34dd701 100644 (file)
@@ -132,11 +132,11 @@ function dbsource( $fname, $database = false ) {
 # Obsolete, use Database::fieldExists()
 function field_exists( $table, $field ) {
        $fname = "Update script: field_exists";
-       $db =& wfGetDB( DB_READ );
+       $db =& wfGetDB( DB_SLAVE );
        $res = $db->query( "DESCRIBE $table", $fname );
        $found = false;
        
-       while ( $row = wfFetchObject( $res ) ) {
+       while ( $row = $db->fetchObject( $res ) ) {
                if ( $row->Field == $field ) {
                        $found = true;
                        break;
index 41052bc..bcc860d 100644 (file)
@@ -32,16 +32,18 @@ $wgCommandLineMode = true;
 set_time_limit(0);
 
 sleep(30);
+$dbr =& wfGetDB( DB_SLAVE );
+$recentchanges = $dbr->tableName( 'recentchanges' );
 
-$res = wfQuery( "SELECT rc_timestamp FROM recentchanges ORDER BY rc_timestamp DESC LIMIT 1", DB_READ ); 
-$row = wfFetchObject( $res );
+$res = $dbr->query( "SELECT rc_timestamp FROM $recentchanges ORDER BY rc_timestamp DESC LIMIT 1" ); 
+$row = $dbr->fetchObject( $res );
 $oldTimestamp = $row->rc_timestamp;
 $serverCount = 0;
 
 while (1) {
-       $res = wfQuery( "SELECT * FROM recentchanges WHERE rc_timestamp>'$oldTimestamp' ORDER BY rc_timestamp", DB_READ );
+       $res = $dbr->query( "SELECT * FROM $recentchanges WHERE rc_timestamp>'$oldTimestamp' ORDER BY rc_timestamp" );
        $rowIndex = 0;
-       while ( $row = wfFetchObject( $res ) ) {
+       while ( $row = $dbr->fetchObject( $res ) ) {
                if ( ++$serverCount % 20 == 0 ) {
                        print "/server $ircServer\n";
                }
index 96790cc..0a61d62 100644 (file)
@@ -1350,11 +1350,12 @@ You might want to check the following regular expression for patterns that are c
 
 # Info page
 "infosubtitle" => "Information for page",
-"numedits" => "Number of edits (article): ",
-"numtalkedits" => "Number of edits (discussion page): ",
-"numwatchers" => "Number of watchers: ",
-"numauthors" => "Number of distinct authors (article): ",
-"numtalkauthors" => "Number of distinct authors (discussion page): ",
+"numedits" => "Number of edits (article): $1",
+"numtalkedits" => "Number of edits (discussion page): $1",
+"numwatchers" => "Number of watchers: $1",
+"numauthors" => "Number of distinct authors (article): $1",
+"numtalkauthors" => "Number of distinct authors (discussion page): $1",
+
 # Math options
        'mw_math_png' => 'Always render PNG',
        'mw_math_simple' => 'HTML if very simple or else PNG',
index 699ec66..3f3dff2 100755 (executable)
@@ -40,7 +40,13 @@ function initialiseMessages( $overwrite = false, $messageArray = false ) {
 </td></tr>";
        
        print "Initialising \"MediaWiki\" namespace...\n";
-       $sql = "SELECT cur_title,cur_is_new,cur_user_text FROM cur WHERE cur_namespace=$ns AND cur_title IN(";
+
+       
+       $dbr =& wfGetDB( DB_SLAVE );
+       $dbw =& wfGetDB( DB_MASTER );
+       $cur = $dbr->tableName( 'cur' );
+
+       $sql = "SELECT cur_title,cur_is_new,cur_user_text FROM $cur WHERE cur_namespace=$ns AND cur_title IN(";
 
        # Get keys from $wgAllMessagesEn, which is more complete than the local language
        $first = true;
@@ -51,8 +57,9 @@ function initialiseMessages( $overwrite = false, $messageArray = false ) {
        }
        
        ksort( $sortedArray );
-       
+
        # SELECT all existing messages
+       # Can't afford to be locking all rows for update, this script can take quite a long time to complete
        foreach ( $sortedArray as $key => $enMsg ) {
                if ( $key == '' ) {
                        continue; // Skip odd members
@@ -63,12 +70,12 @@ function initialiseMessages( $overwrite = false, $messageArray = false ) {
                        $sql .= ',';
                }
                $titleObj = Title::newFromText( $key );
-               $enctitle = wfStrencode($titleObj->getDBkey());
+               $enctitle = $dbr->strencode($titleObj->getDBkey());
                $sql .= "'$enctitle'";
        }
        $sql .= ')';
-       $res = wfQuery( $sql, DB_READ );
-       $row = wfFetchObject( $res );
+       $res = $dbr->query( $sql );
+       $row = $dbr->fetchObject( $res );
 
        # Read the results into an array
        # Decide whether or not each one needs to be overwritten
@@ -80,12 +87,12 @@ function initialiseMessages( $overwrite = false, $messageArray = false ) {
                        $existingTitles[$row->cur_title] = 'chuck';
                }
 
-               $row = wfFetchObject( $res );
+               $row = $dbr->fetchObject( $res );
        }
 
        # Insert queries are done in one multi-row insert
        # Here's the start of it:
-       $sql = "INSERT INTO cur (cur_namespace, cur_title, cur_text,
+       $sql = "INSERT INTO $cur (cur_namespace, cur_title, cur_text,
                cur_user_text, cur_timestamp, cur_restrictions,
                cur_is_new, inverse_timestamp, cur_touched) VALUES      ";
        $first = true;
@@ -105,7 +112,7 @@ function initialiseMessages( $overwrite = false, $messageArray = false ) {
                }
                $titleObj = Title::newFromText( $key );
                $title = $titleObj->getDBkey();
-               $dbencMsg = wfStrencode( $message );
+               $dbencMsg = $dbw->strencode( $message );
 
                # Update messages which already exist
                if ( array_key_exists( $title, $existingTitles ) ) {
@@ -150,7 +157,7 @@ $message
 
        # Perform the insert query
        if ( !$first ) {
-               wfQuery( $sql, DB_WRITE, $fname );
+               $dbw->query( $sql, $fname );
        }
 
        # Write the navigation page
index 4b330fa..3950fab 100644 (file)
@@ -63,14 +63,14 @@ function convertUserTable()
        print "Converting USER table.\n";
 
        $sql = "LOCK TABLES old_user READ, user WRITE";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 
        $sql = "SELECT user_id,user_name,user_rights,user_password," .
          "user_email,user_options,user_watch FROM old_user";
-       $oldres = wfQuery( $sql, DB_READ );
+       $oldres = wfQuery( $sql, DB_SLAVE );
 
        $sql = "DELETE FROM user";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 
        $sql = "";
        while ( $row = mysql_fetch_object( $oldres ) ) {
@@ -78,7 +78,7 @@ function convertUserTable()
                if ( "" == $name ) continue; # Don't convert illegal names
 
                if ( 0 == ( $count % 10 ) ) {
-                       if ( 0 != $count ) { $newres = wfQuery( $sql, DB_WRITE ); }
+                       if ( 0 != $count ) { $newres = wfQuery( $sql, DB_MASTER ); }
 
                        $sql = "INSERT INTO user (user_id,user_name,user_rights," .
                          "user_password,user_newpassword,user_email,user_options," .
@@ -99,13 +99,13 @@ function convertUserTable()
                        print "$count user records processed.\n";
                }
        }
-       if ( $sql ) { $newres = wfQuery( $sql, DB_WRITE ); }
+       if ( $sql ) { $newres = wfQuery( $sql, DB_MASTER ); }
 
        print "$count user records processed.\n";
        mysql_free_result( $oldres );
 
        $sql = "UNLOCK TABLES";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 }
 
 # Convert May 2002 version of database into new format.
@@ -116,18 +116,18 @@ function convertCurTable()
        print "Converting CUR table.\n";
 
        $sql = "LOCK TABLES old_cur READ, cur WRITE, site_stats WRITE";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 
        $sql = "SELECT cur_id,cur_title,cur_text,cur_comment,cur_user," .
          "cur_timestamp,cur_minor_edit,cur_restrictions," .
          "cur_counter,cur_ind_title,cur_user_text FROM old_cur";
-       $oldres = wfQuery( $sql, DB_READ );
+       $oldres = wfQuery( $sql, DB_SLAVE );
 
        $sql = "DELETE FROM cur";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
        $sql = "DELETE FROM site_stats";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
        $sql = "";
        while ( $row = mysql_fetch_object( $oldres ) ) {
@@ -166,7 +166,7 @@ function convertCurTable()
                  "'{$com}',{$row->cur_user},'{$row->cur_timestamp}'," .
                  "{$isme},{$isnew},'{$cr}',0,'{$ititle}','{$itext}'," .
                  "{$redir},'{$cut}')";
-               wfQuery( $sql, DB_WRITE );
+               wfQuery( $sql, DB_MASTER );
 
                if ( ( ++$count % 1000 ) == 0 ) {
                        print "$count article records processed.\n";
@@ -181,10 +181,10 @@ function convertCurTable()
 
        $sql = "REPLACE INTO site_stats (ss_row_id,ss_total_views," .
          "ss_total_edits,ss_good_articles) VALUES (1,0,0,{$countables})";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
        $sql = "UNLOCK TABLES";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 }
 
 # Convert May 2002 version of database into new format.
@@ -195,14 +195,14 @@ function convertOldTable()
        print "Converting OLD table.\n";
 
        $sql = "LOCK TABLES old_old READ, old WRITE";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 
        $sql = "SELECT old_id,old_title,old_text,old_comment,old_user," .
          "old_timestamp,old_minor_edit,old_user_text FROM old_old";
-       $oldres = wfQuery( $sql, DB_READ );
+       $oldres = wfQuery( $sql, DB_SLAVE );
 
        $sql = "DELETE FROM old";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 
        while ( $row = mysql_fetch_object( $oldres ) ) {
                $nt = Title::newFromDBkey( $row->old_title );
@@ -231,7 +231,7 @@ function convertOldTable()
                $sql .= "({$row->old_id},{$ns},'{$title}','{$text}'," .
                  "'{$com}',{$row->old_user},'{$row->old_timestamp}'," .
                  "{$isme},'{$cut}')";
-               wfQuery( $sql, DB_WRITE );
+               wfQuery( $sql, DB_MASTER );
 
                if ( ( ++$count % 1000 ) == 0 ) {
                        print "$count history records processed.\n";
@@ -241,7 +241,7 @@ function convertOldTable()
        mysql_free_result( $oldres );
 
        $sql = "UNLOCK TABLES";
-       $newres = wfQuery( $sql, DB_WRITE );
+       $newres = wfQuery( $sql, DB_MASTER );
 }
 
 function convertImageDirectoriesX()
@@ -284,14 +284,14 @@ function convertImageDirectoriesX()
 
                        $sql = "DELETE FROM image WHERE img_name='" .
                          addslashes( $nname ) . "'";
-                       $res = wfQuery( $sql, DB_WRITE );
+                       $res = wfQuery( $sql, DB_MASTER );
 
                        $sql = "INSERT INTO image (img_name,img_timestamp,img_user," .
                          "img_user_text,img_size,img_description) VALUES ('" .
                          addslashes( $nname ) . "','" .
                          date( "YmdHis" ) . "',0,'(Automated conversion)','" .
                          filesize( "{$dest}/{$nname}" ) . "','')";
-                       $res = wfQuery( $sql, DB_WRITE );
+                       $res = wfQuery( $sql, DB_MASTER );
                } else {
                        die( "Couldn't copy \"{$oname}\" to \"{$nname}\"\n" );
                }
@@ -306,7 +306,7 @@ function convertImageDirectories()
 
 
        $sql = "SELECT DISTINCT il_to FROM imagelinks";
-       $result = wfQuery ( $sql, DB_READ ) ;
+       $result = wfQuery ( $sql, DB_SLAVE ) ;
 
    while ( $row = mysql_fetch_object ( $result ) ) {
        $oname = $row->il_to ;
@@ -347,14 +347,14 @@ function convertImageDirectories()
 
                        $sql = "DELETE FROM image WHERE img_name='" .
                          addslashes( $nname ) . "'";
-                       $res = wfQuery( $sql, DB_WRITE );
+                       $res = wfQuery( $sql, DB_MASTER );
 
                        $sql = "INSERT INTO image (img_name,img_timestamp,img_user," .
                          "img_user_text,img_size,img_description) VALUES ('" .
                          addslashes( $nname ) . "','" .
                          date( "YmdHis" ) . "',0,'(Automated conversion)','" .
                          filesize( "{$dest}/{$nname}" ) . "','')";
-                       $res = wfQuery( $sql, DB_WRITE );
+                       $res = wfQuery( $sql, DB_MASTER );
                } else {
             echo( "Couldn't copy \"{$oname}\" to \"{$nname}\"\n" );
         }
@@ -557,36 +557,36 @@ function refillRandom()
        $sql = "INSERT INTO random(ra_current,ra_title) SELECT 0,cur_title " .
          "FROM cur WHERE cur_namespace=0 AND cur_is_redirect=0 " .
          "ORDER BY RAND() LIMIT 1000";
-       wfQuery( $sql, DB_WRITE, $fname );
+       wfQuery( $sql, DB_MASTER, $fname );
 
        $sql = "UPDATE random SET ra_current=(ra_current+1)";
-       wfQuery( $sql, DB_WRITE, $fname );
+       wfQuery( $sql, DB_MASTER, $fname );
 
        $sql = "DELETE FROM random WHERE ra_current>1";
-       wfQuery( $sql, DB_WRITE, $fname );
+       wfQuery( $sql, DB_MASTER, $fname );
 }
 
 function renameOldTables()
 {
        $sql = "ALTER TABLE user RENAME TO old_user";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
        $sql = "ALTER TABLE cur RENAME TO old_cur";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
        $sql = "ALTER TABLE old RENAME TO old_old";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
        $sql = "DROP TABLE IF EXISTS linked";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
        $sql = "DROP TABLE IF EXISTS unlinked";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 }
 
 function removeOldTables()
 {
-       wfQuery( "DROP TABLE IF EXISTS old_user", DB_WRITE );
-       wfQuery( "DROP TABLE IF EXISTS old_linked", DB_WRITE );
-       wfQuery( "DROP TABLE IF EXISTS old_unlinked", DB_WRITE );
-       wfQuery( "DROP TABLE IF EXISTS old_cur", DB_WRITE );
-       wfQuery( "DROP TABLE IF EXISTS old_old", DB_WRITE );
+       wfQuery( "DROP TABLE IF EXISTS old_user", DB_MASTER );
+       wfQuery( "DROP TABLE IF EXISTS old_linked", DB_MASTER );
+       wfQuery( "DROP TABLE IF EXISTS old_unlinked", DB_MASTER );
+       wfQuery( "DROP TABLE IF EXISTS old_cur", DB_MASTER );
+       wfQuery( "DROP TABLE IF EXISTS old_old", DB_MASTER );
 }
 
 ?>
index 5438194..e4eadd5 100644 (file)
@@ -1,9 +1,11 @@
 <?php
 
 function isTemplateInitialised() {
-       $sql = "SELECT 1 FROM cur WHERE cur_namespace=" . NS_TEMPLATE . " LIMIT 1";
-       $res = wfQuery( $sql, DB_READ );
-       return wfNumRows( $res ) ? true : false;
+       $fname = 'isTemplateInitialised';
+
+       $dbw =& wfGetDB( DB_MASTER );
+       $res = $dbw->select( 'cur', 1, array( 'cur_namespace' => NS_TEMPLATE ), $fname, array( 'LIMIT' => 1 ) );
+       return $dbw->numRows( $res ) ? true : false;
 }
 
 function moveCustomMessages( $phase ) {
@@ -15,7 +17,9 @@ function moveCustomMessages( $phase ) {
        $wgUser->setName( "Template namespace initialisation script" );
        $wgUser->addRight( "bot" );
 
-       wfIgnoreSQLErrors( true );
+       $dbw =& wfGetDB( DB_MASTER );
+
+       $dbw->setIgnoreErrors( true );
 
        # Compose DB key array
        $dbkeys = array();
@@ -25,17 +29,16 @@ function moveCustomMessages( $phase ) {
                $dbkeys[$title->getDBkey()] = 1;
        }
 
-       $sql = "SELECT cur_id, cur_title FROM cur WHERE cur_namespace= " . NS_MEDIAWIKI;
-       $res = wfQuery( $sql, DB_READ );
+       $res = $dbw->select( 'cur', array( 'cur_id', 'cur_title' ), array( 'cur_namespace' => NS_MEDIAWIKI ) );
 
        # Compile target array
        $targets = array();
-       while ( $row = wfFetchObject( $res ) ) {
+       while ( $row = $dbw->fetchObject( $res ) ) {
                if ( !array_key_exists( $row->cur_title, $dbkeys ) ) {
                        $targets[$row->cur_title] = 1;
                }
        }
-       wfFreeResult( $res );
+       $dbw->freeResult( $res );
 
        # Create redirects from destination to source
        if ( $phase == 0 || $phase == 1 ) {
@@ -61,7 +64,7 @@ function moveCustomMessages( $phase ) {
        if ( $phase == 0 || $phase == 2 ) {
                print "\nMoving pages...\n";
                foreach ( $targets as $partial => $dummy ) {
-                       wfQuery( "BEGIN", DB_WRITE );
+                       $dbw->query( "BEGIN" );
                        $ot = Title::makeTitle( NS_MEDIAWIKI, $partial );
                        $nt = Title::makeTitle( NS_TEMPLATE, $partial );
                        print "$partial...";
@@ -76,7 +79,7 @@ function moveCustomMessages( $phase ) {
                                $up = array_pop( $wgDeferredUpdateList );
                                $up->doUpdate();
                        }
-                       wfQuery( "COMMIT", DB_WRITE );
+                       $dbw->query( "COMMIT" );
                }
        }
 
@@ -97,12 +100,12 @@ function moveCustomMessages( $phase ) {
                        $dest = Title::makeTitle( NS_MEDIAWIKI, $partial );
                        $linksTo = $dest->getLinksTo();
                        foreach( $linksTo as $source ) {
-                               wfQuery( "BEGIN", DB_WRITE );
+                               $dbw->query( "BEGIN" );
                                $pdbk = $source->getPrefixedDBkey();
                                if ( !array_key_exists( $pdbk, $completedTitles ) ) {   
                                        $completedTitles[$pdbk] = 1;
                                        $id = $source->getArticleID();
-                                       $row = wfGetArray( 'cur', array( 'cur_text' ), 
+                                       $row = $dbw->selectRow( 'cur', array( 'cur_text' ), 
                                                array( 'cur_id' => $source->getArticleID() ) );
                                        $parser->startExternalParse( $source, $options, OT_WIKI );
                                        $text = $parser->strip( $row->cur_text, $stripState, false );
@@ -125,7 +128,7 @@ function moveCustomMessages( $phase ) {
                                                print "($pdbk)\n";
                                        }
                                } 
-                               wfQuery( "COMMIT", DB_WRITE );
+                               $dbw->query( "COMMIT" );
                        }
                }
        }
diff --git a/maintenance/archives/patch-image_name_unique.sql b/maintenance/archives/patch-image_name_unique.sql
new file mode 100644 (file)
index 0000000..118b068
--- /dev/null
@@ -0,0 +1,6 @@
+-- Make the image name index unique
+
+ALTER TABLE image DROP INDEX img_name;
+
+ALTER TABLE image
+  ADD UNIQUE INDEX img_name (img_name);
index cd32eb5..20914fc 100644 (file)
@@ -19,19 +19,19 @@ $wgDBuser                   = "wikiadmin";
 $wgDBpassword          = $wgDBadminpassword;
 
 $sql = "DROP TABLE IF EXISTS watchlist";
-wfQuery( $sql, DB_WRITE );
+wfQuery( $sql, DB_MASTER );
 $sql = "CREATE TABLE watchlist (
   wl_user int(5) unsigned NOT NULL,
   wl_page int(8) unsigned NOT NULL,
   UNIQUE KEY (wl_user, wl_page)
 ) TYPE=MyISAM PACK_KEYS=1";
-wfQuery( $sql, DB_WRITE );
+wfQuery( $sql, DB_MASTER );
 
 $lc = new LinkCache;
 
 # Now, convert!
 $sql = "SELECT user_id,user_watch FROM user";
-$res = wfQuery( $sql, DB_READ );
+$res = wfQuery( $sql, DB_SLAVE );
 $nu = wfNumRows( $res );
 $sql = "INSERT into watchlist (wl_user,wl_page) VALUES ";
 $i = $n = 0;
@@ -47,7 +47,7 @@ while( $row = wfFetchObject( $res ) ) {
 }
 echo "$n users done.\n";
 if( $i ) {
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 }
 
 
@@ -56,6 +56,6 @@ if( $i ) {
 $sql = "ALTER TABLE watchlist
   ADD INDEX wl_user (wl_user),
   ADD INDEX wl_page (wl_page)";
-#wfQuery( $sql, DB_WRITE );
+#wfQuery( $sql, DB_MASTER );
 
 ?>
index a6dcf4a..61c43b0 100644 (file)
@@ -16,12 +16,14 @@ if ( count( $args ) < 2 ) {
 $source = $args[0];
 $dest = $args[1];
 
-$eSource = wfStrencode( $source );
-$eDest = wfStrencode( $dest );
+$dbr =& wfGetDB( DB_SLAVE );
+extract( $dbr->tableNames( 'cur','old','user' );
+$eSource = $dbr->strencode( $source );
+$eDest = $dbr->strencode( $dest );
 
 # Get user id
-$res = wfQuery( "SELECT user_id FROM user WHERE user_name='$eDest'", DB_READ );
-$row = wfFetchObject( $res );
+$res = $dbr->query( "SELECT user_id FROM $user WHERE user_name='$eDest'" );
+$row = $dbr->fetchObject( $res );
 if ( !$row ) {
        print "Warning: the target name \"$dest\" does not exist";
        $uid = 0;
@@ -46,8 +48,8 @@ $omitTitle = "Wikipedia:Changing_attribution_for_an_edit";
 # Get old entries
 print "\nOld entries\n\n";
 
-$res = wfQuery( "SELECT old_namespace, old_title, old_id, old_timestamp FROM old WHERE old_user_text='$eSource'", DB_READ );
-$row = wfFetchObject( $res );
+$res = $dbr->query( "SELECT old_namespace, old_title, old_id, old_timestamp FROM $old WHERE old_user_text='$eSource'" );
+$row = $dbr->fetchObject( $res );
 
 if ( $row ) {
 /*
@@ -59,7 +61,7 @@ if ( $row ) {
        fwrite( $logfile, "**Old IDs: " );
        fwrite( $sqlfile, "UPDATE old SET old_user=$uid, old_user_text='$eDest' WHERE old_id IN (\n" );
        
-       for ( $first=true; $row; $row = wfFetchObject( $res ) ) {
+       for ( $first=true; $row; $row = $dbr->fetchObject( $res ) ) {
                $ns = $wgLang->getNsText( $row->old_namespace );
                if ( $ns ) {
                        $fullTitle = "$ns:{$row->old_title}";
@@ -72,19 +74,7 @@ if ( $row ) {
 
                print "$fullTitle\n";
                $url = "http://$lang.wikipedia.org/w/wiki.phtml?title=" . urlencode( $fullTitle );
-               $eTitle = wfStrencode( $row->old_title );
-/*             
-               # Find previous entry
-               $lastres = wfQuery( "SELECT old_id FROM old WHERE
-                       old_title='$eTitle' AND old_namespace={$row->old_namespace} AND
-                       old_timestamp<'{$row->old_timestamp}' ORDER BY inverse_timestamp LIMIT 1", DB_READ );
-               $lastrow = wfFetchObject( $lastres );           
-               if ( $lastrow ) {
-                       $last = $lastrow->old_id;
-                       $url .= "&diff={$row->old_id}&oldid=$last";
-               } else {*/
-                       $url .= "&oldid={$row->old_id}";
-#              }
+               $url .= "&oldid={$row->old_id}";
                
                # Output
                fwrite( $sqlfile, "      " );
@@ -106,13 +96,12 @@ if ( $row ) {
 # Get cur entries
 print "\n\nCur entries\n\n";
 
-$res = wfQuery( "SELECT cur_title, cur_namespace, cur_timestamp, cur_id FROM cur WHERE cur_user_text='$eSource'",
-       DB_READ );
-$row = wfFetchObject( $res );
+$res = $dbr->query( "SELECT cur_title, cur_namespace, cur_timestamp, cur_id FROM $cur WHERE cur_user_text='$eSource'" );
+$row = $dbr->fetchObject( $res );
 if ( $row ) {
        fwrite( $sqlfile, "\n\nUPDATE cur SET cur_user=$uid, cur_user_text='$eDest' WHERE cur_id IN(\n" );
        fwrite( $logfile, "**Cur entries:\n" );
-       for ( $first=true; $row; $row = wfFetchObject( $res ) ) {
+       for ( $first=true; $row; $row = $dbr->fetchObject( $res ) ) {
                $ns = $wgLang->getNsText( $row->cur_namespace );
                if ( $ns ) {
                        $fullTitle = "$ns:{$row->cur_title}";
index 8da4272..249816e 100644 (file)
@@ -1,22 +1,26 @@
 <?php
 
 function compressOldPages( $start = 0 ) {
+       $fname = 'compressOldPages';
+
        $chunksize = 50;
        print "Starting from old_id $start...\n";
+       $dbw =& wfGetDB( DB_MASTER );
+       $old = $dbw->tableName( 'old' );
        do {
                $end = $start + $chunksize;
-               $sql = "SELECT old_id,old_flags,old_namespace,old_title,old_text FROM old WHERE old_id>=$start ORDER BY old_id LIMIT $chunksize";
-               $res = wfQuery( $sql, DB_READ, "compressOldPages" );
-               if( wfNumRows( $res ) == 0 ) {
+               $res = dbw->select( 'old', array( 'old_id','old_flags','old_namespace','old_title','old_text' ),
+                       "old_id>=$start", $fname, array( 'ORDER BY' => 'old_id', 'LIMIT' => $chunksize, 'FOR UPDATE' ) );
+               if( $dbw->numRows( $res ) == 0 ) {
                        break;
                }
                $last = $start;
-               while( $row = wfFetchObject( $res ) ) {
+               while( $row = $dbw->fetchObject( $res ) ) {
                        # print "  {$row->old_id} - {$row->old_namespace}:{$row->old_title}\n";
                        compressPage( $row );
                        $last = $row->old_id;
                }
-               wfFreeResult( $res );
+               $dbw->freeResult( $res );
                $start = $last + 1; # Deletion may leave long empty stretches
                print "$start...\n";
        } while( true );
@@ -27,11 +31,17 @@ function compressPage( $row ) {
                print "Already compressed row {$row->old_id}?\n";
                return false;
        }
+       $dbw =& wfGetDB( DB_MASTER );
        $flags = $row->old_flags ? "{$row->old_flags},gzip" : "gzip";
-       $compress = wfStrencode( gzdeflate( $row->old_text ) );
-       
-       $sql = "UPDATE old SET old_flags='$flags', old_text='$compress' WHERE old_id={$row->old_id} LIMIT 1";
-        $res = wfQuery( $sql, DB_WRITE, 'compressPage' );
+       $compress = $dbw->strencode( gzdeflate( $row->old_text ) );
+       $dbw->update( 'old', 
+               array( /* SET */
+                       'old_flags' => $flags,
+                       'old_text' => $compress
+               ), array( /* WHERE */
+                       'old_id' => $row->old_id
+               ), $fname, 'LIMIT 1'
+       );
        return $res;
 }
 
index 3a25930..62ec7a2 100644 (file)
@@ -30,17 +30,20 @@ function convertLinks() {
        $logPerformance = false; # output performance data to a file
        $perfLogFilename = "convLinksPerf.txt";
        #--------------------------------------------------------------------
+       
+       $dbw =& wfGetDB( DB_MASTER );
+       extract( $dbw->tableNames( 'cur', 'links', 'links_temp', 'links_backup' ) );
 
-       $res = wfQuery( "SELECT l_from FROM links LIMIT 1", DB_READ );
-       if ( mysql_field_type( $res, 0 ) == "int" ) {
+       $res = $dbw->query( "SELECT l_from FROM $links LIMIT 1" );
+       if ( $dbw->fieldType( $res, 0 ) == "int" ) {
                print "Schema already converted\n";
                return;
        }
        
-       $res = wfQuery( "SELECT COUNT(*) AS count FROM links", DB_WRITE );
-       $row = wfFetchObject($res);
+       $res = $dbw->query( "SELECT COUNT(*) AS count FROM $links" );
+       $row = $dbw->fetchObject($res);
        $numRows = $row->count;
-       wfFreeResult( $res );
+       $dbw->freeResult( $res );
 
        if ( $numRows == 0 ) {
                print "Updating schema (no rows to convert)...\n";
@@ -49,14 +52,15 @@ function convertLinks() {
                if ( $logPerformance ) { $fh = fopen ( $perfLogFilename, "w" ); }
                $baseTime = $startTime = getMicroTime();
                # Create a title -> cur_id map
-               print "Loading IDs from cur table...\n";
+               print "Loading IDs from $cur table...\n";
                performanceLog ( "Reading $numRows rows from cur table...\n" );
                performanceLog ( "rows read vs seconds elapsed:\n" );
-               wfBufferSQLResults( false );
-               $res = wfQuery( "SELECT cur_namespace,cur_title,cur_id FROM cur", DB_WRITE );
+               
+               $dbw->setBufferResults( false );
+               $res = $dbw->query( "SELECT cur_namespace,cur_title,cur_id FROM $cur" );
                $ids = array();
 
-               while ( $row = wfFetchObject( $res ) ) {
+               while ( $row = $dbw->fetchObject( $res ) ) {
                        $title = $row->cur_title;
                        if ( $row->cur_namespace ) {
                                $title = $wgLang->getNsText( $row->cur_namespace ) . ":$title";
@@ -66,12 +70,12 @@ function convertLinks() {
                        if ($reportCurReadProgress) {
                                if (($curRowsRead % $curReadReportInterval) == 0) {
                                        performanceLog( $curRowsRead . " " . (getMicroTime() - $baseTime) . "\n" );
-                                       print "\t$curRowsRead rows of cur table read.\n";       
+                                       print "\t$curRowsRead rows of $cur table read.\n";      
                                }
                        }
                }
-               wfFreeResult( $res );
-               wfBufferSQLResults( true );
+               $dbw->freeResult( $res );
+               $dbw->setBufferResults( true );
                print "Finished loading IDs.\n\n";
                performanceLog( "Took " . (getMicroTime() - $baseTime) . " seconds to load IDs.\n\n" );
        #--------------------------------------------------------------------
@@ -81,21 +85,21 @@ function convertLinks() {
                createTempTable();
                performanceLog( "Resetting timer.\n\n" );
                $baseTime = getMicroTime();
-               print "Processing $numRows rows from links table...\n";
-               performanceLog( "Processing $numRows rows from links table...\n" );
+               print "Processing $numRows rows from $links table...\n";
+               performanceLog( "Processing $numRows rows from $links table...\n" );
                performanceLog( "rows inserted vs seconds elapsed:\n" );
                
                for ($rowOffset = $initialRowOffset; $rowOffset < $numRows; $rowOffset += $linksConvInsertInterval) {
-                       $sqlRead = "SELECT * FROM links ".wfLimitResult($linksConvInsertInterval,$rowOffset);
-                       $res = wfQuery($sqlRead, DB_READ);
+                       $sqlRead = "SELECT * FROM $links ".wfLimitResult($linksConvInsertInterval,$rowOffset);
+                       $res = $dbw->query($sqlRead);
                        if ( $noKeys ) {
-                               $sqlWrite = array("INSERT INTO links_temp(l_from,l_to) VALUES ");
+                               $sqlWrite = array("INSERT INTO $links_temp (l_from,l_to) VALUES ");
                        } else {
-                               $sqlWrite = array("INSERT IGNORE INTO links_temp(l_from,l_to) VALUES ");
+                               $sqlWrite = array("INSERT IGNORE INTO $links_temp (l_from,l_to) VALUES ");
                        }
                        
                        $tuplesAdded = 0; # no tuples added to INSERT yet
-                       while ( $row = wfFetchObject($res) ) {
+                       while ( $row = $dbw->fetchObject($res) ) {
                                $fromTitle = $row->l_from; 
                                if ( array_key_exists( $fromTitle, $ids ) ) { # valid title
                                        $from = $ids[$fromTitle];
@@ -109,13 +113,13 @@ function convertLinks() {
                                        $numBadLinks++;
                                }
                        }
-                       wfFreeResult($res);
+                       $dbw->freeResult($res);
                        #print "rowOffset: $rowOffset\ttuplesAdded: $tuplesAdded\tnumBadLinks: $numBadLinks\n";
                        if ( $tuplesAdded != 0  ) {
                                if ($reportLinksConvProgress) {
-                                       print "Inserting $tuplesAdded tuples into links_temp...";
+                                       print "Inserting $tuplesAdded tuples into $links_temp...";
                                }
-                               wfQuery( implode("",$sqlWrite) , DB_WRITE );
+                               $dbw->query( implode("",$sqlWrite) );
                                $totalTuplesInserted += $tuplesAdded;
                                if ($reportLinksConvProgress)
                                        print " done. Total $totalTuplesInserted tuples inserted.\n";
@@ -137,19 +141,19 @@ function convertLinks() {
                }
                # Check for existing links_backup, and delete it if it exists.
                print "Dropping backup links table if it exists...";
-               $dbConn->query( "DROP TABLE IF EXISTS links_backup", DB_WRITE);
+               $dbConn->query( "DROP TABLE IF EXISTS $links_backup", DB_MASTER);
                print " done.\n";
                
                # Swap in the new table, and move old links table to links_backup
-               print "Swapping tables 'links' to 'links_backup'; 'links_temp' to 'links'...";
-               $dbConn->query( "RENAME TABLE links TO links_backup, links_temp TO links", DB_WRITE );
+               print "Swapping tables '$links' to '$links_backup'; '$links_temp' to '$links'...";
+               $dbConn->query( "RENAME TABLE links TO $links_backup, $links_temp TO $links", DB_MASTER );
                print " done.\n\n";
                
                $dbConn->close();
-               print "Conversion complete. The old table remains at links_backup;\n";
+               print "Conversion complete. The old table remains at $links_backup;\n";
                print "delete at your leisure.\n";
        } else {
-               print "Conversion complete.  The converted table is at links_temp;\n";
+               print "Conversion complete.  The converted table is at $links_temp;\n";
                print "the original links table is unchanged.\n";
        }
 }
@@ -165,22 +169,23 @@ function createTempTable() {
                print "Opening connection to database failed.\n";
                return;
        }
+       $links_temp = $dbConn->tableName( 'links_temp' );
        
        print "Dropping temporary links table if it exists...";
-       $dbConn->query( "DROP TABLE IF EXISTS links_temp", DB_WRITE);
+       $dbConn->query( "DROP TABLE IF EXISTS $links_temp");
        print " done.\n";
        
        print "Creating temporary links table...";
        if ( $noKeys ) {
-               $dbConn->query( "CREATE TABLE links_temp ( " .
+               $dbConn->query( "CREATE TABLE $links_temp ( " .
                "l_from int(8) unsigned NOT NULL default '0', " .
-               "l_to int(8) unsigned NOT NULL default '0')", DB_WRITE);
+               "l_to int(8) unsigned NOT NULL default '0')");
        } else {
-               $dbConn->query( "CREATE TABLE links_temp ( " .
+               $dbConn->query( "CREATE TABLE $links_temp ( " .
                "l_from int(8) unsigned NOT NULL default '0', " .
                "l_to int(8) unsigned NOT NULL default '0', " .
                "UNIQUE KEY l_from(l_from,l_to), " .
-               "KEY (l_to))", DB_WRITE);
+               "KEY (l_to))");
        }
        print " done.\n\n";
 }
index 66c02d8..42120e2 100644 (file)
@@ -88,7 +88,7 @@ class Phase2Importer {
        # MySQL copies everything over to the new database and tweaks a few things.
        function importCurData() {
                print "Clearing pages from default install, if any...\n";
-               wfQuery( "DELETE FROM cur", DB_WRITE );
+               wfQuery( "DELETE FROM cur", DB_MASTER );
                
                print "Importing current revision data...\n";
                wfQuery( "INSERT INTO cur (cur_id,cur_namespace,cur_title,cur_text,cur_comment,
@@ -97,35 +97,35 @@ class Phase2Importer {
                        SELECT cur_id,0,cur_title,cur_text,cur_comment,
                                cur_user,cur_user_text,cur_timestamp,REPLACE(cur_restrictions,'is_',''),cur_counter,
                                cur_text like '#redirect%',cur_minor_edit,0,RAND(),NOW()+0,99999999999999-cur_timestamp
-                       FROM {$this->olddb}.cur", DB_WRITE );
+                       FROM {$this->olddb}.cur", DB_MASTER );
                $n = mysql_affected_rows();
                print "$n rows imported.\n";
        }
 
        function importOldData() {
                print "Clearing old revision data from default install, if any...\n";
-               wfQuery( "DELETE FROM old", DB_WRITE );
+               wfQuery( "DELETE FROM old", DB_MASTER );
 
                print "Importing old revision data...\n";
                wfQuery( "INSERT INTO old (old_id,old_namespace,old_title,old_text,old_comment,
                        old_user,old_user_text,old_timestamp,old_minor_edit,old_flags,inverse_timestamp)
                        SELECT old_id,0,old_title,old_text,old_comment,
                                old_user,old_user_text,old_timestamp,old_minor_edit,'',99999999999999-old_timestamp
-                       FROM {$this->olddb}.old", DB_WRITE );
+                       FROM {$this->olddb}.old", DB_MASTER );
                $n = mysql_affected_rows();
                print "$n rows imported.\n";
        }
 
        function importUserData() {
                print "Clearing users from default install, if any...\n";
-               wfQuery( "DELETE FROM user", DB_WRITE );
+               wfQuery( "DELETE FROM user", DB_MASTER );
 
                print "Importing user data...\n";
                wfQuery( "INSERT INTO $newdb.user (user_id,user_name,user_rights,
                        user_password,user_newpassword,user_email,user_options,user_touched)
                        SELECT user_id,user_name,REPLACE(user_rights,'is_',''),
                                MD5(CONCAT(user_id,'-',MD5(user_password))),'',user_email,user_options,NOW()+0
-                       FROM {$this->olddb}.user", DB_WRITE );
+                       FROM {$this->olddb}.user", DB_MASTER );
                $n = mysql_affected_rows();
                print "$n rows imported.\n";
        }
@@ -133,10 +133,10 @@ class Phase2Importer {
        # A little less clean...
        function importWatchlists() {
                print "Clearing watchlists from default install, if any...\n";
-               wfQuery( "DELETE FROM watchlist", DB_WRITE );
+               wfQuery( "DELETE FROM watchlist", DB_MASTER );
 
                print "Importing watchlists...";
-               $res = wfQuery( "SELECT user_id,user_watch FROM {$this->olddb}.user WHERE user_watch != ''", DB_WRITE );
+               $res = wfQuery( "SELECT user_id,user_watch FROM {$this->olddb}.user WHERE user_watch != ''", DB_MASTER );
                $total = wfNumRows( $res );
                $n = 0;
                print " ($total total)\n";
@@ -151,7 +151,7 @@ class Phase2Importer {
                                } else {
                                        $ns = $title->getNamespace();
                                        $t = wfStrencode( $title->getDBkey() );
-                                       wfQuery( "INSERT INTO watchlist(wl_user,wl_namespace,wl_title) VALUES ($id,$ns,'$t')", DB_WRITE );
+                                       wfQuery( "INSERT INTO watchlist(wl_user,wl_namespace,wl_title) VALUES ($id,$ns,'$t')", DB_MASTER );
                                }
                        }
                        if( ++$n % 50 == 0 ) {
@@ -164,14 +164,14 @@ class Phase2Importer {
        function importLinkData() {
                # MUST BE CALLED BEFORE! fixCurTitles()
                print "Clearing links from default install, if any...\n";
-               wfQuery( "DELETE FROM links", DB_WRITE );
-               wfQuery( "DELETE FROM brokenlinks", DB_WRITE );
+               wfQuery( "DELETE FROM links", DB_MASTER );
+               wfQuery( "DELETE FROM brokenlinks", DB_MASTER );
 
                print "Importing live links...";
                wfQuery( "INSERT INTO links (l_from, l_to)
                                        SELECT DISTINCT linked_from,cur_id
                                        FROM {$this->olddb}.linked,{$this->olddb}.cur
-                                       WHERE linked_to=cur_title", DB_WRITE );
+                                       WHERE linked_to=cur_title", DB_MASTER );
                $n = mysql_affected_rows();
                print "$n rows imported.\n";
                
@@ -179,7 +179,7 @@ class Phase2Importer {
                wfQuery( "INSERT INTO brokenlinks (bl_from, bl_to)
                                        SELECT DISTINCT cur_id,unlinked_to
                                        FROM {$this->olddb}.unlinked,{$this->olddb}.cur
-                                       WHERE unlinked_from=cur_title", DB_WRITE );
+                                       WHERE unlinked_from=cur_title", DB_MASTER );
                $n = mysql_affected_rows();
                print "$n rows imported.\n";
        }
@@ -195,7 +195,7 @@ class Phase2Importer {
        
        function fixTitles( $table ) {
                print "Fixing titles in $table...";
-               $res = wfQuery( "SELECT DISTINCT {$table}_title AS title FROM $table", DB_WRITE );
+               $res = wfQuery( "SELECT DISTINCT {$table}_title AS title FROM $table", DB_MASTER );
                $total = wfNumRows( $res );
                $n = 0;
                print " ($total total)\n";
@@ -209,7 +209,7 @@ class Phase2Importer {
                                $ns = $title->getNamespace();
                                $t = wfStrencode( $title->getDBkey() );
                                wfQuery( "UPDATE $table SET {$table}_namespace=$ns,{$table}_title='$t'
-                                                               WHERE {$table}_namespace=0 AND {$table}_title='$xt'", DB_WRITE );
+                                                               WHERE {$table}_namespace=0 AND {$table}_title='$xt'", DB_MASTER );
                        }
                        if( ++$n % 50 == 0 ) {
                                print "$n\n";
@@ -288,7 +288,7 @@ class Phase2Importer {
 
        function fixUserOptions() {
                print "Fixing user options...";
-               $res = wfQuery( "SELECT user_id,user_options FROM user", DB_WRITE );
+               $res = wfQuery( "SELECT user_id,user_options FROM user", DB_MASTER );
                $total = wfNumRows( $res );
                $n = 0;
                print " ($total total)\n";
@@ -296,7 +296,7 @@ class Phase2Importer {
                while( $row = wfFetchObject( $res ) ) {
                        $id = IntVal( $row->user_id );
                        $option = wfStrencode( $this->rewriteUserOptions( $row->user_options ) );
-                       wfQuery( "UPDATE user SET user_options='$option' WHERE user_id=$id LIMIT 1", DB_WRITE );
+                       wfQuery( "UPDATE user SET user_options='$option' WHERE user_id=$id LIMIT 1", DB_MASTER );
                        if( ++$n % 50 == 0 ) {
                                print "$n\n";
                        }
index fa03590..64a9ce2 100644 (file)
@@ -36,7 +36,6 @@ ALTER TABLE ipblocks
   ADD INDEX ipb_user (ipb_user);
 
 ALTER TABLE image
-  ADD INDEX img_name (img_name(10)),
   ADD INDEX img_size (img_size),
   ADD INDEX img_timestamp (img_timestamp);
 
diff --git a/maintenance/rebuildInterwiki.inc b/maintenance/rebuildInterwiki.inc
new file mode 100644 (file)
index 0000000..22c0f7f
--- /dev/null
@@ -0,0 +1,218 @@
+<?
+
+# Rebuild interwiki table using the file on meta and the language list
+# Wikimedia specific!
+$oldCwd = getcwd();
+
+$optionsWithArgs = array( "o" );
+include_once( "commandLine.inc" );
+
+class Site {
+       var $suffix, $lateral, $url;
+
+       function Site( $s, $l, $u ) {
+               $this->suffix = $s;
+               $this->lateral = $l;
+               $this->url = $u;
+       }
+
+       function getURL( $lang ) {
+               return "http://$lang.{$this->url}/wiki/\$1";
+       }
+}
+
+function getRebuildInterwikiSQL() {
+       global $langlist, $languageAliases;
+
+       # Initialise lists of wikis
+       $sites = array( 
+               'wiki' => new Site( 'wiki', 'w', 'wikipedia.org' ),
+               'wiktionary' => new Site( 'wiktionary', 'wikt', 'wiktionary.org' ),
+               'wikiquote' => new Site( 'wikiquote', 'wikiquote', 'wikiquote.org' ),
+               'wikibooks' => new Site( 'wikibooks', 'wikibooks', 'wikibooks.org' )
+       );
+       $langlist = array_map( "trim", file( "/home/wikipedia/common/langlist" ) );
+       $dblist = array_map( "trim", file( "/home/wikipedia/common/all.dblist" ) );
+       
+       $specials = array( 
+               'sourceswiki' => 'sources.wikipedia.org',
+               'quotewiki' => 'wikiquote.org',
+               'textbookwiki' => 'wikibooks.org',
+               'sep11wiki' => 'sep11.wikipedia.org',
+               'metawiki' => 'meta.wikimedia.org',
+       );
+
+       $extraLinks = array(
+               array( 'm', 'http://meta.wikimedia.org/wiki/$1', 1 ),
+               array( 'meta', 'http://meta.wikimedia.org/wiki/$1', 1 ),
+               array( 'sep11', 'http://sep11.wikipedia.org/wiki/$1', 1 ),
+       );
+
+       $languageAliases = array(
+               'zh-cn' => 'zh',
+               'zh-tw' => 'zh',
+       );
+
+       # Construct a list of reserved prefixes
+       $reserved = array();
+       foreach ( $langlist as $lang ) {
+               $reserved[$lang] = 1;
+       }
+       foreach ( $languageAliases as $alias => $lang ) {
+               $reserved[$alias] = 1;
+       }
+       foreach( $sites as $site ) {
+               $reserved[$site->lateral] = 1;
+       }
+
+       # Extract the intermap from meta
+       $dbr =& wfGetDB( DB_WRITE );
+       $row = $dbr->getArray( "metawiki.cur", array( "cur_text" ), 
+               array( "cur_namespace" => 0, "cur_title" => "Interwiki_map" ) );
+
+       if ( !$row ) {
+               die( "m:Interwiki_map not found" );
+       }
+
+       $lines = explode( "\n", $row->cur_text );
+       $iwArray = array();
+
+       foreach ( $lines as $line ) {
+               if ( preg_match( '/^\|\s*(.*?)\s*\|\|\s*(.*?)\s*$/', $line, $matches ) ) {
+                       $prefix = strtolower( $matches[1] );
+                       $url = $matches[2];
+                       if ( preg_match( '/(wikipedia|wiktionary|wikisource|wikiquote|wikibooks)\.org/', $url ) ) {
+                               $local = 1;
+                       } else {
+                               $local = 0;
+                       }
+                       
+                       if ( empty( $reserved[$prefix] ) ) {
+                               $iwArray[] = array( "iw_prefix" => $prefix, "iw_url" => $url, "iw_local" => $local );
+                       }
+               }
+       }
+       
+       $sql = "-- Generated by rebuildInterwiki.php";
+
+
+       foreach ( $dblist as $db ) {
+               if ( isset( $specials[$db] ) ) {
+                       # Special wiki
+                       # Has interwiki links and interlanguage links to wikipedia
+                       
+                       $host = $specials[$db];
+                       $sql .= "\n--$host\n\n";
+                       $sql .= "USE $db;\n" .
+                                       "TRUNCATE TABLE interwiki;\n" . 
+                                       "INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES \n";
+                       $first = true;
+                       
+                       # Intermap links
+                       foreach ( $iwArray as $iwEntry ) {
+                               $sql .= makeLink( $iwEntry, $first );
+                       }
+
+                       # Links to multilanguage sites
+                       foreach ( $sites as $targetSite ) {
+                               $sql .= makeLink( array( $targetSite->lateral, $targetSite->getURL( 'en' ), 1 ), $first );
+                       }
+                       
+                       # Interlanguage links to wikipedia
+                       $sql .= makeLanguageLinks( $sites['wiki'], $first );
+
+                       # Extra links
+                       foreach ( $extraLinks as $link ) {
+                                       $sql .= makeLink( $link, $first );
+                       }
+                       
+                       $sql .= ";\n";
+               } else {
+                       # Find out which site this DB belongs to
+                       $site = false;
+                       foreach( $sites as $candidateSite ) {
+                               $suffix = $candidateSite->suffix;
+                               if ( preg_match( "/(.*)$suffix$/", $db, $matches ) ) {
+                                       $site = $candidateSite;
+                                       break;
+                               }
+                       }
+                       if ( !$site ) {
+                               print "Invalid database $db\n";
+                               continue;
+                       }
+                       $lang = $matches[1];
+                       $host = "$lang." . $site->url;
+                       $sql .= "\n--$host\n\n";
+                       
+                       $sql .= "USE $db;\n" .
+                                       "TRUNCATE TABLE interwiki;\n" .
+                                       "INSERT INTO interwiki (iw_prefix,iw_url,iw_local) VALUES\n";
+                       $first = true;
+
+                       # Intermap links
+                       foreach ( $iwArray as $iwEntry ) {
+                               $sql .= makeLink( $iwEntry, $first );
+                       }
+
+                       # Lateral links
+                       foreach ( $sites as $targetSite ) {
+                               # Suppress link to self
+                               if ( $targetSite->suffix != $site->suffix ) {
+                                       $sql .= makeLink( array( $targetSite->lateral, $targetSite->getURL( $lang ), 1 ), $first );
+                               }
+                       }
+
+                       # Interlanguage links
+                       $sql .= makeLanguageLinks( $site, $first );
+
+                       # w link within wikipedias
+                       # Other sites already have it as a lateral link
+                       if ( $site->suffix == "wiki" ) {
+                               $sql .= makeLink( array("w", "http://en.wikipedia.org/wiki/$1", 1), $first );
+                       }
+                       
+                       # Extra links
+                       foreach ( $extraLinks as $link ){ 
+                                       $sql .= makeLink( $link, $first );
+                       }
+                       $sql .= ";\n\n";
+               }
+       }
+       return $sql;
+}
+
+# ------------------------------------------------------------------------------------------
+
+# Returns part of an INSERT statement, corresponding to all interlanguage links to a particular site
+function makeLanguageLinks( &$site, &$first ) {
+       global $langlist, $languageAliases;
+
+       $sql = "";
+
+       # Actual languages with their own databases
+       foreach ( $langlist as $targetLang ) {
+               $sql .= makeLink( array( $targetLang, $site->getURL( $targetLang ), 1 ), $first );
+       }
+
+       # Language aliases
+       foreach ( $languageAliases as $alias => $lang ) {
+               $sql .= makeLink( array( $alias, $site->getURL( $lang ), 1 ), $first );
+       }
+       return $sql;
+}
+
+# Make SQL for a single link from an array
+function makeLink( $entry, &$first ) {
+       $sql = "";
+       # Add comma
+       if ( $first ) {
+               $first = false;
+       } else {
+               $sql .= ",\n";
+       }
+       $sql .= "(" . Database::makeList( $entry ) . ")";
+       return $sql;
+}
+
+?>
index 328e765..d2add0b 100644 (file)
@@ -6,158 +6,9 @@ $oldCwd = getcwd();
 
 $optionsWithArgs = array( "o" );
 include_once( "commandLine.inc" );
+include_once( "rebuildInterwiki.inc" );
 
-class Site {
-       var $suffix, $lateral, $url;
-
-       function Site( $s, $l, $u ) {
-               $this->suffix = $s;
-               $this->lateral = $l;
-               $this->url = $u;
-       }
-
-       function getURL( $lang ) {
-               return "http://$lang.{$this->url}/wiki/\$1";
-       }
-}
-
-# Initialise lists of wikis
-$sites = array( 
-       'wiki' => new Site( 'wiki', 'w', 'wikipedia.org' ),
-       'wiktionary' => new Site( 'wiktionary', 'wikt', 'wiktionary.org' )
-);
-$langlist = array_map( "trim", file( "/home/wikipedia/common/langlist" ) );
-
-$specials = array( 
-       'sourceswiki' => 'sources.wikipedia.org',
-       'quotewiki' => 'wikiquote.org',
-       'textbookwiki' => 'wikibooks.org',
-       'sep11wiki' => 'sep11.wikipedia.org',
-       'metawiki' => 'meta.wikipedia.org',
-);
-
-$extraLinks = array(
-       array( 'm', 'http://meta.wikipedia.org/wiki/$1', 1 ),
-       array( 'meta', 'http://meta.wikipedia.org/wiki/$1', 1 ),
-       array( 'sep11', 'http://sep11.wikipedia.org/wiki/$1', 1 ),
-);
-
-$languageAliases = array(
-       'zh-cn' => 'zh',
-       'zh-tw' => 'zh',
-);
-
-# Extract the intermap from meta
-
-$row = wfGetArray( "metawiki.cur", array( "cur_text" ), array( "cur_namespace" => 0, "cur_title" => "Interwiki_map" ) );
-
-if ( !$row ) {
-       die( "m:Interwiki_map not found" );
-}
-
-$lines = explode( "\n", $row->cur_text );
-$iwArray = array();
-
-foreach ( $lines as $line ) {
-       if ( preg_match( '/^\|\s*(.*?)\s*\|\|\s*(.*?)\s*$/', $line, $matches ) ) {
-               $prefix = $matches[1];
-               $url = $matches[2];
-               if ( preg_match( '/(wikipedia|wiktionary|wikisource|wikiquote|wikibooks)\.org/', $url ) ) {
-                       $local = 1;
-               } else {
-                       $local = 0;
-               }
-
-               $iwArray[] = array( "iw_prefix" => $prefix, "iw_url" => $url, "iw_local" => $local );
-       }
-}
-
-
-# Insert links into special wikis
-# These have intermap links and interlanguage links pointing to wikipedia
-
-$sql = "-- Generated by rebuildInterwiki.php";
-
-foreach ( $specials as $db => $host ) {
-       $sql .= "\nUSE $db;\n" .
-                       "TRUNCATE TABLE interwiki;\n" . 
-                       "INSERT INTO interwiki (iw_prefix, iw_url, iw_local) VALUES \n";
-       $first = true;
-       
-       # Intermap links
-       foreach ( $iwArray as $iwEntry ) {
-               # Suppress links to self
-               if ( strpos( $iwEntry['iw_url'], $host ) === false ) {
-                       $sql .= makeLink( $iwEntry, $first );
-               }
-       }
-       # w link
-       $sql .= makeLink( array("w", "http://en.wikipedia.org/wiki/$1", 1 ), $first );
-       
-       # Interlanguage links to wikipedia
-       $sql .= makeLanguageLinks( $sites['wiki'], $first );
-
-       # Extra links
-       foreach ( $extraLinks as $link ) {
-                       $sql .= makeLink( $link, $first );
-       }
-       
-       $sql .= ";\n";
-}
-$sql .= "\n";
-
-# Insert links into multilanguage sites
-
-foreach ( $sites as $site ) {
-       $sql .= <<<EOS
-
----
---- {$site->suffix}
----
-
-EOS;
-       foreach ( $langlist as $lang ) {
-               $db = $lang . $site->suffix;
-               $db = str_replace( "-", "_", $db );
-
-               $sql .= "USE $db;\n" .
-                               "TRUNCATE TABLE interwiki;\n" .
-                               "INSERT INTO interwiki (iw_prefix,iw_url,iw_local) VALUES\n";
-               $first = true;
-
-               # Intermap links
-               foreach ( $iwArray as $iwEntry ) {
-                       # Suppress links to self
-                       if ( strpos( $iwEntry['iw_url'], $site->url ) === false || 
-                         strpos( $iwEntry['iw_url'], 'meta.wikipedia.org' ) !== false ) {
-                               $sql .= makeLink( $iwEntry, $first );
-                       }
-               }
-
-               # Lateral links
-               foreach ( $sites as $targetSite ) {
-                       # Suppress link to self
-                       if ( $targetSite->suffix != $site->suffix ) {
-                               $sql .= makeLink( array( $targetSite->lateral, $targetSite->getURL( $lang ), 1 ), $first );
-                       }
-               }
-
-               # Interlanguage links
-               $sql .= makeLanguageLinks( $site, $first );
-
-               # w link within wikipedias
-               # Other sites already have it as a lateral link
-               if ( $site->suffix == "wiki" ) {
-                       $sql .= makeLink( array("w", "http://en.wikipedia.org/wiki/$1", 1), $first );
-               }
-               
-               # Extra links
-               foreach ( $extraLinks as $link ){ 
-                               $sql .= makeLink( $link, $first );
-               }
-               $sql .= ";\n\n";
-       }
-}
+$sql = getRebuildInterwikiSQL();
 
 # Output
 if ( isset( $options['o'] ) ) {        
@@ -171,37 +22,4 @@ if ( isset( $options['o'] ) ) {
        print $sql;
 }
 
-# ------------------------------------------------------------------------------------------
-
-# Returns part of an INSERT statement, corresponding to all interlanguage links to a particular site
-function makeLanguageLinks( &$site, &$first ) {
-       global $langlist, $languageAliases;
-
-       $sql = "";
-
-       # Actual languages with their own databases
-       foreach ( $langlist as $targetLang ) {
-               $sql .= makeLink( array( $targetLang, $site->getURL( $targetLang ), 1 ), $first );
-       }
-
-       # Language aliases
-       foreach ( $languageAliases as $alias => $lang ) {
-               $sql .= makeLink( array( $alias, $site->getURL( $lang ), 1 ), $first );
-       }
-       return $sql;
-}
-
-# Make SQL for a single link from an array
-function makeLink( $entry, &$first ) {
-       $sql = "";
-       # Add comma
-       if ( $first ) {
-               $first = false;
-       } else {
-               $sql .= ",\n";
-       }
-       $sql .= "(" . Database::makeList( $entry ) . ")";
-       return $sql;
-}
-
 ?>
index eb549b4..0a40f94 100755 (executable)
@@ -21,7 +21,8 @@ if ( isset( $args[0] ) ) {
 }
 
 if ( $response == 0 ) {
-       $row = wfGetArray( "cur", array("count(*) as c"), array("cur_namespace" => NS_MEDIAWIKI) );
+       $dbr =& wfGetDB( DB_SLAVE );
+       $row = $dbr->selectRow( "cur", array("count(*) as c"), array("cur_namespace" => NS_MEDIAWIKI) );
        print "Current namespace size: {$row->c}\n";
 
        print   "1. Update messages to include latest additions to Language.php\n" . 
index 3aba4d0..83298d1 100644 (file)
@@ -27,42 +27,42 @@ function rebuildLinkTables()
        print "Rebuilding link tables.\n";
 
        print "Setting AUTOCOMMIT=1\n";
-       wfQuery("SET SESSION AUTOCOMMIT=1", DB_WRITE);
+       wfQuery("SET SESSION AUTOCOMMIT=1", DB_MASTER);
 
        print "Extracting often used data from cur (may take a few minutes)\n";
        $sql = "CREATE TEMPORARY TABLE cur_fast SELECT cur_namespace, cur_title, cur_id FROM cur";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
        $sql = "ALTER TABLE cur_fast ADD INDEX(cur_namespace, cur_title)";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
        print "Locking tables\n";
        $sql = "LOCK TABLES cur READ, cur_fast READ, interwiki READ, user_newtalk READ, " .
                "links WRITE, brokenlinks WRITE, imagelinks WRITE";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
 
        print "Deleting old data in links table.\n";
        $sql = "DELETE FROM links";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
        print "Deleting old data in brokenlinks table.\n";
        $sql = "DELETE FROM brokenlinks";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
        print "Deleting old data in imagelinks table.\n";
        $sql = "DELETE FROM imagelinks";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
 
        print "Finding number of articles to process... ";
        $sql = "SELECT COUNT(*) as count FROM cur";
-       $res = wfQuery( $sql, DB_READ );
+       $res = wfQuery( $sql, DB_SLAVE );
        $obj = wfFetchObject( $res );
        $total = $obj->count;
        print "$total\n";
 
        print "Finding highest article id\n";
        $sql = "SELECT MIN(cur_id) AS min, MAX(cur_id) AS max FROM cur";
-       $res = wfQuery( $sql, DB_READ );
+       $res = wfQuery( $sql, DB_SLAVE );
        $obj = wfFetchObject( $res );
  
        $cur_pulser = new SelectPulser("SELECT cur_id,cur_namespace,cur_title,cur_text " .
@@ -169,7 +169,7 @@ function rebuildLinkTables()
                        }
                        $sql = "SELECT cur_namespace, cur_title, cur_id FROM cur_fast WHERE " . 
                                implode(" OR ", $parts);
-                       $res = wfQuery( $sql, DB_WRITE );
+                       $res = wfQuery( $sql, DB_MASTER );
                        while($row = wfFetchObject( $res ) ){
                                $pos = $titles_needing_curdata_pos[$row->cur_title . $row->cur_namespace];
                                $titles_needing_curdata[$pos]->mArticleID = intval($row->cur_id);
@@ -226,7 +226,7 @@ function rebuildLinkTables()
        print "$count articles scanned.\n";
 
        $sql = "UNLOCK TABLES";
-       wfQuery( $sql, DB_WRITE );
+       wfQuery( $sql, DB_MASTER );
        print "Done\n";
 }
 
@@ -267,7 +267,7 @@ class InsertBuffer {
        function flush(){
                if( $this->mBufcount > 0 ){
                        $sql = $this->mSql . implode(",", $this->mBuf);
-                       wfQuery( $sql, DB_WRITE );
+                       wfQuery( $sql, DB_MASTER );
                        $this->mBuf = array();
                        $this->mBufcount = 0;
                        // print "Wrote query of size " . strlen( $sql ) . "\n";
@@ -303,7 +303,7 @@ class SelectPulser {
                                " AND " . ($this->mPos + $this->mSetsize - 1);
                        $this->mPos += $this->mSetsize;
 
-                       $res = wfQuery( $sql, DB_READ );
+                       $res = wfQuery( $sql, DB_SLAVE );
                        while ( $row = wfFetchObject( $res ) ) {
                                $this->mSet[] = $row;
                        }
index d14a4b9..f4d739e 100644 (file)
@@ -5,42 +5,59 @@
 
 function rebuildRecentChangesTablePass1()
 {
-       $sql = "DELETE FROM recentchanges";
-       wfQuery( $sql, DB_WRITE );
+       $fname = 'rebuildRecentChangesTablePass1';
+       $dbw =& wfGetDB( DB_MASTER );
+       extract( $dbw->tableNames( 'recentchanges', 'cur', 'old' );
 
-       print( "Loading from CUR table...\n" );
+       $dbw->delete( 'recentchanges', '*' );
 
-       $sql = "INSERT INTO recentchanges (rc_timestamp,rc_cur_time,rc_user," .
-         "rc_user_text,rc_namespace,rc_title,rc_comment,rc_minor,rc_bot,rc_new," .
-         "rc_cur_id,rc_this_oldid,rc_last_oldid) SELECT cur_timestamp," .
-         "cur_timestamp,cur_user,cur_user_text,cur_namespace,cur_title," .
-         "cur_comment,cur_minor_edit,0,cur_is_new,cur_id,0,0 FROM cur " .
-         "ORDER BY inverse_timestamp LIMIT 5000";
-       wfQuery( $sql, DB_WRITE );
+       print( "Loading from CUR table...\n" );
 
+       $dbw->insertSelect( 'recentchanges', 'cur', 
+               array(
+                       'rc_timestamp' => 'cur_timestamp',
+                       'rc_cur_time' => 'cur_timestamp',
+                       'rc_user' => 'cur_user',
+                       'rc_user_text' => 'cur_user_text',
+                       'rc_namespace' => 'cur_namespace',
+                       'rc_title' => 'cur_title',
+                       'rc_comment' => 'cur_comment',
+                       'rc_minor' => 'cur_minor_edit',
+                       'rc_bot' => 0,
+                       'rc_new' => 'cur_is_new',
+                       'rc_cur_id' => 'cur_id',
+                       'rc_this_oldid' => 0,
+                       'rc_last_oldid' => 0,
+                       'rc_type' => 'IF(cur_is_new,' . RC_NEW . ',' . RC_EDIT . ')'
+               ), '*', $fname, array( 'ORDER BY' => 'inverse_timestamp', 'LIMIT' => 5000 
+       );
+       
        print( "Loading from OLD table...\n" );
 
-       $sql = "INSERT INTO recentchanges (rc_timestamp,rc_cur_time,rc_user," .
+       $sql = "INSERT INTO $recentchanges (rc_timestamp,rc_cur_time,rc_user," .
       "rc_user_text,rc_namespace,rc_title,rc_comment,rc_minor,rc_bot,rc_new," .
       "rc_cur_id,rc_this_oldid,rc_last_oldid) SELECT old_timestamp,cur_timestamp," .
          "old_user,old_user_text,old_namespace,old_title,old_comment," .
-         "old_minor_edit,0,0,cur_id,old_id,0 FROM old,cur " .
-         "WHERE old_namespace=cur_namespace AND old_title=cur_title ORDER BY old.inverse_timestamp " .
+         "old_minor_edit,0,0,cur_id,old_id,0 FROM $old,$cur " .
+         "WHERE old_namespace=cur_namespace AND old_title=cur_title ORDER BY $old.inverse_timestamp " .
          "LIMIT 5000";
-       wfQuery( $sql, DB_WRITE );
+       $dbw->query( $sql );
 
-       $sql = "SELECT rc_timestamp FROM recentchanges " .
+       $sql = "SELECT rc_timestamp FROM $recentchanges " .
          "ORDER BY rc_timestamp DESC LIMIT 5000,1";
-       $res = wfQuery( $sql, DB_WRITE );
-       $obj = wfFetchObject( $res );
+       $res = $dbw->query( $sql );
+       $obj = $dbw->fetchObject( $res );
        $ts = $obj->rc_timestamp;
 
-       $sql = "DELETE FROM recentchanges WHERE rc_timestamp < '{$ts}'";
-       wfQuery( $sql, DB_WRITE );
+       $sql = "DELETE FROM $recentchanges WHERE rc_timestamp < '{$ts}'";
+       $dbw->query( $sql );
 }
 
 function rebuildRecentChangesTablePass2()
 {
+       $dbw =& wfGetDB( DB_MASTER );
+       extract( $dbw->tableNames( 'recentchanges', 'cur', 'old' );
+
        $ns = $id = $count = 0;
        $title = $ct =  "";
 
@@ -48,40 +65,41 @@ function rebuildRecentChangesTablePass2()
 
        # Fill in the rc_last_oldid field, which points to the previous edit
        #
-       $sql = "SELECT rc_cur_id,rc_this_oldid,rc_timestamp FROM recentchanges " .
+       $sql = "SELECT rc_cur_id,rc_this_oldid,rc_timestamp FROM $recentchanges " .
          "ORDER BY rc_cur_id,rc_timestamp";
-       $res = wfQuery( $sql, DB_WRITE );
+       $res = $dbw->query( $sql, DB_MASTER );
 
        $lastCurId = 0;
        $lastOldId = 0;
-       while ( $obj = wfFetchObject( $res ) ) {
+       while ( $obj = $dbw->fetchObject( $res ) ) {
                $new = 0;
                if( $obj->rc_cur_id != $lastCurId ) {
                        # Switch! Look up the previous last edit, if any
                        $lastCurId = IntVal( $obj->rc_cur_id );
                        $emit = wfInvertTimestamp( $obj->rc_timestamp );
-                       $sql2 = "SELECT old_id FROM old,cur " .
+                       $sql2 = "SELECT old_id FROM $old,$cur " .
                                "WHERE old_namespace=cur_namespace AND old_title=cur_title AND cur_id={$lastCurId} ".
-                               "AND old.inverse_timestamp>'{$emit}' ORDER BY old.inverse_timestamp LIMIT 1";
-                       $res2 = wfQuery( $sql2, DB_WRITE );
-                       if( $row = wfFetchObject( $res2 ) ) {
+                               "AND $old.inverse_timestamp>'{$emit}' ORDER BY $old.inverse_timestamp LIMIT 1";
+                       $res2 = $dbw->query( $sql2 );
+                       if( $row = $dbw->fetchObject( $res2 ) ) {
                                $lastOldId = IntVal( $row->old_id );
                        } else {
                                # No previous edit
                                $lastOldId = 0;
                                $new = 1;
                        }
-                       wfFreeResult( $res2 );
+                       $dbw->freeResult( $res2 );
                }
                if( $lastCurId == 0 ) {
                        print "Uhhh, something wrong? No curid\n";
                } else {
-                       $sql3 = "UPDATE recentchanges SET rc_last_oldid=$lastOldId,rc_new=$new,rc_type=$new WHERE rc_cur_id={$lastCurId} AND rc_this_oldid={$obj->rc_this_oldid}";
-                       wfQuery( $sql3, DB_WRITE );
+                       $sql3 = "UPDATE $recentchanges SET rc_last_oldid=$lastOldId,rc_new=$new,rc_type=$new " .
+                               "WHERE rc_cur_id={$lastCurId} AND rc_this_oldid={$obj->rc_this_oldid}";
+                       $dbw->query( $sql3 );
                        $lastOldId = IntVal( $obj->rc_this_oldid );
                }
        }
-       wfFreeResult( $res );
+       $dbw->freeResult( $res );
 }
 
 ?>
index 2608226..04e0eb6 100644 (file)
@@ -10,29 +10,30 @@ define( "RTI_CHUNK_SIZE", 500 );
 
 function dropTextIndex( &$database )
 {
-       if ( wfIndexExists( "searchindex", "si_title" ) ) {
+       $searchindex = $database->tableName( 'searchindex' );
+       if ( $database->indexExists( "searchindex", "si_title" ) ) {
                echo "Dropping index...\n";
-               $sql = "ALTER TABLE searchindex DROP INDEX si_title, DROP INDEX si_text";
+               $sql = "ALTER TABLE $searchindex DROP INDEX si_title, DROP INDEX si_text";
                $database->query($sql, "dropTextIndex" );
        }
-       # Truncate table, in an attempt to bring the slaves to a consistent state
-       # (zwinger was accidentally written to)
-       $database->query( "TRUNCATE TABLE searchindex", "dropTextIndex" );
 }
 
 function createTextIndex( &$database )
 {
+       $searchindex = $database->tableName( 'searchindex' );
        echo "Rebuild the index...\n";
-       $sql = "ALTER TABLE searchindex ADD FULLTEXT si_title (si_title), " .
+       $sql = "ALTER TABLE $searchindex ADD FULLTEXT si_title (si_title), " .
          "ADD FULLTEXT si_text (si_text)";
        $database->query($sql, "createTextIndex" );
 }
 
 function rebuildTextIndex( &$database )
 {
-       $sql = "SELECT MAX(cur_id) AS count FROM cur";
+       extract( $database->tableNames( 'cur', 'searchindex' ) );
+
+       $sql = "SELECT MAX(cur_id) AS count FROM $cur";
        $res = $database->query($sql, "rebuildTextIndex" );
-       $s = wfFetchObject($res);
+       $s = $database->fetchObject($res);
        $count = $s->count;
        echo "Rebuilding index fields for {$count} pages...\n";
        $n = 0;
@@ -40,14 +41,14 @@ function rebuildTextIndex( &$database )
        while ( $n < $count ) {
                print "$n\n";
                $end = $n + RTI_CHUNK_SIZE - 1;
-               $sql = "SELECT cur_id, cur_namespace, cur_title, cur_text FROM cur WHERE cur_id BETWEEN $n AND $end";
+               $sql = "SELECT cur_id, cur_namespace, cur_title, cur_text FROM $cur WHERE cur_id BETWEEN $n AND $end";
                $res = $database->query($sql, "rebuildTextIndex" );
 
-               while( $s = wfFetchObject($res) ) {
+               while( $s = $database->fetchObject($res) ) {
                        $u = new SearchUpdate( $s->cur_id, $s->cur_title, $s->cur_text );
                        $u->doUpdate();
                }
-               wfFreeResult( $res );
+               $database->freeResult( $res );
                $n += RTI_CHUNK_SIZE;
        }
 }
index 42e1138..285aba7 100644 (file)
@@ -6,9 +6,9 @@ define( "PAUSE_INTERVAL", 50 );
 function refreshLinks( $start ) {
        global $wgUser, $wgTitle, $wgArticle, $wgEnablePersistentLC, $wgLinkCache, $wgOut;
 
-       $res = wfQuery("SELECT max(cur_id) as m FROM cur", DB_READ);
-       $row = wfFetchObject( $res );
-       $end = $row->m;
+       $dbw =& wfGetDB( DB_MASTER );
+       
+       $end = $dbw->selectField( 'cur_id', 'max(cur_id)', false );
 
        print("Refreshing link table. Starting from cur_id $start of $end.\n");
 
@@ -32,10 +32,11 @@ function refreshLinks( $start ) {
                $wgArticle = new Article( $wgTitle );
                $text = $wgArticle->getContent( true );
                $wgLinkCache = new LinkCache;
+               $wgLinkCache->forUpdate( true );
                $wgOut->addWikiText( $text );
 
                if ( $wgEnablePersistentLC ) {
-                       $wgLinkCache->saveToLinkscc( $id, wfStrencode( $wgTitle->getPrefixedDBkey() ) );
+                       $wgLinkCache->saveToLinkscc( $id, $dbw->strencode( $wgTitle->getPrefixedDBkey() ) );
                }
 
                $linksUpdate = new LinksUpdate( $id, $wgTitle->getPrefixedDBkey() );
index 7faecef..8cdd9ba 100644 (file)
@@ -5,19 +5,16 @@ require_once( "commandLine.inc" );
 require_once( "./rebuildrecentchanges.inc" );
 $wgTitle = Title::newFromText( "Rebuild brokenlinks script" );
 
-$wgDBuser                      = $wgDBadminuser;
-$wgDBpassword          = $wgDBadminpassword;
-
-
-# That above is common code and should be hidden away :(
-
 $n = 0;
 
 echo "Checking for broken brokenlinks...\n";
 
-$sql = "SELECT cur_namespace,cur_title,cur_id FROM cur";
-$res = wfQuery( $sql, DB_WRITE );
-while( $s = wfFetchObject( $res ) ) {
+$dbw =& wfGetDB( DB_MASTER );
+extract( $dbw->tableNames( 'brokenlinks', 'cur', 'linkscc' );
+
+$res = $dbw->select( 'cur', array( 'cur_namespace', 'cur_title', 'cur_id' ), false );
+
+while( $s = $dbw->fetchObject( $res ) ) {
        $n++;
        if(($n % 500) == 0) {
                echo "$n\n";
@@ -25,21 +22,22 @@ while( $s = wfFetchObject( $res ) ) {
        $title = Title::makeTitle( $s->cur_namespace, $s->cur_title );
        if($title) {
                $t = $title->getPrefixedDBKey();
-               $tt = wfStrencode( $t );
+               $tt = $dbw->strencode( $t );
                $any = false;
-               $sql2 = "SELECT bl_from,cur_id,cur_namespace,cur_title FROM brokenlinks,cur WHERE bl_to='$tt' AND cur_id=bl_from";
-               $res2 = wfQuery( $sql2, DB_WRITE );
-               while( $s = wfFetchObject( $res2 ) ) {
+               $sql2 = "SELECT bl_from,cur_id,cur_namespace,cur_title FROM $brokenlinks,$cur " .
+                       "WHERE bl_to='$tt' AND cur_id=bl_from";
+               $res2 = $dbw->query( $sql2 );
+               while( $s = $dbw->fetchObject( $res2 ) ) {
                        $from = Title::makeTitle( $s->cur_namespace, $s->cur_title );
                        $xt = $from->getPrefixedText();
                        echo "Found bad brokenlink to [[$t]] from page #$s->cur_id [[$xt]]!\n";
                        $any = true;
                }
-               wfFreeResult( $res2 );
+               $dbw->freeResult( $res2 );
                if($any) {
                        echo "Removing brokenlinks to [[$t]]...\n";
-                       $sql3 = "DELETE FROM brokenlinks WHERE bl_to='$tt'";
-                       $res3 = wfQuery( $sql3, DB_WRITE );
+                       $sql3 = "DELETE FROM $brokenlinks WHERE bl_to='$tt'";
+                       $res3 = $dbw->query( $sql3 );
                        #echo "-- $sql3\n";
                }
        } else {
@@ -49,7 +47,7 @@ while( $s = wfFetchObject( $res ) ) {
 echo "Done at $n.\n\n";
 
 echo "Clearing linkscc table...\n";
-$sql4 = "DELETE FROM linkscc";
-wfQuery( $sql4, DB_WRITE );
+$sql4 = "DELETE FROM $linkscc";
+wfQuery( $sql4, DB_MASTER );
 
 ?>
index da269c6..6d1e4d4 100644 (file)
@@ -160,7 +160,8 @@ CREATE TABLE image (
   img_description tinyblob NOT NULL default '',
   img_user int(5) unsigned NOT NULL default '0',
   img_user_text varchar(255) binary NOT NULL default '',
-  img_timestamp char(14) binary NOT NULL default ''
+  img_timestamp char(14) binary NOT NULL default '',
+  UNIQUE KEY img_name (img_name)
 ) PACK_KEYS=1;
 
 CREATE TABLE oldimage (
index 4a0bb39..321e86e 100644 (file)
@@ -4,8 +4,10 @@ print "DB name: $wgDBname\n";
 print "DB user: $wgDBuser\n";
 print "DB password: $wgDBpassword\n";
 
-$res = wfQuery( "SELECT MAX(cur_id) as m FROM cur", DB_READ );
-$row = wfFetchObject( $res );
+$dbr =& wfGetDB( DB_SLAVE );
+$cur = $dbr->tableName( 'cur' );
+$res = $dbr->query( "SELECT MAX(cur_id) as m FROM $cur" );
+$row = $dbr->fetchObject( $res );
 print "Max cur_id: {$row->m}\n";
 
 ?>
index f3c3646..1344f51 100644 (file)
@@ -9,15 +9,18 @@ function updateSearchIndex( $start, $end, $maxLockTime, $quiet ) {
        $wgQuiet = $quiet;
        $wgDisableSearchUpdate = false;
 
+       $dbw =& wfGetDB( DB_MASTER );
+       $recentchanges = $dbw->tableName( 'recentchanges' );
+       
        output( "Updating searchindex between $start and $end\n" );
 
        # Select entries from recentchanges which are on top and between the specified times
-       $start = wfStrencode( $start );
-       $end = wfStrencode( $end );
+       $start = $dbw->strencode( $start );
+       $end = $dbw->strencode( $end );
 
-       $sql = "SELECT rc_cur_id,rc_type,rc_moved_to_ns,rc_moved_to_title FROM recentchanges
+       $sql = "SELECT rc_cur_id,rc_type,rc_moved_to_ns,rc_moved_to_title FROM $recentchanges
          WHERE rc_this_oldid=0 AND rc_timestamp BETWEEN '$start' AND '$end'";
-       $res = wfQuery( $sql, DB_READ, $fname );
+       $res = $dbw->query( $sql, $fname );
 
        # Lock searchindex
        if ( $maxLockTime ) {
@@ -28,7 +31,7 @@ function updateSearchIndex( $start, $end, $maxLockTime, $quiet ) {
        }
 
        # Loop through the results and do a search update
-       while ( $row = wfFetchObject( $res ) ) {
+       while ( $row = $dbw->fetchObject( $res ) ) {
                # Allow reads to be processed
                if ( $maxLockTime && time() > $lockTime + $maxLockTime ) {
                        output( "    --- Relocking ---" );
@@ -47,7 +50,8 @@ function updateSearchIndex( $start, $end, $maxLockTime, $quiet ) {
                        output( "\n" );
                } else {
                        # Get cur row
-                       $curRow = wfGetArray( 'cur', array( 'cur_namespace', 'cur_title', 'cur_text' ), array( 'cur_id' => $row->rc_cur_id ) );
+                       $curRow = $dbw->selectRow( 'cur', array( 'cur_namespace', 'cur_title', 'cur_text' ), 
+                               array( 'cur_id' => $row->rc_cur_id ), $fname, 'FOR UPDATE' );
                        if ( $curRow ) {
                                $titleObj = Title::makeTitle( $curRow->cur_namespace, $curRow->cur_title );
                                $title = $titleObj->getPrefixedDBkey();
@@ -67,12 +71,15 @@ function updateSearchIndex( $start, $end, $maxLockTime, $quiet ) {
        output( "Done\n" );
 }
 
-function lockSearchindex() {
-       wfQuery( "LOCK TABLES searchindex LOW_PRIORITY WRITE, cur READ, interwiki READ", DB_WRITE );
+function lockSearchindex( &$db ) {
+       $dbw =& wfGetDB( DB_MASTER );
+       extract( $dbw->tableNames( 'searchindex', 'cur', 'interwiki' ) );
+       $dbw->query( "LOCK TABLES $searchindex LOW_PRIORITY WRITE, $cur READ, $interwiki READ" );
 }
 
 function unlockSearchindex() {
-       wfQuery( "UNLOCK TABLES", DB_WRITE );
+       $dbw =& wfGetDB( DB_MASTER );
+       $dbw->query( "UNLOCK TABLES" );
 }
 
 # Unlock and lock again
index 8ed663b..5538107 100644 (file)
@@ -184,4 +184,15 @@ function do_categorylinks_update() {
                echo "ok\n";
        }
 }
+
+function do_image_name_unique_update() {
+       global $wgDatabase;
+       if ( $wgDatabase->indexUnique( 'image', 'img_name' ) ) {
+               echo "...img_name already unique.\n";
+       } else {
+               echo "Making the img_name index unique... ";
+               dbsource( "maintenance/archives/patch-image_name_unique.sql", $wgDatabase );
+               echo "ok\n";
+       }
+}
 ?>
index 7f5e1a0..a47416e 100644 (file)
@@ -28,7 +28,7 @@ function xlinkToMathImage ( $tex, $outputhash )
 function texvc_cgi_renderMath( $tex )
 {
        global $wgMathDirectory, $wgTmpDirectory, $wgInputEncoding;
-       $dbr =& wfGetDB( DB_READ );
+       $dbr =& wfGetDB( DB_SLAVE );
        $mf   = wfMsg( "math_failure" );
        $munk = wfMsg( "math_unknown_error" );
 
@@ -113,7 +113,7 @@ function texvc_cgi_renderMath( $tex )
                $outmd5_sql = pack("H32", $outmd5);
                
                # Someone may have inserted the same hash since the SELECT, but that's no big deal, just ignore errors
-               $dbw =& wfGetDB( DB_WRITE );
+               $dbw =& wfGetDB( DB_MASTER );
                $dbw->insertArray( 'math', 
                  array( 
                    'math_inputhash' => $md5_sql,