aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Starling <tstarling@users.mediawiki.org>2004-07-10 03:09:26 +0000
committerTim Starling <tstarling@users.mediawiki.org>2004-07-10 03:09:26 +0000
commitb96b707efa42ebcbc78e50fedcc29ccaf8dd1467 (patch)
tree7048c60e9e79e21dcf76bbe806de4400b3849864
parent9b868b96f49a60ef16a18aff3514de7765ffa3c1 (diff)
downloadmediawikicore-b96b707efa42ebcbc78e50fedcc29ccaf8dd1467.tar.gz
mediawikicore-b96b707efa42ebcbc78e50fedcc29ccaf8dd1467.zip
OOP calling convention for database functions. DBMS abstraction implemented by means of functions instead of global variables, PostgreSQL object converted to a subclass instead of a drop-in replacement. Also the beginnings of a flexible table name feature.
Notes
Notes: http://mediawiki.org/wiki/Special:Code/MediaWiki/4261
-rw-r--r--includes/Article.php614
-rw-r--r--includes/Block.php75
-rw-r--r--includes/Database.php372
-rw-r--r--includes/DatabaseFunctions.php50
-rw-r--r--includes/DatabasePostgreSQL.php479
-rw-r--r--includes/DefaultSettings.php12
-rw-r--r--includes/DifferenceEngine.php51
-rw-r--r--includes/EditPage.php18
-rw-r--r--includes/GlobalFunctions.php85
-rw-r--r--includes/Image.php39
-rw-r--r--includes/ImagePage.php44
-rw-r--r--includes/LinkCache.php95
-rw-r--r--includes/LinksUpdate.php167
-rw-r--r--includes/LoadBalancer.php43
-rw-r--r--includes/LogPage.php69
-rw-r--r--includes/Math.php60
-rwxr-xr-xincludes/MessageCache.php22
-rw-r--r--includes/ObjectCache.php15
-rw-r--r--includes/OutputPage.php2
-rw-r--r--includes/PageHistory.php17
-rw-r--r--includes/Parser.php47
-rwxr-xr-xincludes/Profiling.php25
-rw-r--r--includes/QueryPage.php71
-rw-r--r--includes/RawPage.php15
-rw-r--r--includes/SearchEngine.php13
-rw-r--r--includes/SearchUpdate.php10
-rw-r--r--includes/Setup.php17
-rw-r--r--includes/SiteStatsUpdate.php7
-rw-r--r--includes/Skin.php17
-rw-r--r--includes/SkinPHPTal.php4
-rw-r--r--includes/SpecialAllpages.php6
-rw-r--r--includes/SpecialAncientpages.php4
-rw-r--r--includes/SpecialContributions.php4
-rw-r--r--includes/SpecialListadmins.php3
-rw-r--r--includes/SpecialListusers.php5
-rw-r--r--includes/SpecialMaintenance.php163
-rw-r--r--includes/SpecialNewpages.php2
-rw-r--r--includes/SpecialRandompage.php9
-rw-r--r--includes/SpecialStatistics.php25
-rw-r--r--includes/SpecialWatchlist.php13
-rw-r--r--includes/Title.php241
-rw-r--r--includes/ViewCountUpdate.php7
-rw-r--r--includes/WatchedItem.php23
-rw-r--r--index.php5
-rw-r--r--install-utils.inc3
-rw-r--r--texvc.phtml254
46 files changed, 1828 insertions, 1494 deletions
diff --git a/includes/Article.php b/includes/Article.php
index 1af07e38722c..4a905e6bcffb 100644
--- a/includes/Article.php
+++ b/includes/Article.php
@@ -9,6 +9,9 @@
require_once( 'CacheManager.php' );
+$wgArticleCurContentFields = false;
+$wgArticleOldContentFields = false;
+
class Article {
/* private */ var $mContent, $mContentLoaded;
/* private */ var $mUser, $mTimestamp, $mUserText;
@@ -140,7 +143,7 @@ class Article {
$index = $matches[4];
if ( $machineID == 0 ) {
# Current connection
- $db =& wfGetDB();
+ $db =& wfGetDB( DB_READ );
} else {
# Alternate connection
$db =& $wgLoadBalancer->getConnection( $machineID );
@@ -153,7 +156,7 @@ class Article {
}
}
if ( $db->isOpen() ) {
- $index = wfStrencode( $index );
+ $index = $db->strencode( $index );
$res = $db->query( "SELECT blob_data FROM $dbName.$tblName WHERE blob_index='$index'", $fname );
$row = $db->fetchObject( $res );
$text = $row->text_data;
@@ -309,12 +312,30 @@ class Article {
}
+ function &getCurContentFields() {
+ global $wgArticleCurContentFields;
+ if ( !$wgArticleCurContentFields ) {
+ $wgArticleCurContentFields = array( 'cur_text','cur_timestamp','cur_user', 'cur_user_text',
+ 'cur_comment','cur_counter','cur_restrictions','cur_touched' );
+ }
+ return $wgArticleCurContentFields;
+ }
+
+ function &getOldContentFields() {
+ global $wgArticleOldContentFields;
+ if ( !$wgArticleOldContentFields ) {
+ $wgArticleOldContentFields = array( 'old_namespace','old_title','old_text','old_timestamp',
+ 'old_user','old_user_text','old_comment','old_flags' );
+ }
+ return $wgArticleOldContentFields;
+ }
# Load the revision (including cur_text) into this object
function loadContent( $noredir = false )
{
- global $wgOut, $wgMwRedir, $wgRequest, $wgIsPg, $wgLoadBalancer;
+ global $wgOut, $wgMwRedir, $wgRequest;
+ $dbr =& wfGetDB( DB_READ );
# Query variables :P
$oldid = $wgRequest->getVal( 'oldid' );
$redirect = $wgRequest->getVal( 'redirect' );
@@ -340,16 +361,11 @@ class Article {
$id = $this->getID();
if ( 0 == $id ) return;
- $sql = 'SELECT ' .
- 'cur_text,cur_timestamp,cur_user,cur_user_text,cur_comment,cur_counter,cur_restrictions,cur_touched ' .
- "FROM cur WHERE cur_id={$id}";
- wfDebug( "$sql\n" );
- $res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) {
+ $s = $dbr->getArray( 'cur', $this->getCurContentFields(), array( 'cur_id' => $id ), $fname );
+ if ( $s === false ) {
return;
}
- $s = wfFetchObject( $res );
# If we got a redirect, follow it (unless we've been told
# not to by either the function parameter or the query
if ( ( 'no' != $redirect ) && ( false == $noredir ) &&
@@ -372,14 +388,12 @@ class Article {
}
$rid = $rt->getArticleID();
if ( 0 != $rid ) {
- $sql = 'SELECT cur_text,cur_timestamp,cur_user,cur_user_text,cur_comment,' .
- "cur_counter,cur_restrictions,cur_touched FROM cur WHERE cur_id={$rid}";
- $res = wfQuery( $sql, DB_READ, $fname );
+ $redirRow = $dbr->getArray( 'cur', $this->getContentFields(), array( 'cur_id' => $rid ), $fname );
- if ( 0 != wfNumRows( $res ) ) {
+ if ( $redirRow !== false ) {
$this->mRedirectedFrom = $this->mTitle->getPrefixedText();
$this->mTitle = $rt;
- $s = wfFetchObject( $res );
+ $s = $redirRow;
}
}
}
@@ -395,20 +409,12 @@ class Article {
$this->mTouched = $s->cur_touched;
$this->mTitle->mRestrictions = explode( ',', trim( $s->cur_restrictions ) );
$this->mTitle->mRestrictionsLoaded = true;
- wfFreeResult( $res );
} else { # oldid set, retrieve historical version
- $wgLoadBalancer->force(-1);
- $oldtable=$wgIsPg?'"old"':'old';
- $sql = "SELECT old_namespace,old_title,old_text,old_timestamp,".
- "old_user,old_user_text,old_comment,old_flags FROM old ".
- "WHERE old_id={$oldid}";
- $res = wfQuery( $sql, DB_READ, $fname );
- $wgLoadBalancer->force(0);
- if ( 0 == wfNumRows( $res ) ) {
+ $s = $dbr->getArray( 'old', $this->getOldContentFields(), array( 'old_id' => $oldid ), $fname );
+ if ( $s === false ) {
return;
}
- $s = wfFetchObject( $res );
if( $this->mTitle->getNamespace() != $s->old_namespace ||
$this->mTitle->getDBkey() != $s->old_title ) {
$oldTitle = Title::makeTitle( $s->old_namesapce, $s->old_title );
@@ -421,7 +427,6 @@ class Article {
$this->mComment = $s->old_comment;
$this->mCounter = 0;
$this->mTimestamp = $s->old_timestamp;
- wfFreeResult( $res );
}
$this->mContentLoaded = true;
return $this->mContent;
@@ -430,14 +435,15 @@ class Article {
# Gets the article text without using so many damn globals
# Returns false on error
function getContentWithoutUsingSoManyDamnGlobals( $oldid = 0, $noredir = false ) {
- global $wgMwRedir, $wgIsPg;
+ global $wgMwRedir;
if ( $this->mContentLoaded ) {
return $this->mContent;
}
$this->mContent = false;
- $fname = 'Article::loadContent';
+ $fname = 'Article::getContentWithout';
+ $dbr =& wfGetDB( DB_READ );
if ( ! $oldid ) { # Retrieve current version
$id = $this->getID();
@@ -445,15 +451,11 @@ class Article {
return false;
}
- $sql = 'SELECT ' .
- 'cur_text,cur_timestamp,cur_user,cur_counter,cur_restrictions,cur_touched ' .
- "FROM cur WHERE cur_id={$id}";
- $res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) {
+ $s = $dbr->getArray( 'cur', $this->getCurContentFields(), array( 'cur_id' => $id ), $fname );
+ if ( $s === false ) {
return false;
}
- $s = wfFetchObject( $res );
# If we got a redirect, follow it (unless we've been told
# not to by either the function parameter or the query
if ( !$noredir && $wgMwRedir->matchStart( $s->cur_text ) ) {
@@ -463,14 +465,12 @@ class Article {
if( $rt && $rt->getInterwiki() == '' && $rt->getNamespace() != Namespace::getSpecial() ) {
$rid = $rt->getArticleID();
if ( 0 != $rid ) {
- $sql = 'SELECT cur_text,cur_timestamp,cur_user,' .
- "cur_counter,cur_restrictions,cur_touched FROM cur WHERE cur_id={$rid}";
- $res = wfQuery( $sql, DB_READ, $fname );
+ $redirRow = $dbr->getArray( 'cur', $this->getCurContentFields(), array( 'cur_id' => $rid ), $fname );
- if ( 0 != wfNumRows( $res ) ) {
+ if ( $redirRow !== false ) {
$this->mRedirectedFrom = $this->mTitle->getPrefixedText();
$this->mTitle = $rt;
- $s = wfFetchObject( $res );
+ $s = $redirRow;
}
}
}
@@ -479,27 +479,24 @@ class Article {
$this->mContent = $s->cur_text;
$this->mUser = $s->cur_user;
+ $this->mUserText = $s->cur_user_text;
+ $this->mComment = $s->cur_comment;
$this->mCounter = $s->cur_counter;
$this->mTimestamp = $s->cur_timestamp;
$this->mTouched = $s->cur_touched;
$this->mTitle->mRestrictions = explode( ",", trim( $s->cur_restrictions ) );
$this->mTitle->mRestrictionsLoaded = true;
- wfFreeResult( $res );
} else { # oldid set, retrieve historical version
- $oldtable=$wgIsPg?'"old"':'old';
- $sql = "SELECT old_text,old_timestamp,old_user,old_flags FROM $oldtable " .
- "WHERE old_id={$oldid}";
- $res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) {
+ $s = $dbr->getArray( 'old', $this->getOldContentFields(), array( 'old_id' => $oldid ) );
+ if ( $s === false ) {
return false;
}
-
- $s = wfFetchObject( $res );
$this->mContent = Article::getRevisionText( $s );
$this->mUser = $s->old_user;
+ $this->mUserText = $s->old_user_text;
+ $this->mComment = $s->old_comment;
$this->mCounter = 0;
$this->mTimestamp = $s->old_timestamp;
- wfFreeResult( $res );
}
$this->mContentLoaded = true;
return $this->mContent;
@@ -517,7 +514,8 @@ class Article {
{
if ( -1 == $this->mCounter ) {
$id = $this->getID();
- $this->mCounter = wfGetSQL( 'cur', 'cur_counter', "cur_id={$id}" );
+ $dbr =& wfGetDB( DB_READ );
+ $this->mCounter = $dbr->getField( 'cur', 'cur_counter', "cur_id={$id}" );
}
return $this->mCounter;
}
@@ -543,14 +541,15 @@ class Article {
{
global $wgOut;
if ( -1 != $this->mUser ) return;
+
+ $fname = 'Article::loadLastEdit';
- $sql = 'SELECT cur_user,cur_user_text,cur_timestamp,' .
- 'cur_comment,cur_minor_edit FROM cur WHERE ' .
- 'cur_id=' . $this->getID();
- $res = wfQuery( $sql, DB_READ, 'Article::loadLastEdit' );
+ $dbr =& wfGetDB( DB_READ );
+ $s = $dbr->getArray( 'cur',
+ array( 'cur_user','cur_user_text','cur_timestamp', 'cur_comment','cur_minor_edit' ),
+ array( 'cur_id' => $this->getID() ), $fname );
- if ( wfNumRows( $res ) > 0 ) {
- $s = wfFetchObject( $res );
+ if ( $s !== false ) {
$this->mUser = $s->cur_user;
$this->mUserText = $s->cur_user_text;
$this->mTimestamp = $s->cur_timestamp;
@@ -596,29 +595,33 @@ class Article {
# XXX: this is expensive; cache this info somewhere.
$title = $this->mTitle;
-
$contribs = array();
-
- $sql = 'SELECT old_user, old_user_text, ' .
- ' user_real_name, MAX(old_timestamp) as timestamp' .
- ' FROM old LEFT JOIN user ON old.old_user = user.user_id ' .
- ' WHERE old.old_namespace = ' . $title->getNamespace() .
- ' AND old.old_title = "' . $title->getDBkey() . '"' .
- ' AND old.old_user != ' . $this->getUser() .
- ' GROUP BY old.old_user ' .
- ' ORDER BY timestamp DESC ';
+ $dbr = wfGetDB( DB_READ );
+ $oldTable = $dbr->tableName( 'old' );
+ $userTable = $dbr->tableName( 'user' );
+ $encDBkey = $dbr->strencode( $title->getDBkey() );
+ $ns = $title->getNamespace();
+ $user = $this->getUser();
+
+ $sql = "SELECT old_user, old_user_text, user_real_name, MAX(old_timestamp) as timestamp
+ FROM $oldTable LEFT JOIN $userTable ON old_user = user_id
+ WHERE old_namespace = $user
+ AND old_title = $encDBkey
+ AND old_user != $user
+ GROUP BY old_user
+ ORDER BY timestamp DESC";
if ($limit > 0) {
$sql .= ' LIMIT '.$limit;
}
- $res = wfQuery($sql, DB_READ, $fname);
+ $res = $dbr->query($sql, $fname);
- while ( $line = wfFetchObject( $res ) ) {
+ while ( $line = $dbr->fetchObject( $res ) ) {
$contribs[] = array($line->old_user, $line->old_user_text, $line->user_real_name);
}
- wfFreeResult($res);
+ $dbr->freeResult($res);
return $contribs;
}
@@ -738,7 +741,7 @@ class Article {
/* private */ function insertNewArticle( $text, $summary, $isminor, $watchthis )
{
global $wgOut, $wgUser, $wgLinkCache, $wgMwRedir;
- global $wgUseSquid, $wgDeferredUpdateList, $wgInternalServer, $wgIsPg, $wgIsMySQL;
+ global $wgUseSquid, $wgDeferredUpdateList, $wgInternalServer;
$fname = 'Article::insertNewArticle';
@@ -754,30 +757,32 @@ class Article {
$won = wfInvertTimestamp( $now );
wfSeedRandom();
$rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
+ $dbw =& wfGetDB( DB_WRITE );
- if ($wgIsPg) {
- $cur_id_column="cur_id,";
- $cur_id=wfGetSQL(""," nextval('cur_cur_id_seq')");
- $cur_id_value="{$cur_id},";
- } else {
- $cur_id_column="";
- $cur_id="";
- $cur_id_value="";
- }
+ $cur_id = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
$isminor = ( $isminor && $wgUser->getID() ) ? 1 : 0;
- $sql = "INSERT INTO cur ({$cur_id_column}cur_namespace,cur_title,cur_text," .
- 'cur_comment,cur_user,cur_timestamp,cur_minor_edit,cur_counter,' .
- 'cur_restrictions,cur_user_text,cur_is_redirect,' .
- "cur_is_new,cur_random,cur_touched,inverse_timestamp) VALUES ({$cur_id_value}{$ns},'" . wfStrencode( $ttl ) . "', '" .
- wfStrencode( $text ) . "', '" .
- wfStrencode( $summary ) . "', '" .
- $wgUser->getID() . "', '{$now}', " .
- $isminor . ", 0, '', '" .
- wfStrencode( $wgUser->getName() ) . "', $redir, 1, $rand, '{$now}', '{$won}')";
- $res = wfQuery( $sql, DB_WRITE, $fname );
-
- $newid = $wgIsPg?$cur_id:wfInsertId();
+
+ $dbw->insertArray( 'cur', array(
+ 'cur_id' => $cur_id,
+ 'cur_namespace' => $ns,
+ 'cur_title' => $ttl,
+ 'cur_text' => $text,
+ 'cur_comment' => $summary,
+ 'cur_user' => $wgUser->getID(),
+ 'cur_timestamp' => $now,
+ 'cur_minor_edit' => $isminor,
+ 'cur_counter' => 0,
+ 'cur_restrictions' => '',
+ 'cur_user_text' => $wgUser->getName(),
+ 'cur_is_redirect' => $redir,
+ 'cur_is_new' => 1,
+ 'cur_random' => $rand,
+ 'cur_touched' => $now,
+ 'inverse_timestamp' => $won,
+ ), $fname );
+
+ $newid = $dbw->insertId();
$this->mTitle->resetArticleID( $newid );
Article::onArticleCreate( $this->mTitle );
@@ -793,8 +798,7 @@ class Article {
# The talk page isn't in the regular link tables, so we need to update manually:
$talkns = $ns ^ 1; # talk -> normal; normal -> talk
- $sql = "UPDATE cur set cur_touched='$now' WHERE cur_namespace=$talkns AND cur_title='" . wfStrencode( $ttl ) . "'";
- wfQuery( $sql, DB_WRITE );
+ $dbw->updateArray( 'cur', array( 'cur_touched' => $now ), array( 'cur_namespace' => $talkns, 'cur_title' => $ttl ), $fname );
# standard deferred updates
$this->editUpdates( $text );
@@ -884,9 +888,10 @@ class Article {
global $wgOut, $wgUser, $wgLinkCache;
global $wgDBtransactions, $wgMwRedir;
global $wgUseSquid, $wgInternalServer;
- global $wgIsPg;
+
$fname = 'Article::updateArticle';
-
+ $good = true;
+
if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; }
if ( $minor && $wgUser->getID() ) { $me2 = 1; } else { $me2 = 0; }
if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ')[^\\n]+)/i', $text, $m ) ) {
@@ -896,78 +901,87 @@ class Article {
else { $redir = 0; }
$text = $this->preSaveTransform( $text );
+ $dbw =& wfGetDB( DB_WRITE );
# Update article, but only if changed.
+ # It's important that we either rollback or complete, otherwise an attacker could
+ # overwrite cur entries by sending precisely timed user aborts. Random bored users
+ # could conceivably have the same effect, especially if cur is locked for long periods.
if( $wgDBtransactions ) {
- $sql = 'BEGIN';
- wfQuery( $sql, DB_WRITE );
+ $dbw->query( 'BEGIN', $fname );
+ } else {
+ $userAbort = ignore_user_abort( true );
}
+
$oldtext = $this->getContent( true );
if ( 0 != strcmp( $text, $oldtext ) ) {
$this->mCountAdjustment = $this->isCountable( $text )
- $this->isCountable( $oldtext );
-
$now = wfTimestampNow();
$won = wfInvertTimestamp( $now );
- $sql = "UPDATE cur SET cur_text='" . wfStrencode( $text ) .
- "',cur_comment='" . wfStrencode( $summary ) .
- "',cur_minor_edit={$me2}, cur_user=" . $wgUser->getID() .
- ",cur_timestamp='{$now}',cur_user_text='" .
- wfStrencode( $wgUser->getName() ) .
- "',cur_is_redirect={$redir}, cur_is_new=0, cur_touched='{$now}', inverse_timestamp='{$won}' " .
- "WHERE cur_id=" . $this->getID() .
- " AND cur_timestamp='" . $this->getTimestamp() . "'";
- $res = wfQuery( $sql, DB_WRITE, $fname );
-
- if( wfAffectedRows() == 0 ) {
- /* Belated edit conflict! Run away!! */
- return false;
- }
- # This overwrites $oldtext if revision compression is on
- $flags = Article::compressRevisionText( $oldtext );
-
- $oldtable=$wgIsPg?'"old"':'old';
- if ($wgIsPg) {
- $oldtable='"old"';
- $old_id_column='old_id,';
- $old_id=wfGetSQL(""," nextval('old_old_id_seq')");
- $old_id_value=$old_id.',';
+ # First update the cur row
+ $dbw->updateArray( 'cur',
+ array( /* SET */
+ 'cur_text' => $text,
+ 'cur_comment' => $summary,
+ 'cur_minor_edit' => $me2,
+ 'cur_user' => $wgUser->getID(),
+ 'cur_timestamp' => $now,
+ 'cur_user_text' => $wgUser->getName(),
+ 'cur_is_redirect' => $redir,
+ 'cur_is_new' => 0,
+ 'cur_touched' => $now,
+ 'inverse_timestamp' => $won
+ ), array( /* WHERE */
+ 'cur_id' => $this->getID(),
+ 'cur_timestamp' => $this->getTimestamp()
+ ), $fname
+ );
+
+ if( $dbw->affectedRows() == 0 ) {
+ /* Belated edit conflict! Run away!! */
+ $good = false;
} else {
- $oldtable='old';
- $old_id_column='';
- $old_id_value='';
+ # Now insert the previous revision into old
+
+ # This overwrites $oldtext if revision compression is on
+ $flags = Article::compressRevisionText( $oldtext );
+
+ $dbw->insertArray( 'old',
+ array(
+ 'old_id' => $dbw->nextSequenceValue( 'old_old_id_seq' ),
+ 'old_namespace' => $this->mTitle->getNamespace(),
+ 'old_title' => $this->mTitle->getDBkey(),
+ 'old_text' => $oldtext,
+ 'old_comment' => $this->getComment(),
+ 'old_user' => $this->getUser(),
+ 'old_user_text' => $this->getUserText(),
+ 'old_timestamp' => $this->getTimestamp(),
+ 'old_minor_edit' => $me1,
+ 'inverse_timestamp' => wfInvertTimestamp( $this->getTimestamp() ),
+ 'old_flags' => $flags,
+ ), $fname
+ );
+
+ $oldid = $dbw->insertId();
+
+ $bot = (int)($wgUser->isBot() || $forceBot);
+ RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary,
+ $oldid, $this->getTimestamp(), $bot );
+ Article::onArticleEdit( $this->mTitle );
}
-
- $sql = "INSERT INTO $oldtable ({$old_id_column}old_namespace,old_title,old_text," .
- 'old_comment,old_user,old_user_text,old_timestamp,' .
- 'old_minor_edit,inverse_timestamp,old_flags) VALUES (' .
- $old_id_value.
- $this->mTitle->getNamespace() . ", '" .
- wfStrencode( $this->mTitle->getDBkey() ) . "', '" .
- wfStrencode( $oldtext ) . "', '" .
- wfStrencode( $this->getComment() ) . "', " .
- $this->getUser() . ", '" .
- wfStrencode( $this->getUserText() ) . "', '" .
- $this->getTimestamp() . "', " . $me1 . ", '" .
- wfInvertTimestamp( $this->getTimestamp() ) . "','$flags')";
- $res = wfQuery( $sql, DB_WRITE, $fname );
-
- $oldid = $wgIsPg?$old_id:wfInsertId( $res );
-
- $bot = (int)($wgUser->isBot() || $forceBot);
- RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary,
- $oldid, $this->getTimestamp(), $bot );
- Article::onArticleEdit( $this->mTitle );
}
if( $wgDBtransactions ) {
- $sql = 'COMMIT';
- wfQuery( $sql, DB_WRITE );
+ $dbw->query( 'COMMIT', $fname );
+ } else {
+ ignore_user_abort( $userAbort );
}
+ if ( $good ) {
if ($watchthis) {
if (!$this->mTitle->userIsWatching()) $this->watch();
} else {
@@ -986,9 +1000,9 @@ class Article {
$titles = $this->mTitle->getLinksTo();
Title::touchArray( $titles );
if ( $wgUseSquid ) {
- foreach ( $titles as $title ) {
- $urls[] = $title->getInternalURL();
- }
+ foreach ( $titles as $title ) {
+ $urls[] = $title->getInternalURL();
+ }
}
}
@@ -1000,7 +1014,8 @@ class Article {
}
$this->showArticle( $text, wfMsg( 'updated' ), $sectionanchor );
- return true;
+ }
+ return $good;
}
# After we've either updated or inserted the article, update
@@ -1093,10 +1108,15 @@ class Article {
$reason = $wgRequest->getText( 'wpReasonProtect' );
if ( $confirm ) {
-
- $sql = "UPDATE cur SET cur_touched='" . wfTimestampNow() . "'," .
- "cur_restrictions='{$limit}' WHERE cur_id={$id}";
- wfQuery( $sql, DB_WRITE, 'Article::protect' );
+ $dbw =& wfGetDB( DB_WRITE );
+ $dbw->updateArray( 'cur',
+ array( /* SET */
+ 'cur_touched' => wfTimestampNow(),
+ 'cur_restrictions' => (string)$limit
+ ), array( /* WHERE */
+ 'cur_id' => $id
+ ), 'Article::protect'
+ );
$log = new LogPage( wfMsg( 'protectlogpage' ), wfMsg( 'protectlogtext' ) );
if ( $limit === "" ) {
@@ -1185,7 +1205,7 @@ class Article {
# UI entry point for page deletion
function delete()
{
- global $wgUser, $wgOut, $wgMessageCache, $wgRequest, $wgIsPg;
+ global $wgUser, $wgOut, $wgMessageCache, $wgRequest;
$fname = 'Article::delete';
$confirm = $wgRequest->getBool( 'wpConfirm' ) && $wgRequest->wasPosted();
$reason = $wgRequest->getText( 'wpReason' );
@@ -1218,22 +1238,33 @@ 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 );
$ns = $this->mTitle->getNamespace();
$title = $this->mTitle->getDBkey();
- $etitle = wfStrencode( $title );
- $oldtable=$wgIsPg?'"old"':'old';
- $sql = "SELECT old_text,old_flags FROM $oldtable WHERE old_namespace=$ns and old_title='$etitle' ORDER BY inverse_timestamp LIMIT 1";
- $res = wfQuery( $sql, DB_READ, $fname );
- if( ($old=wfFetchObject($res)) && !$confirm ) {
+ $old = $dbr->getArray( 'old',
+ array( 'old_text', 'old_flags' ),
+ array(
+ 'old_namespace' => $ns,
+ 'old_title' => $title,
+ ), $fname, array( 'ORDER BY' => 'inverse_timestamp' )
+ );
+
+ if( $old !== false && !$confirm ) {
$skin=$wgUser->getSkin();
$wgOut->addHTML('<b>'.wfMsg('historywarning'));
$wgOut->addHTML( $skin->historyLink() .'</b>');
}
-
- $sql="SELECT cur_text FROM cur WHERE cur_namespace=$ns and cur_title='$etitle'";
- $res=wfQuery($sql, DB_READ, $fname);
- if( ($s=wfFetchObject($res))) {
-
+
+ # Fetch cur_text
+ $s = $dbr->getArray( 'cur',
+ array( 'cur_text' ),
+ array(
+ 'cur_namespace' => $ns,
+ 'cur_title' => $title,
+ ), $fname
+ );
+
+ if( $s !== false ) {
# if this is a mini-text, we can paste part of it into the deletion reason
#if this is empty, an earlier revision may contain "useful" text
@@ -1368,9 +1399,10 @@ class Article {
$fname = 'Article::doDeleteArticle';
wfDebug( $fname."\n" );
-
+
+ $dbw =& wfGetDB( DB_WRITE );
$ns = $this->mTitle->getNamespace();
- $t = wfStrencode( $this->mTitle->getDBkey() );
+ $t = $this->mTitle->getDBkey();
$id = $this->mTitle->getArticleID();
if ( '' == $t || $id == 0 ) {
@@ -1401,68 +1433,75 @@ class Article {
Title::touchArray( $linksTo );
# Move article and history to the "archive" table
- $sql = 'INSERT INTO archive (ar_namespace,ar_title,ar_text,' .
- 'ar_comment,ar_user,ar_user_text,ar_timestamp,ar_minor_edit,' .
- 'ar_flags) SELECT cur_namespace,cur_title,cur_text,cur_comment,' .
- 'cur_user,cur_user_text,cur_timestamp,cur_minor_edit,0 FROM cur ' .
- "WHERE cur_namespace={$ns} AND cur_title='{$t}'";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = 'INSERT INTO archive (ar_namespace,ar_title,ar_text,' .
- 'ar_comment,ar_user,ar_user_text,ar_timestamp,ar_minor_edit,' .
- 'ar_flags) SELECT old_namespace,old_title,old_text,old_comment,' .
- 'old_user,old_user_text,old_timestamp,old_minor_edit,old_flags ' .
- "FROM old WHERE old_namespace={$ns} AND old_title='{$t}'";
- wfQuery( $sql, DB_WRITE, $fname );
-
+ $archiveTable = $dbw->tableName( 'archive' );
+ $oldTable = $dbw->tableName( 'old' );
+ $curTable = $dbw->tableName( 'cur' );
+ $recentchangesTable = $dbw->tableName( 'recentchanges' );
+ $linksTable = $dbw->tableName( 'links' );
+ $brokenlinksTable = $dbw->tableName( 'brokenlinks' );
+
+ $dbw->insertSelect( 'archive', 'cur',
+ array(
+ 'ar_namespace' => 'cur_namespace',
+ 'ar_title' => 'cur_title',
+ 'ar_text' => 'cur_text',
+ 'ar_comment' => 'cur_comment',
+ 'ar_user' => 'cur_user',
+ 'ar_user_text' => 'cur_user_text',
+ 'ar_timestamp' => 'cur_timestamp',
+ 'ar_minor_edit' => 'cur_minor_edit',
+ 'ar_flags' => 0,
+ ), array(
+ 'cur_namespace' => $ns,
+ 'cur_title' => $t,
+ ), $fname
+ );
+
+ $dbw->insertSelect( 'archive', 'old',
+ array(
+ 'ar_namespace' => 'old_namespace',
+ 'ar_title' => 'old_title',
+ 'ar_text' => 'old_text',
+ 'ar_comment' => 'old_comment',
+ 'ar_user' => 'old_user',
+ 'ar_user_text' => 'old_user_text',
+ 'ar_timestamp' => 'old_timestamp',
+ 'ar_minor_edit' => 'old_minor_edit',
+ 'ar_flags' => 'old_flags'
+ ), array(
+ 'old_namespace' => $ns,
+ 'old_title' => $t,
+ ), $fname
+ );
+
# Now that it's safely backed up, delete it
- $sql = "DELETE FROM cur WHERE cur_namespace={$ns} AND " .
- "cur_title='{$t}'";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = "DELETE FROM old WHERE old_namespace={$ns} AND " .
- "old_title='{$t}'";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = "DELETE FROM recentchanges WHERE rc_namespace={$ns} AND " .
- "rc_title='{$t}'";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->delete( 'cur', array( 'cur_namespace' => $ns, 'cur_title' => $t ), $fname );
+ $dbw->delete( 'old', array( 'old_namespace' => $ns, 'old_title' => $t ), $fname );
+ $dbw->delete( 'recentchanges', array( 'rc_namespace' => $ns, 'rc_title' => $t ), $fname );
# Finally, clean up the link tables
- $t = wfStrencode( $this->mTitle->getPrefixedDBkey() );
+ $t = $this->mTitle->getPrefixedDBkey();
Article::onArticleDelete( $this->mTitle );
- $sql = 'INSERT INTO brokenlinks (bl_from,bl_to) VALUES ';
- $first = true;
-
+ # Insert broken links
+ $brokenLinks = array();
foreach ( $linksTo as $titleObj ) {
- if ( ! $first ) { $sql .= ','; }
- $first = false;
# Get article ID. Efficient because it was loaded into the cache by getLinksTo().
$linkID = $titleObj->getArticleID();
- $sql .= "({$linkID},'{$t}')";
- }
- if ( ! $first ) {
- wfQuery( $sql, DB_WRITE, $fname );
- }
-
- $sql = "DELETE FROM links WHERE l_to={$id}";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = "DELETE FROM links WHERE l_from={$id}";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = "DELETE FROM imagelinks WHERE il_from={$id}";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = "DELETE FROM brokenlinks WHERE bl_from={$id}";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = "DELETE FROM categorylinks WHERE cl_from={$id}";
- wfQuery( $sql, DB_WRITE, $fname );
-
+ $brokenLinks[] = array( 'bl_from' => $linkID, 'bl_to' => $t );
+ }
+ $dbw->insertArray( 'brokenlinks', $brokenLinks, $fname );
+
+ # Delete live links
+ $dbw->delete( 'links', array( 'l_to' => $id ) );
+ $dbw->delete( 'links', array( 'l_from' => $id ) );
+ $dbw->delete( 'imagelinks', array( 'il_from' => $id ) );
+ $dbw->delete( 'brokenlinks', array( 'bl_from' => $id ) );
+ $dbw->delete( 'categorylinks', array( 'cl_from' => $id ) );
+
+ # Log the deletion
$log = new LogPage( wfMsg( 'dellogpage' ), wfMsg( 'dellogpagetext' ) );
$art = $this->mTitle->getPrefixedText();
$log->addEntry( wfMsg( 'deletedarticle', $art ), $reason );
@@ -1475,8 +1514,9 @@ class Article {
function rollback()
{
- global $wgUser, $wgLang, $wgOut, $wgRequest, $wgIsMySQL, $wgIsPg;
-
+ global $wgUser, $wgLang, $wgOut, $wgRequest;
+ $fname = "Article::rollback";
+
if ( ! $wgUser->isSysop() ) {
$wgOut->sysopRequired();
return;
@@ -1485,25 +1525,27 @@ class Article {
$wgOut->readOnlyPage( $this->getContent( true ) );
return;
}
+ $dbw =& wfGetDB( DB_WRITE );
# Enhanced rollback, marks edits rc_bot=1
$bot = $wgRequest->getBool( 'bot' );
# Replace all this user's current edits with the next one down
- $tt = wfStrencode( $this->mTitle->getDBKey() );
+ $tt = $this->mTitle->getDBKey();
$n = $this->mTitle->getNamespace();
- # Get the last editor
- $sql = 'SELECT cur_id,cur_user,cur_user_text,cur_comment ' .
- "FROM cur WHERE cur_title='{$tt}' AND cur_namespace={$n}";
- $res = wfQuery( $sql, DB_READ );
- if( ($x = wfNumRows( $res )) != 1 ) {
+ # Get the last editor, lock table exclusively
+ $s = $dbw->getArray( 'cur',
+ array( 'cur_id','cur_user','cur_user_text','cur_comment' ),
+ array( 'cur_title' => $tt, 'cur_namespace' => $n ),
+ $fname, 'FOR UPDATE'
+ );
+ if( $s === false ) {
# Something wrong
$wgOut->addHTML( wfMsg( 'notanarticle' ) );
return;
}
- $s = wfFetchObject( $res );
- $ut = wfStrencode( $s->cur_user_text );
+ $ut = $dbw->strencode( $s->cur_user_text );
$uid = $s->cur_user;
$pid = $s->cur_id;
@@ -1523,28 +1565,31 @@ class Article {
}
# Get the last edit not by this guy
-
- $use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":"";
- $oldtable=$wgIsPg?'"old"':'old';
- $sql = 'SELECT old_text,old_user,old_user_text,old_timestamp,old_flags ' .
- "FROM $oldtable {$use_index} " .
- "WHERE old_namespace={$n} AND old_title='{$tt}' " .
- "AND (old_user <> {$uid} OR old_user_text <> '{$ut}') " .
- 'ORDER BY inverse_timestamp LIMIT 1';
- $res = wfQuery( $sql, DB_READ );
- if( wfNumRows( $res ) != 1 ) {
+ $s = $dbw->getArray( 'old',
+ array( 'old_text','old_user','old_user_text','old_timestamp','old_flags' ),
+ array(
+ 'old_namespace' => $n,
+ 'old_title' => $tt,
+ "old_user <> {$uid} OR old_user_text <> '{$ut}'"
+ ), $fname, array( 'FOR UPDATE', 'USE INDEX' => 'name_title_timestamp' )
+ );
+ if( $s === false ) {
# Something wrong
$wgOut->setPageTitle(wfMsg('rollbackfailed'));
$wgOut->addHTML( wfMsg( 'cantrollback' ) );
return;
}
- $s = wfFetchObject( $res );
if ( $bot ) {
# Mark all reverted edits as bot
- $sql = 'UPDATE recentchanges SET rc_bot=1 WHERE ' .
- "rc_cur_id=$pid AND rc_user=$uid AND rc_timestamp > '{$s->old_timestamp}'";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->updateArray( 'recentchanges',
+ array( /* SET */
+ 'rc_bot' => 1
+ ), array( /* WHERE */
+ 'rc_user' => $uid,
+ "rc_timestamp > '{$s->old_timestamp}'",
+ ), $fname
+ );
}
# Save it!
@@ -1583,12 +1628,13 @@ class Article {
{
global $wgDeferredUpdateList, $wgDBname, $wgMemc;
global $wgMessageCache;
-
+
wfSeedRandom();
if ( 0 == mt_rand( 0, 999 ) ) {
+ $dbw =& wfGetDB( DB_WRITE );
$cutoff = wfUnix2Timestamp( time() - ( 7 * 86400 ) );
$sql = "DELETE FROM recentchanges WHERE rc_timestamp < '{$cutoff}'";
- wfQuery( $sql, DB_WRITE );
+ $dbw->query( $sql );
}
$id = $this->getID();
$title = $this->mTitle->getPrefixedDBkey();
@@ -1686,9 +1732,10 @@ class Article {
# Loads cur_touched and returns a value indicating if it should be used
function checkTouched() {
$id = $this->getID();
- $sql = 'SELECT cur_touched,cur_is_redirect FROM cur WHERE cur_id='.$id;
- $res = wfQuery( $sql, DB_READ, 'Article::checkTouched' );
- if( $s = wfFetchObject( $res ) ) {
+ $dbr =& wfGetDB( DB_READ );
+ $s = $dbr->getArray( 'cur', array( 'cur_touched', 'cur_is_redirect' ),
+ array( 'cur_id' => $id ), $fname );
+ if( $s !== false ) {
$this->mTouched = $s->cur_touched;
return !$s->cur_is_redirect;
} else {
@@ -1698,24 +1745,35 @@ class Article {
# Edit an article without doing all that other stuff
function quickEdit( $text, $comment = '', $minor = 0 ) {
- global $wgUser, $wgMwRedir, $wgIsPg;
+ global $wgUser, $wgMwRedir;
$fname = 'Article::quickEdit';
wfProfileIn( $fname );
+ $dbw =& wfGetDB( DB_WRITE );
$ns = $this->mTitle->getNamespace();
$dbkey = $this->mTitle->getDBkey();
- $encDbKey = wfStrencode( $dbkey );
+ $encDbKey = $dbw->strencode( $dbkey );
$timestamp = wfTimestampNow();
# Save to history
- $oldtable=$wgIsPg?'"old"':'old';
- $sql = "INSERT INTO $oldtable (old_namespace,old_title,old_text,old_comment,old_user,old_user_text,old_timestamp,inverse_timestamp)
- SELECT cur_namespace,cur_title,cur_text,cur_comment,cur_user,cur_user_text,cur_timestamp,99999999999999-cur_timestamp
- FROM cur WHERE cur_namespace=$ns AND cur_title='$encDbKey'";
- wfQuery( $sql, DB_WRITE );
+ $dbw->insertSelect( 'old', 'cur',
+ array(
+ 'old_namespace' => 'cur_namespace',
+ 'old_title' => 'cur_title',
+ 'old_text' => 'cur_text',
+ 'old_comment' => 'cur_comment',
+ 'old_user' => 'cur_user',
+ 'old_user_text' => 'cur_user_text',
+ 'old_timestamp' => 'cur_timestamp',
+ 'inverse_timestamp' => '99999999999999-cur_timestamp',
+ ), array(
+ 'cur_namespace' => $ns,
+ 'cur_title' => $dbkey,
+ ), $fname
+ );
# Use the affected row count to determine if the article is new
- $numRows = wfAffectedRows();
+ $numRows = $dbw->affectedRows();
# Make an array of fields to be inserted
$fields = array(
@@ -1733,14 +1791,14 @@ class Article {
if ( $numRows ) {
# Update article
$fields['cur_is_new'] = 0;
- wfUpdateArray( 'cur', $fields, array( 'cur_namespace' => $ns, 'cur_title' => $dbkey ), $fname );
+ $dbw->updateArray( 'cur', $fields, array( 'cur_namespace' => $ns, 'cur_title' => $dbkey ), $fname );
} else {
# Insert new article
$fields['cur_is_new'] = 1;
$fields['cur_namespace'] = $ns;
$fields['cur_title'] = $dbkey;
$fields['cur_random'] = $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
- wfInsertArray( 'cur', $fields, $fname );
+ $dbw->insertArray( 'cur', $fields, $fname );
}
wfProfileOut( $fname );
}
@@ -1750,45 +1808,49 @@ class Article {
$id = intval( $id );
global $wgHitcounterUpdateFreq;
+ $dbw =& wfGetDB( DB_WRITE );
+ $curTable = $dbw->tableName( 'cur' );
+ $hitcounterTable = $dbw->tableName( 'hitcounter' );
+ $acchitsTable = $dbw->tableName( 'acchits' );
+
if( $wgHitcounterUpdateFreq <= 1 ){ //
- wfQuery('UPDATE cur SET cur_counter = cur_counter + 1 ' .
- 'WHERE cur_id = '.$id, DB_WRITE);
+ $dbw->query( "UPDATE $curTable SET cur_counter = cur_counter + 1 WHERE cur_id = $id" );
return;
}
# Not important enough to warrant an error page in case of failure
- $oldignore = wfIgnoreSQLErrors( true );
+ $oldignore = $dbw->setIgnoreErrors( true );
- wfQuery("INSERT INTO hitcounter (hc_id) VALUES ({$id})", DB_WRITE);
+ $dbw->query( "INSERT INTO $hitcounterTable (hc_id) VALUES ({$id})" );
$checkfreq = intval( $wgHitcounterUpdateFreq/25 + 1 );
- if( (rand() % $checkfreq != 0) or (wfLastErrno() != 0) ){
+ if( (rand() % $checkfreq != 0) or ($dbw->lastErrno() != 0) ){
# Most of the time (or on SQL errors), skip row count check
- wfIgnoreSQLErrors( $oldignore );
+ $dbw->setIgnoreErrors( $oldignore );
return;
}
- $res = wfQuery('SELECT COUNT(*) as n FROM hitcounter', DB_WRITE);
- $row = wfFetchObject( $res );
+ $res = $dbw->query("SELECT COUNT(*) as n FROM $hitcounterTable");
+ $row = $dbw->fetchObject( $res );
$rown = intval( $row->n );
if( $rown >= $wgHitcounterUpdateFreq ){
wfProfileIn( 'Article::incViewCount-collect' );
$old_user_abort = ignore_user_abort( true );
- wfQuery('LOCK TABLES hitcounter WRITE', DB_WRITE);
- wfQuery('CREATE TEMPORARY TABLE acchits TYPE=HEAP '.
- 'SELECT hc_id,COUNT(*) AS hc_n FROM hitcounter '.
- 'GROUP BY hc_id', DB_WRITE);
- wfQuery('DELETE FROM hitcounter', DB_WRITE);
- wfQuery('UNLOCK TABLES', DB_WRITE);
- wfQuery('UPDATE cur,acchits SET cur_counter=cur_counter + hc_n '.
- 'WHERE cur_id = hc_id', DB_WRITE);
- wfQuery('DROP TABLE acchits', DB_WRITE);
+ $dbw->query("LOCK TABLES $hitcounterTable WRITE");
+ $dbw->query("CREATE TEMPORARY TABLE $acchitsTable TYPE=HEAP ".
+ "SELECT hc_id,COUNT(*) AS hc_n FROM $hitcounterTable ".
+ 'GROUP BY hc_id');
+ $dbw->query("DELETE FROM $hitcounterTable");
+ $dbw->query('UNLOCK TABLES');
+ $dbw->query("UPDATE $curTable,$acchitsTable SET cur_counter=cur_counter + hc_n ".
+ 'WHERE cur_id = hc_id');
+ $dbw->query("DROP TABLE $acchitsTable");
ignore_user_abort( $old_user_abort );
wfProfileOut( 'Article::incViewCount-collect' );
}
- wfIgnoreSQLErrors( $oldignore );
+ $dbw->setIgnoreErrors( $oldignore );
}
# The onArticle*() functions are supposed to be a kind of hooks
diff --git a/includes/Block.php b/includes/Block.php
index e5df26241a23..80b102a71255 100644
--- a/includes/Block.php
+++ b/includes/Block.php
@@ -45,31 +45,31 @@ class Block
# Get a ban from the DB, with either the given address or the given username
function load( $address = "", $user = 0, $killExpired = true )
{
- global $wgLoadBalancer;
- $fname = 'Block::load';
+ $fname = 'Block::load';
+
$ret = false;
$killed = false;
-
+ $dbr =& wfGetDB( DB_READ );
+ $ipblocks = $dbr->tableName( 'ipblocks' );
+
if ( 0 == $user && $address=="" ) {
- $sql = "SELECT * from ipblocks";
+ $sql = "SELECT * from $ipblocks";
} elseif ($address=="") {
- $sql = "SELECT * FROM ipblocks WHERE ipb_user={$user}";
+ $sql = "SELECT * FROM $ipblocks WHERE ipb_user={$user}";
} elseif ($user=="") {
- $sql = "SELECT * FROM ipblocks WHERE ipb_address='" . wfStrencode( $address ) . "'";
+ $sql = "SELECT * FROM $ipblocks WHERE ipb_address='" . $dbr->strencode( $address ) . "'";
} else {
- $sql = "SELECT * FROM ipblocks WHERE (ipb_address='" . wfStrencode( $address ) .
+ $sql = "SELECT * FROM $ipblocks WHERE (ipb_address='" . $dbr->strencode( $address ) .
"' OR ipb_user={$user})";
}
- $wgLoadBalancer->force(-1);
- $res = wfQuery( $sql, DB_READ, $fname );
- $wgLoadBalancer->force(0);
- if ( 0 == wfNumRows( $res ) ) {
+ $res = $dbr->query( $sql, $fname );
+ if ( 0 == $dbr->numRows( $res ) ) {
# User is not blocked
$this->clear();
} else {
# Get first block
- $row = wfFetchObject( $res );
+ $row = $dbr->fetchObject( $res );
$this->initFromRow( $row );
if ( $killExpired ) {
@@ -77,7 +77,7 @@ class Block
do {
$killed = $this->deleteIfExpired();
if ( $killed ) {
- $row = wfFetchObject( $res );
+ $row = $dbr->fetchObject( $res );
if ( $row ) {
$this->initFromRow( $row );
}
@@ -95,7 +95,7 @@ class Block
$ret = true;
}
}
- wfFreeResult( $res );
+ $dbr->freeResult( $res );
return $ret;
}
@@ -132,8 +132,11 @@ class Block
# Callback with a Block object for every block
/*static*/ function enumBlocks( $callback, $tag, $killExpired = true )
{
- $sql = 'SELECT * FROM ipblocks ORDER BY ipb_timestamp DESC';
- $res = wfQuery( $sql, DB_READ, 'Block::enumBans' );
+ $dbr =& wfGetDB( DB_READ );
+ $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 ) ) {
@@ -152,24 +155,31 @@ class Block
function delete()
{
$fname = 'Block::delete';
+ $dbw =& wfGetDB( DB_WRITE );
+
if ( $this->mAddress == "" ) {
- $sql = "DELETE FROM ipblocks WHERE ipb_id={$this->mId}";
+ $condition = array( 'ipb_id' => $this->mId );
} else {
- $sql = "DELETE FROM ipblocks WHERE ipb_address='" .
- wfStrencode( $this->mAddress ) . "'";
+ $condition = array( 'ipb_address' => $this->mAddress );
}
- wfQuery( $sql, DB_WRITE, 'Block::delete' );
-
+ $dbw->delete( 'ipblocks', $condition, $fname );
$this->clearCache();
}
function insert()
{
- $sql = 'INSERT INTO ipblocks ' .
- '(ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry )' .
- "VALUES ('" . wfStrencode( $this->mAddress ) . "', {$this->mUser}, {$this->mBy}, '" .
- wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto}, '{$this->mExpiry}')";
- wfQuery( $sql, DB_WRITE, 'Block::insert' );
+ $dbw =& wfGetDB( DB_WRITE );
+ $dbw->insertArray( 'ipblocks',
+ array(
+ 'ipb_address' => $this->mAddress,
+ 'ipb_user' => $this->mUser,
+ 'ipb_by' => $this->mBy,
+ 'ipb_reason' => $this->mReason,
+ 'ipb_timestamp' => $this->mTimestamp,
+ 'ipb_auto' => $this->mAuto,
+ 'ipb_expiry' => $this->mExpiry,
+ ), 'Block::insert'
+ );
$this->clearCache();
}
@@ -204,10 +214,15 @@ class Block
$this->mTimestamp = wfTimestampNow();
$this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
- wfQuery( 'UPDATE ipblocks SET ' .
- "ipb_timestamp='" . $this->mTimestamp . "', " .
- "ipb_expiry='" . $this->mExpiry . "' " .
- "WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, 'Block::updateTimestamp' );
+ $dbw =& wfGetDB( DB_WRITE );
+ $dbw->updateArray( 'ipblocks',
+ array( /* SET */
+ 'ipb_timestamp' => $this->mTimestamp,
+ 'ipb_expiry' => $this->mExpiry,
+ ), array( /* WHERE */
+ 'ipb_address' => $this->mAddress
+ ), 'Block::updateTimestamp'
+ );
$this->clearCache();
}
diff --git a/includes/Database.php b/includes/Database.php
index bab6cd873570..c1ba5cc94cac 100644
--- a/includes/Database.php
+++ b/includes/Database.php
@@ -60,7 +60,8 @@ class Database {
# Other functions
#------------------------------------------------------------------------------
- function Database()
+ function Database( $server = false, $user = false, $password = false, $dbName = false,
+ $failFunction = false, $debug = false, $bufferResults = true, $ignoreErrors = false )
{
global $wgOut;
# Can't get a reference if it hasn't been set yet
@@ -68,27 +69,27 @@ class Database {
$wgOut = NULL;
}
$this->mOut =& $wgOut;
-
+
+ $this->mFailFunction = $failFunction;
+ $this->mIgnoreErrors = $ignoreErrors;
+ $this->mDebug = $debug;
+ $this->mBufferResults = $bufferResults;
+ if ( $server ) {
+ $this->open( $server, $user, $password, $dbName );
+ }
}
/* static */ function newFromParams( $server, $user, $password, $dbName,
$failFunction = false, $debug = false, $bufferResults = true, $ignoreErrors = false )
{
- $db = new Database;
- $db->mFailFunction = $failFunction;
- $db->mIgnoreErrors = $ignoreErrors;
- $db->mDebug = $debug;
- $db->mBufferResults = $bufferResults;
- $db->open( $server, $user, $password, $dbName );
- return $db;
+ return new Database( $server, $user, $password, $dbName, $failFunction, $debug,
+ $bufferResults, $ignoreErrors );
}
# Usually aborts on failure
# If the failFunction is set to a non-zero integer, returns success
function open( $server, $user, $password, $dbName )
{
- global $wgEmergencyContact;
-
# Test for missing mysql.so
# Otherwise we get a suppressed fatal error, which is very hard to track down
if ( !function_exists( 'mysql_connect' ) ) {
@@ -155,7 +156,7 @@ class Database {
# Usually aborts on failure
# If errors are explicitly ignored, returns success
- function query( $sql, $fname = "" )
+ function query( $sql, $fname = "", $tempIgnore = false )
{
global $wgProfiling, $wgCommandLineMode;
@@ -173,16 +174,26 @@ class Database {
$sqlx = wordwrap(strtr($sqlx,"\t\n"," "));
wfDebug( "SQL: $sqlx\n" );
}
+ # Add a comment for easy SHOW PROCESSLIST interpretation
+ if ( $fname ) {
+ $commentedSql = "/* $fname */ $sql";
+ } else {
+ $commentedSql = $sql;
+ }
+
if( $this->mBufferResults ) {
- $ret = mysql_query( $sql, $this->mConn );
+ $ret = mysql_query( $commentedSql, $this->mConn );
} else {
- $ret = mysql_unbuffered_query( $sql, $this->mConn );
+ $ret = mysql_unbuffered_query( $commentedSql, $this->mConn );
}
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( $this->mIgnoreErrors ) {
+ if( $ignore || $tempIgnore ) {
wfDebug("SQL ERROR (ignored): " . $error . "\n");
} else {
$sql1line = str_replace( "\n", "\\n", $sql );
@@ -199,6 +210,7 @@ class Database {
$this->mOut->databaseError( $fname, $sql, $error, $errno );
}
}
+ $this->setIgnoreErrors( $ignore );
}
if ( $wgProfiling ) {
@@ -216,7 +228,7 @@ class Database {
@$row = mysql_fetch_object( $res );
# FIXME: HACK HACK HACK HACK debug
if( mysql_errno() ) {
- wfDebugDieBacktrace( "SQL error: " . htmlspecialchars( mysql_error() ) );
+ wfDebugDieBacktrace( "Error in fetchObject(): " . htmlspecialchars( mysql_error() ) );
}
return $row;
}
@@ -224,7 +236,7 @@ class Database {
function fetchRow( $res ) {
@$row = mysql_fetch_array( $res );
if (mysql_errno() ) {
- wfDebugDieBacktrace( "SQL error: " . htmlspecialchars( mysql_error() ) );
+ wfDebugDieBacktrace( "Error in fetchRow(): " . htmlspecialchars( mysql_error() ) );
}
return $row;
}
@@ -232,7 +244,7 @@ class Database {
function numRows( $res ) {
@$n = mysql_num_rows( $res );
if( mysql_errno() ) {
- wfDebugDieBacktrace( "SQL error: " . htmlspecialchars( mysql_error() ) );
+ wfDebugDieBacktrace( "Error in numRows(): " . htmlspecialchars( mysql_error() ) );
}
return $n;
}
@@ -249,6 +261,7 @@ class Database {
# If errors are explicitly ignored, returns success
function set( $table, $var, $value, $cond, $fname = "Database::set" )
{
+ $table = $this->tableName( $table );
$sql = "UPDATE $table SET $var = '" .
wfStrencode( $value ) . "' WHERE ($cond)";
return !!$this->query( $sql, DB_WRITE, $fname );
@@ -257,41 +270,89 @@ class Database {
# 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 get( $table, $var, $cond, $fname = "Database::get" )
+ function getField( $table, $var, $cond, $fname = "Database::get" )
{
- $sql = "SELECT $var FROM $table WHERE ($cond)";
- $result = $this->query( $sql, DB_READ, $fname );
-
- $ret = "";
- if ( mysql_num_rows( $result ) > 0 ) {
- $s = mysql_fetch_object( $result );
- $ret = $s->$var;
- mysql_free_result( $result );
+ $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 = '';
+ }
+ $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 );
}
return $ret;
}
- # More complex SELECT wrapper, single row only
- # Aborts or returns FALSE on error
- # 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" ) )
- # would return an object where $obj->cur_id is the ID of the Astronomy article
- function getArray( $table, $vars, $conds, $fname = "Database::getArray" )
+ # SELECT wrapper
+ function select( $table, $vars, $conds, $fname = "Database::select", $options = array() )
{
$vars = implode( ",", $vars );
+ $table = $this->tableName( $table );
+ if ( !is_array( $options ) ) {
+ $options = array( $options );
+ }
+
+ $tailOpts = '';
+
+ if ( isset( $options['ORDER BY'] ) ) {
+ $tailOpts .= " ORDER BY {$options['ORDER BY']}";
+ }
+ if ( isset( $options['LIMIT'] ) ) {
+ $tailOpts .= " LIMIT {$options['LIMIT']}";
+ }
+
+ if ( is_numeric( array_search( 'FOR UPDATE', $options ) ) ) {
+ $tailOpts .= ' FOR UPDATE';
+ }
+
+ if ( is_numeric( array_search( 'LOCK IN SHARE MODE', $options ) ) ) {
+ $tailOpts .= ' LOCK IN SHARE MODE';
+ }
+
+ if ( isset( $options['USE INDEX'] ) ) {
+ $useIndex = $this->useIndexClause( $options['USE INDEX'] );
+ } else {
+ $useIndex = '';
+ }
+
if ( $conds !== false ) {
- $where = Database::makeList( $conds, LIST_AND );
- $sql = "SELECT $vars FROM $table WHERE $where LIMIT 1";
+ $where = $this->makeList( $conds, LIST_AND );
+ $sql = "SELECT $vars FROM $table $useIndex WHERE $where $tailOpts";
} else {
- $sql = "SELECT $vars FROM $table LIMIT 1";
+ $sql = "SELECT $vars FROM $table $useIndex $tailOpts";
}
- $res = $this->query( $sql, $fname );
+ return $this->query( $sql, $fname );
+ }
+
+ # Single row SELECT wrapper
+ # Aborts or returns FALSE on error
+ #
+ # $vars: the selected variables
+ # $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" ) )
+ # 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() ) {
+ $options['LIMIT'] = 1;
+ $res = $this->select( $table, $vars, $conds, $fname, $options );
if ( $res === false || !$this->numRows( $res ) ) {
return false;
}
$obj = $this->fetchObject( $res );
$this->freeResult( $res );
return $obj;
+
}
# Removes most variables from an SQL query and replaces them with X or N for numbers.
@@ -322,6 +383,7 @@ class Database {
# If errors are explicitly ignored, returns NULL on failure
function fieldExists( $table, $field, $fname = "Database::fieldExists" )
{
+ $table = $this->tableName( $table );
$res = $this->query( "DESCRIBE $table", DB_READ, $fname );
if ( !$res ) {
return NULL;
@@ -343,28 +405,35 @@ class Database {
# If errors are explicitly ignored, returns NULL on failure
function indexExists( $table, $index, $fname = "Database::indexExists" )
{
+ $info = $this->indexInfo( $table, $index, $fname );
+ if ( is_null( $info ) ) {
+ return NULL;
+ } else {
+ return $info !== false;
+ }
+ }
+
+ function indexInfo( $table, $index, $fname = "Database::indexInfo" ) {
# SHOW INDEX works in MySQL 3.23.58, but SHOW INDEXES does not.
# SHOW INDEX should work for 3.x and up:
# http://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
+ $table = $this->tableName( $table );
$sql = "SHOW INDEX FROM $table";
- $res = $this->query( $sql, DB_READ, $fname );
+ $res = $this->query( $sql, $fname );
if ( !$res ) {
return NULL;
}
- $found = false;
-
while ( $row = $this->fetchObject( $res ) ) {
if ( $row->Key_name == $index ) {
- $found = true;
- break;
+ return $row;
}
}
- return $found;
+ return false;
}
-
function tableExists( $table )
{
+ $table = $this->tableName( $table );
$old = $this->mIgnoreErrors;
$this->mIgnoreErrors = true;
$res = $this->query( "SELECT 1 FROM $table LIMIT 1" );
@@ -379,6 +448,7 @@ class Database {
function fieldInfo( $table, $field )
{
+ $table = $this->tableName( $table );
$res = $this->query( "SELECT * FROM $table LIMIT 1" );
$n = mysql_num_fields( $res );
for( $i = 0; $i < $n; $i++ ) {
@@ -391,39 +461,61 @@ class Database {
}
# INSERT wrapper, inserts an array into a table
- # Keys are field names, values are values
+ #
+ # $a may be a single associative array, or an array of these with numeric keys, for
+ # multi-row insert.
+ #
# Usually aborts on failure
# If errors are explicitly ignored, returns success
- function insertArray( $table, $a, $fname = "Database::insertArray" )
+ function insertArray( $table, $a, $fname = "Database::insertArray", $options = array() )
{
- $sql1 = "INSERT INTO $table (";
- $sql2 = "VALUES (" . Database::makeList( $a );
- $first = true;
- foreach ( $a as $field => $value ) {
- if ( !$first ) {
- $sql1 .= ",";
+ $table = $this->tableName( $table );
+ if ( isset( $a[0] ) && is_array( $a[0] ) ) {
+ $multi = true;
+ $keys = array_keys( $a[0] );
+ } else {
+ $multi = false;
+ $keys = array_keys( $a );
+ }
+
+ $sql = 'INSERT ' . implode( ' ', $options ) .
+ " INTO $table (" . implode( ',', $keys ) . ') VALUES ';
+
+ if ( $multi ) {
+ $first = true;
+ foreach ( $a as $row ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",";
+ }
+ $sql .= '(' . $this->makeList( $row ) . ')';
}
- $first = false;
- $sql1 .= $field;
+ } else {
+ $sql .= '(' . $this->makeList( $a ) . ')';
}
- $sql = "$sql1) $sql2)";
return !!$this->query( $sql, $fname );
}
- # A cross between insertArray and getArray, takes a condition array and a SET array
+ # UPDATE wrapper, takes a condition array and a SET array
function updateArray( $table, $values, $conds, $fname = "Database::updateArray" )
{
+ $table = $this->tableName( $table );
$sql = "UPDATE $table SET " . $this->makeList( $values, LIST_SET );
$sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
$this->query( $sql, $fname );
}
# Makes a wfStrencoded list from an array
- # $mode: LIST_COMMA - comma separated, no field names
- # LIST_AND - ANDed WHERE clause (without the WHERE)
- # LIST_SET - comma separated with field names, like a SET clause
- /* static */ function makeList( $a, $mode = LIST_COMMA )
+ # $mode: LIST_COMMA - comma separated, no field names
+ # LIST_AND - ANDed WHERE clause (without the WHERE)
+ # LIST_SET - comma separated with field names, like a SET clause
+ function makeList( $a, $mode = LIST_COMMA )
{
+ if ( !is_array( $a ) ) {
+ wfDebugDieBacktrace( 'Database::makeList called with incorrect parameters' );
+ }
+
$first = true;
$list = "";
foreach ( $a as $field => $value ) {
@@ -436,13 +528,13 @@ class Database {
} else {
$first = false;
}
- if ( $mode == LIST_AND || $mode == LIST_SET ) {
- $list .= "$field=";
- }
- if ( !is_numeric( $value ) ) {
- $list .= "'" . wfStrencode( $value ) . "'";
+ if ( $mode == LIST_AND && is_numeric( $field ) ) {
+ $list .= "($value)";
} else {
- $list .= $value;
+ if ( $mode == LIST_AND || $mode == LIST_SET ) {
+ $list .= "$field=";
+ }
+ $list .= $this->addQuotes( $value );
}
}
return $list;
@@ -465,8 +557,151 @@ class Database {
function stopTimer()
{
}
+
+ function tableName( $name ) {
+ return $name;
+ }
+
+ function strencode( $s ) {
+ return addslashes( $s );
+ }
+
+ # If it's a string, adds quotes and backslashes
+ # Otherwise returns as-is
+ function addQuotes( $s ) {
+ if ( !is_numeric( $s ) ) {
+ $s = "'" . $this->strencode( $s ) . "'";
+ } else if ( is_null( $s ) ) {
+ $s = 'NULL';
+ }
+ return $s;
+ }
+
+ # Returns an appropriately quoted sequence value for inserting a new row.
+ # MySQL has autoincrement fields, so this is just NULL. But the PostgreSQL
+ # subclass will return an integer, and save the value for insertId()
+ function nextSequenceValue( $seqName ) {
+ return NULL;
+ }
+
+ # USE INDEX clause
+ # PostgreSQL doesn't have them and returns ""
+ function useIndexClause( $index ) {
+ return "USE INDEX ($index)";
+ }
+
+ # REPLACE query wrapper
+ # PostgreSQL simulates this with a DELETE followed by INSERT
+ # $row is the row to insert, an associative array
+ # $uniqueIndexes is an array of indexes. Each element may be either a
+ # field name or an array of field names
+ #
+ # It may be more efficient to leave off unique indexes which are unlikely to collide.
+ # However if you do this, you run the risk of encountering errors which wouldn't have
+ # occurred in MySQL
+ function replace( $table, $uniqueIndexes, $rows, $fname = "Database::replace" ) {
+ $table = $this->tableName( $table );
+
+ # Single row case
+ if ( !is_array( reset( $rows ) ) ) {
+ $rows = array( $rows );
+ }
+
+ $sql = "REPLACE INTO $table (" . implode( ',', array_flip( $rows[0] ) ) .") VALUES ";
+ $first = true;
+ foreach ( $rows as $row ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",";
+ }
+ $sql .= "(" . $this->makeList( $row ) . ")";
+ }
+ return $this->query( $sql, $fname );
+ }
+
+ # DELETE where the condition is a join
+ # MySQL does this with a multi-table DELETE syntax, PostgreSQL does it with sub-selects
+ #
+ # $delTable is the table to delete from
+ # $joinTable is the other table
+ # $delVar is the variable to join on, in the first table
+ # $joinVar is the variable to join on, in the second table
+ # $conds is a condition array of field names mapped to variables, ANDed together in the WHERE clause
+ #
+ # For safety, an empty $conds will not delete everything. If you want to delete all rows where the
+ # join condition matches, set $conds='*'
+ #
+ # DO NOT put the join condition in $conds
+ function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin" ) {
+ if ( !$conds ) {
+ wfDebugDieBacktrace( 'Database::deleteJoin() called with empty $conds' );
+ }
+
+ $delTable = $this->tableName( $delTable );
+ $joinTable = $this->tableName( $joinTable );
+ $sql = "DELETE $delTable FROM $delTable, $joinTable WHERE $delVar=$joinVar ";
+ if ( $conds != '*' ) {
+ $sql .= " AND " . $this->makeList( $conds, LIST_AND );
+ }
+
+ return $this->query( $sql, $fname );
+ }
+
+ # Returns the size of a text field, or -1 for "unlimited"
+ function textFieldSize( $table, $field ) {
+ $table = $this->tableName( $table );
+ $sql = "SHOW COLUMNS FROM $table LIKE \"$field\";";
+ $res = $this->query( $sql, "Database::textFieldSize" );
+ $row = wfFetchObject( $res );
+ $this->freeResult( $res );
+
+ if ( preg_match( "/\((.*)\)/", $row->Type, $m ) ) {
+ $size = $m[1];
+ } else {
+ $size = -1;
+ }
+ return $size;
+ }
+
+ function lowPriorityOption() {
+ return 'LOW_PRIORITY';
+ }
+
+ # Use $conds == "*" to delete all rows
+ function delete( $table, $conds, $fname = "Database::delete" ) {
+ if ( !$conds ) {
+ wfDebugDieBacktrace( "Database::delete() called with no conditions" );
+ }
+ $table = $this->tableName( $table );
+ $sql = "DELETE FROM $table ";
+ if ( $conds != '*' ) {
+ $sql .= "WHERE " . $this->makeList( $conds, LIST_AND );
+ }
+ return $this->query( $sql, $fname );
+ }
+
+ # INSERT SELECT wrapper
+ # $varMap must be an associative array of the form array( 'dest1' => 'source1', ...)
+ # Source items may be literals rather than field names, but strings should be quoted with Database::addQuotes()
+ # $conds may be "*" to copy the whole table
+ function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = 'Database::insertSelect' ) {
+ $destTable = $this->tableName( $destTable );
+ $srcTable = $this->tableName( $srcTable );
+ $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ")" .
+ " SELECT " . implode( ',', $varMap ) .
+ " FROM $srcTable";
+ if ( $conds != '*' ) {
+ $sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
+ }
+ return $this->query( $sql, $fname );
+ }
}
+class DatabaseMysql extends Database {
+ # Inherit all
+}
+
#------------------------------------------------------------------------------
# Global functions
#------------------------------------------------------------------------------
@@ -520,11 +755,6 @@ function wfEmergencyAbort( &$conn, $error ) {
wfAbruptExit();
}
-function wfStrencode( $s )
-{
- return addslashes( $s );
-}
-
function wfLimitResult( $limit, $offset ) {
return " LIMIT ".(is_numeric($offset)?"{$offset},":"")."{$limit} ";
}
diff --git a/includes/DatabaseFunctions.php b/includes/DatabaseFunctions.php
index 3fde31b9f0c0..c5f1b6dbe60d 100644
--- a/includes/DatabaseFunctions.php
+++ b/includes/DatabaseFunctions.php
@@ -10,18 +10,6 @@
# Note: $wgDatabase has ceased to exist. Destroy all references.
-$wgIsMySQL=false;
-$wgIsPg=false;
-
-if ($wgDBtype=="mysql") {
- require_once( "Database.php" );
- $wgIsMySQL=true;
-} elseif ($wgDBtype=="pgsql") {
- require_once( "DatabasePostgreSQL.php" );
- $wgIsPg=true;
-}
-
-
# Usually aborts on failure
# If errors are explicitly ignored, returns success
function wfQuery( $sql, $db, $fname = "" )
@@ -220,7 +208,7 @@ function wfGetSQL( $table, $var, $cond="", $dbi = DB_LAST )
{
$db =& wfGetDB( $dbi );
if ( $db !== false ) {
- return $db->get( $table, $var, $cond );
+ return $db->getField( $table, $var, $cond );
} else {
return false;
}
@@ -277,4 +265,40 @@ function wfUpdateArray( $table, $values, $conds, $fname = "wfUpdateArray", $dbi
}
}
+function wfTableName( $name, $dbi = DB_LAST ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->tableName( $name );
+ } else {
+ return false;
+ }
+}
+
+function wfStrencode( $s, $dbi = DB_LAST )
+{
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->strencode( $s );
+ } else {
+ return false;
+ }
+}
+
+function wfNextSequenceValue( $seqName, $dbi = DB_WRITE ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->nextSequenceValue( $seqName );
+ } else {
+ return false;
+ }
+}
+
+function wfUseIndexClause( $index, $dbi = DB_READ ) {
+ $db =& wfGetDB( $dbi );
+ if ( $db !== false ) {
+ return $db->useIndexClause( $index );
+ } else {
+ return false;
+ }
+}
?>
diff --git a/includes/DatabasePostgreSQL.php b/includes/DatabasePostgreSQL.php
index 2b3ba25f10b5..1b22a8e0f58f 100644
--- a/includes/DatabasePostgreSQL.php
+++ b/includes/DatabasePostgreSQL.php
@@ -14,98 +14,32 @@
#
# Hashar
-require_once( "FulltextStoplist.php" );
-require_once( "CacheManager.php" );
+class DatabasePgsql extends Database {
+ var $mInsertId = NULL;
-define( "DB_READ", -1 );
-define( "DB_WRITE", -2 );
-define( "DB_LAST", -3 );
-
-define( "LIST_COMMA", 0 );
-define( "LIST_AND", 1 );
-define( "LIST_SET", 2 );
-
-class Database {
-
-#------------------------------------------------------------------------------
-# Variables
-#------------------------------------------------------------------------------
- /* private */ var $mLastQuery = "";
- /* private */ var $mBufferResults = true;
- /* private */ var $mIgnoreErrors = false;
-
- /* private */ var $mServer, $mUser, $mPassword, $mConn, $mDBname;
- /* private */ var $mOut, $mDebug, $mOpened = false;
-
- /* private */ var $mFailFunction;
- /* private */ var $mLastResult;
-
-#------------------------------------------------------------------------------
-# Accessors
-#------------------------------------------------------------------------------
- # Set functions
- # These set a variable and return the previous state
-
- # Fail function, takes a Database as a parameter
- # Set to false for default, 1 for ignore errors
- function setFailFunction( $function ) { return wfSetVar( $this->mFailFunction, $function ); }
-
- # Output page, used for reporting errors
- # FALSE means discard output
- function &setOutputPage( &$out ) { $this->mOut =& $out; }
-
- # Boolean, controls output of large amounts of debug information
- function setDebug( $debug ) { return wfSetVar( $this->mDebug, $debug ); }
-
- # Turns buffering of SQL result sets on (true) or off (false). Default is
- # "on" and it should not be changed without good reasons.
- function setBufferResults( $buffer ) { return wfSetVar( $this->mBufferResults, $buffer ); }
-
- # Turns on (false) or off (true) the automatic generation and sending
- # of a "we're sorry, but there has been a database error" page on
- # database errors. Default is on (false). When turned off, the
- # code should use wfLastErrno() and wfLastError() to handle the
- # situation as appropriate.
- function setIgnoreErrors( $ignoreErrors ) { return wfSetVar( $this->mIgnoreErrors, $ignoreErrors ); }
-
- # Get functions
-
- function lastQuery() { return $this->mLastQuery; }
- function isOpen() { return $this->mOpened; }
-
-#------------------------------------------------------------------------------
-# Other functions
-#------------------------------------------------------------------------------
-
- function Database()
+ function DatabasePgsql($server = false, $user = false, $password = false, $dbName = false,
+ $failFunction = false, $debug = false, $bufferResults = true, $ignoreErrors = false)
{
- global $wgOut;
- # Can't get a reference if it hasn't been set yet
- if ( !isset( $wgOut ) ) {
- $wgOut = NULL;
- }
- $this->mOut =& $wgOut;
-
+ Database::Database( $server, $user, $password, $dbName, $failFunction, $debug,
+ $bufferResults, $ignoreErrors );
}
-
+
/* static */ function newFromParams( $server, $user, $password, $dbName,
$failFunction = false, $debug = false, $bufferResults = true, $ignoreErrors = false )
{
- $db = new Database;
- $db->mFailFunction = $failFunction;
- $db->mIgnoreErrors = $ignoreErrors;
- $db->mDebug = $debug;
- $db->mBufferResults = $bufferResults;
- $db->open( $server, $user, $password, $dbName );
- return $db;
+ return new DatabasePgsql( $server, $user, $password, $dbName, $failFunction, $debug,
+ $bufferResults, $ignoreErrors );
}
-
+
# Usually aborts on failure
# If the failFunction is set to a non-zero integer, returns success
function open( $server, $user, $password, $dbName )
{
- global $wgEmergencyContact;
-
+ # Test for PostgreSQL support, to avoid suppressed fatal error
+ if ( !function_exists( 'pg_connect' ) ) {
+ die( "PostgreSQL functions missing, have you compiled PHP with the --with-pgsql option?\n" );
+ }
+
$this->close();
$this->mServer = $server;
$this->mUser = $user;
@@ -114,7 +48,6 @@ class Database {
$success = false;
-
if ( "" != $dbName ) {
# start a database connection
@$this->mConn = pg_connect("host=$server dbname=$dbName user=$user password=$password");
@@ -141,20 +74,9 @@ class Database {
}
}
- /* private */ function reportConnectionError( $msg = "")
- {
- if ( $this->mFailFunction ) {
- if ( !is_int( $this->mFailFunction ) ) {
- $this->$mFailFunction( $this );
- }
- } else {
- wfEmergencyAbort( $this );
- }
- }
-
# Usually aborts on failure
# If errors are explicitly ignored, returns success
- function query( $sql, $fname = "" )
+ function query( $sql, $fname = "", $tempIgnore = false )
{
global $wgProfiling;
@@ -176,10 +98,12 @@ class Database {
$ret = pg_query( $this->mConn , $sql);
$this->mLastResult = $ret;
if ( false == $ret ) {
+ // Ignore errors during error handling to prevent infinite recursion
+ $ignore = $this->setIgnoreErrors( true );
$error = pg_last_error( $this->mConn );
// TODO FIXME : no error number function in postgre
// $errno = mysql_errno( $this->mConn );
- if( $this->mIgnoreErrors ) {
+ if( $ignore || $tempIgnore ) {
wfDebug("SQL ERROR (ignored): " . $error . "\n");
} else {
wfDebug("SQL ERROR: " . $error . "\n");
@@ -188,6 +112,7 @@ class Database {
$this->mOut->databaseError( $fname, $sql, $error, 0 );
}
}
+ $this->setIgnoreErrors( $ignore );
}
if ( $wgProfiling ) {
@@ -196,6 +121,10 @@ class Database {
return $ret;
}
+ function queryIgnore( $sql, $fname = "" ) {
+ return $this->query( $sql, $fname, true );
+ }
+
function freeResult( $res ) {
if ( !@pg_free_result( $res ) ) {
wfDebugDieBacktrace( "Unable to free PostgreSQL result\n" );
@@ -231,150 +160,40 @@ class Database {
}
function numFields( $res ) { return pg_num_fields( $res ); }
function fieldName( $res, $n ) { return pg_field_name( $res, $n ); }
- // TODO FIXME: need to implement something here
+
+ # This must be called after nextSequenceVal
function insertId() {
- //return mysql_insert_id( $this->mConn );
- wfDebugDieBacktrace( "Database::insertId() error : not implemented for postgre, use sequences" );
+ return $this->mInsertId;
}
+
function dataSeek( $res, $row ) { return pg_result_seek( $res, $row ); }
- function lastErrno() { return $this->lastError(); }
function lastError() { return pg_last_error(); }
function affectedRows() {
return pg_affected_rows( $this->mLastResult );
}
- # Simple UPDATE wrapper
- # Usually aborts on failure
- # If errors are explicitly ignored, returns success
- function set( $table, $var, $value, $cond, $fname = "Database::set" )
- {
- $sql = "UPDATE \"$table\" SET \"$var\" = '" .
- wfStrencode( $value ) . "' WHERE ($cond)";
- return !!$this->query( $sql, DB_WRITE, $fname );
- }
-
- # 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 get( $table, $var, $cond, $fname = "Database::get" )
- {
- $from=$table?" FROM \"$table\" ":"";
- $where=$cond?" WHERE ($cond)":"";
-
- $sql = "SELECT $var $from $where";
-
- $result = $this->query( $sql, DB_READ, $fname );
-
- $ret = "";
- if ( pg_num_rows( $result ) > 0 ) {
- $s = pg_fetch_array( $result );
- $ret = $s[0];
- pg_free_result( $result );
- }
- return $ret;
- }
-
- # More complex SELECT wrapper, single row only
- # Aborts or returns FALSE on error
- # 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" ) )
- # would return an object where $obj->cur_id is the ID of the Astronomy article
- function getArray( $table, $vars, $conds, $fname = "Database::getArray" )
- {
- $vars = implode( ",", $vars );
- $where = Database::makeList( $conds, LIST_AND );
- $sql = "SELECT \"$vars\" FROM \"$table\" WHERE $where LIMIT 1";
- $res = $this->query( $sql, $fname );
- if ( $res === false || !$this->numRows( $res ) ) {
- return false;
- }
- $obj = $this->fetchObject( $res );
- $this->freeResult( $res );
- return $obj;
- }
-
- # Removes most variables from an SQL query and replaces them with X or N for numbers.
- # It's only slightly flawed. Don't use for anything important.
- /* static */ function generalizeSQL( $sql )
- {
- # This does the same as the regexp below would do, but in such a way
- # as to avoid crashing php on some large strings.
- # $sql = preg_replace ( "/'([^\\\\']|\\\\.)*'|\"([^\\\\\"]|\\\\.)*\"/", "'X'", $sql);
-
- $sql = str_replace ( "\\\\", "", $sql);
- $sql = str_replace ( "\\'", "", $sql);
- $sql = str_replace ( "\\\"", "", $sql);
- $sql = preg_replace ("/'.*'/s", "'X'", $sql);
- $sql = preg_replace ('/".*"/s', "'X'", $sql);
-
- # All newlines, tabs, etc replaced by single space
- $sql = preg_replace ( "/\s+/", " ", $sql);
-
- # All numbers => N
- $sql = preg_replace ('/-?[0-9]+/s', "N", $sql);
-
- return $sql;
- }
-
- # Determines whether a field exists in a table
- # Usually aborts on failure
- # If errors are explicitly ignored, returns NULL on failure
- function fieldExists( $table, $field, $fname = "Database::fieldExists" )
- {
- $res = $this->query( "DESCRIBE '$table'", DB_READ, $fname );
- if ( !$res ) {
- return NULL;
- }
-
- $found = false;
-
- while ( $row = $this->fetchObject( $res ) ) {
- if ( $row->Field == $field ) {
- $found = true;
- break;
- }
- }
- return $found;
- }
-
- # Determines whether an index exists
- # Usually aborts on failure
+ # Returns information about an index
# If errors are explicitly ignored, returns NULL on failure
- function indexExists( $table, $index, $fname = "Database::indexExists" )
+ function indexInfo( $table, $index, $fname = "Database::indexExists" )
{
$sql = "SELECT indexname FROM pg_indexes WHERE tablename='$table'";
- $res = $this->query( $sql, DB_READ, $fname );
+ $res = $this->query( $sql, $fname );
if ( !$res ) {
return NULL;
}
- $found = false;
-
while ( $row = $this->fetchObject( $res ) ) {
if ( $row->Key_name == $index ) {
- $found = true;
- break;
+ return $row;
}
}
- return $found;
- }
-
- function tableExists( $table )
- {
- $old = $this->mIgnoreErrors;
- $this->mIgnoreErrors = true;
- $res = $this->query( "SELECT 1 FROM '$table' LIMIT 1" );
- $this->mIgnoreErrors = $old;
- if( $res ) {
- $this->freeResult( $res );
- return true;
- } else {
- return false;
- }
+ return false;
}
function fieldInfo( $table, $field )
{
+ wfDebugDieBacktrace( "Database::fieldInfo() error : mysql_fetch_field() not implemented for postgre" );
+ /*
$res = $this->query( "SELECT * FROM '$table' LIMIT 1" );
$n = pg_num_fields( $res );
for( $i = 0; $i < $n; $i++ ) {
@@ -385,134 +204,154 @@ class Database {
return $meta;
}
}
- return false;
+ return false;*/
}
- # INSERT wrapper, inserts an array into a table
- # Keys are field names, values are values
- # Usually aborts on failure
- # If errors are explicitly ignored, returns success
- function insertArray( $table, $a, $fname = "Database::insertArray" )
- {
- $sql1 = "INSERT INTO \"$table\" (";
- $sql2 = "VALUES (" . Database::makeList( $a );
- $first = true;
- foreach ( $a as $field => $value ) {
- if ( !$first ) {
- $sql1 .= ",";
- }
- $first = false;
- $sql1 .= $field;
+ function insertArray( $table, $a, $fname = "Database::insertArray", $options = array() ) {
+ # PostgreSQL doesn't support options
+ # We have a go at faking some of them
+ if ( in_array( 'IGNORE', $options ) ) {
+ $ignore = true;
+ $oldIgnore = $this->setIgnoreErrors( true );
}
- $sql = "$sql1) $sql2)";
- return !!$this->query( $sql, $fname );
- }
-
- # A cross between insertArray and getArray, takes a condition array and a SET array
- function updateArray( $table, $values, $conds, $fname = "Database::updateArray" )
- {
- $sql = "UPDATE '$table' SET " . $this->makeList( $values, LIST_SET );
- $sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
- $this->query( $sql, $fname );
- }
-
- # Makes a wfStrencoded list from an array
- # $mode: LIST_COMMA - comma separated, no field names
- # LIST_AND - ANDed WHERE clause (without the WHERE)
- # LIST_SET - comma separated with field names, like a SET clause
- /* static */ function makeList( $a, $mode = LIST_COMMA )
- {
- $first = true;
- $list = "";
- foreach ( $a as $field => $value ) {
- if ( !$first ) {
- if ( $mode == LIST_AND ) {
- $list .= " AND ";
- } else {
- $list .= ",";
- }
- } else {
- $first = false;
- }
- if ( $mode == LIST_AND || $mode == LIST_SET ) {
- $list .= "$field=";
- }
- if ( !is_numeric( $value ) ) {
- $list .= "'" . wfStrencode( $value ) . "'";
- } else {
- $list .= $value;
- }
+ $retVal = parent::insertArray( $table, $a, $fname, array() );
+ if ( $ignore ) {
+ $this->setIgnoreErrors( $oldIgnore );
}
- return $list;
+ return $retVal;
}
function startTimer( $timeout )
{
global $IP;
wfDebugDieBacktrace( "Database::startTimer() error : mysql_thread_id() not implemented for postgre" );
- $tid = mysql_thread_id( $this->mConn );
- exec( "php $IP/killthread.php $timeout $tid &>/dev/null &" );
+ /*$tid = mysql_thread_id( $this->mConn );
+ exec( "php $IP/killthread.php $timeout $tid &>/dev/null &" );*/
}
- function stopTimer()
- {
+ function tableName( $name ) {
+ # First run any transformations from the parent object
+ $name = parent::tableName( $name );
+
+ # Now quote PG reserved keywords
+ switch( $name ) {
+ case 'user':
+ return '"user"';
+ case 'old':
+ return '"old"';
+ default:
+ return $name;
+ }
}
-}
+ function strencode( $s ) {
+ return pg_escape_string( $s );
+ }
-#------------------------------------------------------------------------------
-# Global functions
-#------------------------------------------------------------------------------
+ # Return the next in a sequence, save the value for retrieval via insertId()
+ function nextSequenceValue( $seqName ) {
+ $value = $this->getField(""," nextval('" . $seqName . "')");
+ $this->mInsertId = $value;
+ return $value;
+ }
-/* Standard fail function, called by default when a connection cannot be established
- Displays the file cache if possible */
-function wfEmergencyAbort( &$conn ) {
- global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding, $wgSiteNotice, $wgOutputEncoding;
-
- header( "Content-type: text/html; charset=$wgOutputEncoding" );
- $msg = $wgSiteNotice;
- if($msg == "") $msg = wfMsgNoDB( "noconnect" );
- $text = $msg;
+ # USE INDEX clause
+ # PostgreSQL doesn't have them and returns ""
+ function useIndexClause( $index ) {
+ return '';
+ }
- if($wgUseFileCache) {
- if($wgTitle) {
- $t =& $wgTitle;
- } else {
- if($title) {
- $t = Title::newFromURL( $title );
- } elseif (@$_REQUEST['search']) {
- $search = $_REQUEST['search'];
- echo wfMsgNoDB( "searchdisabled" );
- echo wfMsgNoDB( "googlesearch", htmlspecialchars( $search ), $wgInputEncoding );
- wfAbruptExit();
+ # REPLACE query wrapper
+ # PostgreSQL simulates this with a DELETE followed by INSERT
+ # $row is the row to insert, an associative array
+ # $uniqueIndexes is an array of indexes. Each element may be either a
+ # field name or an array of field names
+ #
+ # It may be more efficient to leave off unique indexes which are unlikely to collide.
+ # However if you do this, you run the risk of encountering errors which wouldn't have
+ # occurred in MySQL
+ 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 ";
+ }
+ $sql .= "$col = " $this->strencode
+
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= "OR ";
+ }
+ $sql .= "$col IN (";
+ $indexValues = array();
+ foreach ( $rows as $row ) {
+ $indexValues[] = $row[$col];
+ }
+ $sql .= $this->makeList( $indexValues, LIST_COMMA ) . ") ";
+ }
+ $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 {
- $t = Title::newFromText( wfMsgNoDB( "mainpage" ) );
+ $sql .= ",";
}
+ $sql .= "(" . $this->makeList( $row, LIST_COMMA ) . ")";
+ }
+ $this->query( $sql, $fname );
+ }
+
+ # DELETE where the condition is a join
+ function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = "Database::deleteJoin" ) {
+ if ( !$conds ) {
+ wfDebugDieBacktrace( 'Database::deleteJoin() called with empty $conds' );
}
- $cache = new CacheManager( $t );
- if( $cache->isFileCached() ) {
- $msg = "<p style='color: red'><b>$msg<br />\n" .
- wfMsgNoDB( "cachederror" ) . "</b></p>\n";
-
- $tag = "<div id='article'>";
- $text = str_replace(
- $tag,
- $tag . $msg,
- $cache->fetchPageText() );
+ $delTable = $this->tableName( $delTable );
+ $joinTable = $this->tableName( $joinTable );
+ $sql = "DELETE FROM $delTable WHERE $delVar IN (SELECT $joinVar FROM $joinTable ";
+ if ( $conds != '*' ) {
+ $sql .= "WHERE " . $this->makeList( $conds, LIST_AND );
}
+ $sql .= ")";
+
+ $this->query( $sql, $fname );
}
-
- /* Don't cache error pages! They cause no end of trouble... */
- header( "Cache-control: none" );
- header( "Pragma: nocache" );
- echo $text;
- wfAbruptExit();
-}
-function wfStrencode( $s )
-{
- return pg_escape_string( $s );
+ # Returns the size of a text field, or -1 for "unlimited"
+ function textFieldSize( $table, $field ) {
+ $table = $this->tableName( $table );
+ $res = $this->query( "SELECT $field FROM $table LIMIT 1", "Database::textFieldLength" );
+ $size = pg_field_size( $res, 0 );
+ $this->freeResult( $res );
+ return $size;
+ }
+
+ function lowPriorityOption() {
+ return '';
+ }
}
function wfLimitResult( $limit, $offset ) {
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 447129412fdb..100a1e279a9b 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -61,8 +61,16 @@ $wgDBuser = 'wikiuser';
$wgDBtype = "mysql"; # "mysql" for working code and "pgsql" for development/broken code
# Database load balancer
-$wgDBservers = false; # e.g. array(0 => "larousse", 1 => "pliny")
-$wgDBloads = false; # e.g. array(0 => 0.6, 1 => 0.4);
+# This is a two-dimensional array, an array of server info structures
+# Fields are:
+# host: Host name
+# dbname: Default database name
+# 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
+# Leave at false to use the single-server variables above
+$wgDBservers = false;
# Sysop SQL queries
$wgAllowSysopQueries = false; # Dangerous if not configured properly.
diff --git a/includes/DifferenceEngine.php b/includes/DifferenceEngine.php
index 2e3937ee4802..30d369e6a7e9 100644
--- a/includes/DifferenceEngine.php
+++ b/includes/DifferenceEngine.php
@@ -118,32 +118,33 @@ cellpadding='0' cellspacing='4px' class='diff'><tr>
#
function loadText()
{
- global $wgTitle, $wgOut, $wgLang, $wgIsMySQL, $wgIsPg;
+ global $wgTitle, $wgOut, $wgLang;
$fname = "DifferenceEngine::loadText";
- $oldtable=$wgIsPg?'"old"':'old';
+ $dbr =& wfGetDB( DB_READ );
if ( 0 == $this->mNewid || 0 == $this->mOldid ) {
$wgOut->setArticleFlag( true );
$this->mNewtitle = wfMsg( "currentrev" );
$id = $wgTitle->getArticleID();
- $sql = "SELECT cur_text, cur_user_text, cur_comment FROM cur WHERE cur_id={$id}";
- $res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) { return false; }
+ $s = $dbr->getArray( 'cur', array( 'cur_text', 'cur_user_text', 'cur_comment' ),
+ array( 'cur_id' => $id ), $fname );
+ if ( $s === false ) {
+ return false;
+ }
- $s = wfFetchObject( $res );
$this->mNewPage = &$wgTitle;
$this->mNewtext = $s->cur_text;
$this->mNewUser = $s->cur_user_text;
$this->mNewComment = $s->cur_comment;
} else {
- $sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment FROM $oldtable WHERE " .
- "old_id={$this->mNewid}";
+ $s = $dbr->getArray( 'old', array( 'old_namespace','old_title','old_timestamp', 'old_text',
+ 'old_flags','old_user_text','old_comment' ), array( 'old_id' => $this->mNewid ), $fname );
- $res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) { return false; }
+ if ( $s === false ) {
+ return false;
+ }
- $s = wfFetchObject( $res );
$this->mNewtext = Article::getRevisionText( $s );
$t = $wgLang->timeanddate( $s->old_timestamp, true );
@@ -153,21 +154,23 @@ cellpadding='0' cellspacing='4px' class='diff'><tr>
$this->mNewComment = $s->old_comment;
}
if ( 0 == $this->mOldid ) {
- $use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":"";
- $sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment " .
- "FROM $oldtable $use_index WHERE " .
- "old_namespace=" . $this->mNewPage->getNamespace() . " AND " .
- "old_title='" . wfStrencode( $this->mNewPage->getDBkey() ) .
- "' ORDER BY inverse_timestamp LIMIT 1";
- $res = wfQuery( $sql, DB_READ, $fname );
+ $s = $dbr->getArray( 'old',
+ array( 'old_namespace','old_title','old_timestamp','old_text', 'old_flags','old_user_text','old_comment' ),
+ array( /* WHERE */
+ 'old_namespace' => $this->mNewPage->getNamespace(),
+ 'old_title' => $this->mNewPage->getDBkey()
+ ), $fname, array( 'ORDER BY' => 'inverse_timestamp', 'USE INDEX' => 'name_title_timestamp' )
+ );
} else {
- $sql = "SELECT old_namespace,old_title,old_timestamp,old_text,old_flags,old_user_text,old_comment FROM $oldtable WHERE " .
- "old_id={$this->mOldid}";
- $res = wfQuery( $sql, DB_READ, $fname );
+ $s = $dbr->getArray( 'old',
+ array( 'old_namespace','old_title','old_timestamp','old_text','old_flags','old_user_text','old_comment'),
+ array( 'old_id' => $this->mOldid ),
+ $fname
+ );
+ }
+ if ( $s === false ) {
+ return false;
}
- if ( 0 == wfNumRows( $res ) ) { return false; }
-
- $s = wfFetchObject( $res );
$this->mOldPage = Title::MakeTitle( $s->old_namespace, $s->old_title );
$this->mOldtext = Article::getRevisionText( $s );
diff --git a/includes/EditPage.php b/includes/EditPage.php
index 04ff9c19156c..cb2be1bc79a7 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -541,19 +541,19 @@ htmlspecialchars( $wgLang->recodeForEdit( $this->textbox1 ) ) .
}
/* private */ function mergeChangesInto( &$text ){
- global $wgIsPg;
+ $fname = 'EditPage::mergeChangesInto';
$oldDate = $this->edittime;
- $res = wfQuery("SELECT cur_text FROM cur WHERE cur_id=" .
- $this->mTitle->getArticleID() . " FOR UPDATE", DB_WRITE);
- $obj = wfFetchObject($res);
+ $dbw =& wfGetDB( DB_WRITE );
+ $obj = $dbr->getArray( 'cur', array( 'cur_text' ), array( 'cur_id' => $this->mTitle->getArticleID() ),
+ $fname, 'FOR UPDATE' );
$yourtext = $obj->cur_text;
$ns = $this->mTitle->getNamespace();
- $title = wfStrencode( $this->mTitle->getDBkey() );
- $oldtable=$wgIsPg?'"old"':'old';
- $res = wfQuery("SELECT old_text,old_flags FROM $oldtable WHERE old_namespace = $ns AND ".
- "old_title = '{$title}' AND old_timestamp = '{$oldDate}'", DB_WRITE);
- $obj = wfFetchObject($res);
+ $title = $this->mTitle->getDBkey();
+ $obj = $dbw->getArray( 'old',
+ array( 'old_text','old_flags'),
+ array( 'old_namespace' => $ns, 'old_title' => $title, 'old_timestamp' => $oldDate ),
+ $fname );
$oldText = Article::getRevisionText( $obj );
if(wfMerge($oldText, $text, $yourtext, $result)){
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index a37e1dc20fe0..a72e84909b74 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -392,9 +392,9 @@ function wfDebugDieBacktrace( $msg = '' ) {
$f = explode( DIRECTORY_SEPARATOR, $call['file'] );
$file = $f[count($f)-1];
if ( $wgCommandLineMode ) {
- $msg .= "$file line {$call['line']}, in ";
+ $msg .= "$file line {$call['line']} calls ";
} else {
- $msg .= '<li>' . $file . " line " . $call['line'] . ', in ';
+ $msg .= '<li>' . $file . " line " . $call['line'] . ' calls ';
}
if( !empty( $call['class'] ) ) $msg .= $call['class'] . '::';
$msg .= $call['function'] . "()";
@@ -420,15 +420,18 @@ function wfNumberOfArticles()
/* private */ function wfLoadSiteStats()
{
global $wgNumberOfArticles, $wgTotalViews, $wgTotalEdits;
- if ( -1 != $wgNumberOfArticles ) return;
+ $fname = 'wfLoadSiteStats';
- $sql = 'SELECT ss_total_views, ss_total_edits, ss_good_articles ' .
- 'FROM site_stats WHERE ss_row_id=1';
- $res = wfQuery( $sql, DB_READ, 'wfLoadSiteStats' );
+ if ( -1 != $wgNumberOfArticles ) return;
+ $dbr =& wfGetDB( DB_READ );
+ $s = $dbr->getArray( 'site_stats',
+ array( 'ss_total_views', 'ss_total_edits', 'ss_good_articles' ),
+ array( 'ss_row_id' => 1 ), $fname
+ );
- if ( 0 == wfNumRows( $res ) ) { return; }
- else {
- $s = wfFetchObject( $res );
+ if ( $s === false ) {
+ return;
+ } else {
$wgTotalViews = $s->ss_total_views;
$wgTotalEdits = $s->ss_total_edits;
$wgNumberOfArticles = $s->ss_good_articles;
@@ -505,10 +508,14 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
global $wgUseCopyrightUpload;
$fname = 'wfRecordUpload';
-
- $sql = 'SELECT img_name,img_size,img_timestamp,img_description,img_user,' .
- "img_user_text FROM image WHERE img_name='" . wfStrencode( $name ) . "'";
- $res = wfQuery( $sql, DB_READ, $fname );
+ $dbw =& wfGetDB( DB_WRITE );
+
+ # img_name must be unique
+ $indexInfo = $dbw->indexInfo( 'image', 'img_name' );
+ if ( $indexInfo && $indexInfo->Non_unique ) {
+ wfDebugDieBacktrace( 'Database schema not up to date, please run maintenance/archives/patch-img_name_unique.sql' );
+ }
+
$now = wfTimestampNow();
$won = wfInvertTimestamp( $now );
@@ -524,15 +531,24 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
$now = wfTimestampNow();
$won = wfInvertTimestamp( $now );
-
- if ( 0 == wfNumRows( $res ) ) {
- $sql = 'INSERT INTO image (img_name,img_size,img_timestamp,' .
- "img_description,img_user,img_user_text) VALUES ('" .
- wfStrencode( $name ) . "',$size,'{$now}','" .
- wfStrencode( $desc ) . "', '" . $wgUser->getID() .
- "', '" . wfStrencode( $wgUser->getName() ) . "')";
- wfQuery( $sql, DB_WRITE, $fname );
+ # 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',
+ array(
+ 'img_name' => $name,
+ 'img_size'=> $size,
+ 'img_timestamp' => $now,
+ 'img_description' => $desc,
+ 'img_user' => $wgUser->getID(),
+ 'img_user_text' => $wgUser->getName(),
+ ), $fname, 'IGNORE'
+ );
+
+ if ( $dbw->affectedRows() ) {
+ # Successfully inserted, this is a new image
+
$sql = 'SELECT cur_id,cur_text FROM cur WHERE cur_namespace=' .
Namespace::getImage() . " AND cur_title='" .
wfStrencode( $name ) . "'";
@@ -559,6 +575,9 @@ function wfRecordUpload( $name, $oldver, $size, $desc, $copyStatus = "", $source
$u->doUpdate();
}
} else {
+ # Collision, this is an update of an image
+ $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,' .
@@ -999,5 +1018,29 @@ function wfInvertTimestamp( $ts ) {
);
}
+# Reference-counted warning suppression
+function wfSuppressWarnings( $end = false ) {
+ static $suppressCount = 0;
+ static $originalLevel = false;
+
+ if ( $end ) {
+ if ( $suppressCount ) {
+ $suppressCount --;
+ if ( !$suppressCount ) {
+ error_reporting( $originalLevel );
+ }
+ }
+ } else {
+ if ( !$suppressCount ) {
+ $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE ) );
+ }
+ $suppressCount++;
+ }
+}
+
+# Restore error level to previous value
+function wfRestoreWarnings() {
+ wfSuppressWarnings( true );
+}
?>
diff --git a/includes/Image.php b/includes/Image.php
index 27eeb9d72e3f..eb9dd8ee7f83 100644
--- a/includes/Image.php
+++ b/includes/Image.php
@@ -253,32 +253,31 @@ class Image
//**********************************************************************
// Return the image history of this image, line by line.
- // start with current version, than old versions.
- // use $this->historyLine to check which line to return:
+ // starts with current version, then old versions.
+ // uses $this->historyLine to check which line to return:
// 0 return line for current version
// 1 query for old versions, return first one
// 2, ... return next old version from above query
function nextHistoryLine()
{
$fname = "Image::nextHistoryLine()";
-
- if ( $this->historyLine == 0 ) // called for the first time, return line from cur
- {
- $sql = "SELECT img_size,img_description,img_user," .
- "img_user_text,img_timestamp, '' AS oi_archive_name FROM image WHERE " .
- "img_name='" . wfStrencode( $this->title->getDBkey() ) . "'";
- $this->historyRes = wfQuery( $sql, DB_READ, $fname );
-
- if ( 0 == wfNumRows( $this->historyRes ) ) { return FALSE; }
-
- } else if ( $this->historyLine == 1 )
- {
- $sql = "SELECT 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 FROM oldimage WHERE " .
- "oi_name='" . wfStrencode( $this->title->getDBkey() ) . "' " .
- "ORDER BY oi_timestamp DESC";
- $this->historyRes = wfQuery( $sql, DB_READ, $fname );
+ 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() ),
+ $fname
+ );
+ if ( 0 == wfNumRows( $this->historyRes ) ) {
+ 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'
+ ), array( 'oi_name' => $this->title->getDBkey() ), $fname, array( 'ORDER BY' => 'oi_timestamp DESC' )
+ );
}
$this->historyLine ++;
diff --git a/includes/ImagePage.php b/includes/ImagePage.php
index 6e8d72b6c20e..8073cdd5d651 100644
--- a/includes/ImagePage.php
+++ b/includes/ImagePage.php
@@ -85,18 +85,22 @@ class ImagePage extends Article {
$wgOut->addHTML( "<h2>" . wfMsg( "imagelinks" ) . "</h2>\n" );
- $sql = "SELECT cur_namespace,cur_title FROM imagelinks,cur WHERE il_to='" .
- wfStrencode( $this->mTitle->getDBkey() ) . "' AND il_from=cur_id";
- $res = wfQuery( $sql, DB_READ, "Article::imageLinks" );
+ $dbr =& wfGetDB( DB_READ );
+ $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" );
- if ( 0 == wfNumRows( $res ) ) {
+ if ( 0 == $dbr->numRows( $res ) ) {
$wgOut->addHtml( "<p>" . wfMsg( "nolinkstoimage" ) . "</p>\n" );
return;
}
$wgOut->addHTML( "<p>" . wfMsg( "linkstoimage" ) . "</p>\n<ul>" );
$sk = $wgUser->getSkin();
- while ( $s = wfFetchObject( $res ) ) {
+ while ( $s = $dbr->fetchObject( $res ) ) {
$name = Title::MakeTitle( $s->cur_namespace, $s->cur_title );
$link = $sk->makeKnownLinkObj( $name, "" );
$wgOut->addHTML( "<li>{$link}</li>\n" );
@@ -157,6 +161,8 @@ class ImagePage extends Article {
$reason = $wgRequest->getVal( 'wpReason' );
$image = $wgRequest->getVal( 'image' );
$oldimage = $wgRequest->getVal( 'oldimage' );
+
+ $dbw =& wfGetDB( DB_WRITE );
if ( !is_null( $image ) ) {
$dest = wfImageDir( $image );
@@ -165,14 +171,9 @@ class ImagePage extends Article {
$wgOut->fileDeleteError( "{$dest}/{$image}" );
return;
}
- $sql = "DELETE FROM image WHERE img_name='" .
- wfStrencode( $image ) . "'";
- wfQuery( $sql, DB_WRITE, $fname );
-
- $sql = "SELECT oi_archive_name FROM oldimage WHERE oi_name='" .
- wfStrencode( $image ) . "'";
- $res = wfQuery( $sql, DB_READ, $fname );
-
+ $dbw->delete( 'image', array( 'img_name' => $image ) );
+ $res = $dbw->select( 'oldimage', array( 'oi_archive_name' ), array( 'oi_name' => $image ) );
+
# Squid purging
if ( $wgUseSquid ) {
$urlArr = Array(
@@ -183,7 +184,7 @@ class ImagePage extends Article {
$urlArr = Array();
- while ( $s = wfFetchObject( $res ) ) {
+ while ( $s = $dbr->fetchObject( $res ) ) {
$this->doDeleteOldImage( $s->oi_archive_name );
$urlArr[] = $wgInternalServer.wfImageArchiveUrl( $s->oi_archive_name );
}
@@ -195,9 +196,7 @@ class ImagePage extends Article {
array_push( $wgDeferredUpdateList, $u );
}
- $sql = "DELETE FROM oldimage WHERE oi_name='" .
- wfStrencode( $image ) . "'";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->delete( 'oldimage', array( 'oi_name' => $image ) );
# Image itself is now gone, and database is cleaned.
# Now we remove the image description page.
@@ -216,10 +215,7 @@ class ImagePage extends Article {
wfPurgeSquidServers($urlArr);
}
$this->doDeleteOldImage( $oldimage );
- $sql = "DELETE FROM oldimage WHERE oi_archive_name='" .
- wfStrencode( $oldimage ) . "'";
- wfQuery( $sql, DB_WRITE, $fname );
-
+ $dbw->delete( 'oldimage', array( 'oi_archive_name' => $oldimage ) );
$deleted = $oldimage;
} else {
$this->doDeleteArticle( $reason ); # ignore errors
@@ -276,8 +272,10 @@ class ImagePage extends Article {
return;
}
$oldver = wfTimestampNow() . "!{$name}";
- $size = wfGetSQL( "oldimage", "oi_size", "oi_archive_name='" .
- wfStrencode( $oldimage ) . "'" );
+
+ $dbr =& wfGetDB( DB_READ );
+ $size = $dbr->getField( "oldimage", "oi_size", "oi_archive_name='" .
+ $dbr->strencode( $oldimage ) . "'" );
if ( ! rename( $curfile, "${archive}/{$oldver}" ) ) {
$wgOut->fileRenameError( $curfile, "${archive}/{$oldver}" );
diff --git a/includes/LinkCache.php b/includes/LinkCache.php
index cd0c0879e4e8..8dcba6f55c16 100644
--- a/includes/LinkCache.php
+++ b/includes/LinkCache.php
@@ -131,15 +131,10 @@ class LinkCache {
if( $wgLinkCacheMemcached )
$id = $wgMemc->get( $key = $this->getKey( $title ) );
if( ! is_integer( $id ) ) {
- $sql = "SELECT cur_id FROM cur WHERE cur_namespace=" .
- "{$ns} AND cur_title='" . wfStrencode( $t ) . "'";
- $res = wfQuery( $sql, DB_READ, "LinkCache::addLink" );
-
- if ( 0 == wfNumRows( $res ) ) {
+ $dbr =& wfGetDB( DB_READ );
+ $id = $dbr->getField( 'cur', 'cur_id', array( 'cur_namespace' => $ns, 'cur_title' => $t ), $fname );
+ if ( !$id ) {
$id = 0;
- } else {
- $s = wfFetchObject( $res );
- $id = $s->cur_id;
}
if( $wgLinkCacheMemcached )
$wgMemc->add( $key, $id, 3600*24 );
@@ -176,20 +171,21 @@ class LinkCache {
}
}
+ $dbr =& wfGetDB( DB_READ );
+ $cur = $dbr->tableName( 'cur' );
+ $links = $dbr->tableName( 'links' );
+
$sql = "SELECT cur_id,cur_namespace,cur_title
- FROM cur,links
+ FROM $cur,$links
WHERE cur_id=l_to AND l_from=$id";
- $res = wfQuery( $sql, DB_READ, $fname );
- while( $s = wfFetchObject( $res ) ) {
+ $res = $dbr->query( $sql, $fname );
+ while( $s = $dbr->fetchObject( $res ) ) {
$this->addGoodLink( $s->cur_id,
Title::makeName( $s->cur_namespace, $s->cur_title )
);
}
- $sql = "SELECT bl_to
- FROM brokenlinks
- WHERE bl_from='{$id}'";
- $res = wfQuery( $sql, DB_READ, "LinkCache::preFill" );
+ $res = $dbr->select( 'brokenlinks', array( 'bl_to' ), array( 'bl_from' => $id ), $fname );
while( $s = wfFetchObject( $res ) ) {
$this->addBadLink( $s->bl_to );
}
@@ -276,18 +272,18 @@ class LinkCache {
/* private */ function fillFromLinkscc( $id ){
$id = IntVal( $id );
- $res = wfQuery("SELECT lcc_cacheobj FROM linkscc WHERE lcc_pageid = $id",
- DB_READ);
- $row = wfFetchObject( $res );
- if( $row == FALSE)
- return false;
-
+ $dbr =& wfGetDB( DB_READ );
+ $raw = $dbr->getField( 'linkscc', 'lcc_cacheobj', array( 'lcc_pageid' => $id ) );
+ if ( $raw === false ) {
+ return false;
+ }
+
$cacheobj = false;
if( function_exists( "gzuncompress" ) )
- $cacheobj = @gzuncompress( $row->lcc_cacheobj );
+ $cacheobj = @gzuncompress( $raw );
if($cacheobj == FALSE){
- $cacheobj = $row->lcc_cacheobj;
+ $cacheobj = $raw;
}
$cc = @unserialize( $cacheobj );
if( isset( $cc->mClassVer ) and ($cc->mClassVer == $this->mClassVer ) ){
@@ -302,51 +298,41 @@ class LinkCache {
}
/* private */ function saveToLinkscc( $pid ){
- global $wgCompressedPersistentLC, $wgIsMySQL;
+ global $wgCompressedPersistentLC;
if( $wgCompressedPersistentLC and function_exists( "gzcompress" ) ) {
- $ser = wfStrencode( gzcompress( serialize( $this ), 3 ));
+ $ser = gzcompress( serialize( $this ), 3 );
} else {
- $ser = wfStrencode( serialize( $this ) );
- }
- if ($wgIsMySQL) {
- wfQuery("REPLACE INTO linkscc(lcc_pageid,lcc_cacheobj) " .
- "VALUES({$pid}, '{$ser}')", DB_WRITE);
- } else {
- wfQuery("DELETE FROM linkscc WHERE lcc_pageid={$pid}",DB_WRITE);
- wfQuery("INSERT INTO linkscc(lcc_pageid,lcc_cacheobj) " .
- "VALUES({$pid}, '{$ser}')", DB_WRITE);
+ $ser = serialize( $this );
}
+ $db =& wfGetDB( DB_WRITE );
+ $db->replace( 'linkscc', array( 'lcc_pageid' ), array( 'lcc_pageid' => $pid, 'lcc_cacheobj' => $ser ) );
}
+ # Delete linkscc rows which link to here
# $pid is a page id
/* static */ function linksccClearLinksTo( $pid ){
- global $wgEnablePersistentLC, $wgIsMySQL;
+ global $wgEnablePersistentLC;
if ( $wgEnablePersistentLC ) {
+ $fname = "LinkCache::linksccClearLinksTo";
$pid = intval( $pid );
- if ($wgIsMySQL) {
- wfQuery("DELETE linkscc FROM linkscc,links ".
- "WHERE lcc_pageid=links.l_from AND l_to={$pid}", DB_WRITE);
- } else {
- wfQuery("DELETE FROM linkscc WHERE lcc_pageid IN ".
- "(SELECT l_from FROM links WHERE l_to={$pid})", DB_WRITE);
- }
- wfQuery("DELETE FROM linkscc WHERE lcc_pageid='{$pid}'", DB_WRITE);
+ $dbw =& wfGetDB( DB_WRITE );
+ # 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
+ $dbw->delete( 'linkscc', array( 'lcc_pageid' => $pid ), $fname);
}
+
}
+ # Delete linkscc rows with broken links to here
# $title is a prefixed db title, for example like Title->getPrefixedDBkey() returns.
/* static */ function linksccClearBrokenLinksTo( $title ){
- global $wgEnablePersistentLC,$wgIsMySQL;
+ global $wgEnablePersistentLC;
+ $fname = 'LinkCache::linksccClearBrokenLinksTo';
+
if ( $wgEnablePersistentLC ) {
- $title = wfStrencode( $title );
- if ($wgIsMySQL) {
- wfQuery("DELETE linkscc FROM linkscc,brokenlinks ".
- "WHERE lcc_pageid=bl_from AND bl_to='{$title}'", DB_WRITE);
- } else {
- wfQuery("DELETE FROM linkscc WHERE lcc_pageid IN ".
- "(SELECT bl_from FROM brokenlinks ".
- "WHERE bl_to='{$title}')",DB_WRITE);
- }
+ $dbw =& wfGetDB( DB_WRITE );
+ $dbw->deleteJoin( 'linkscc', 'brokenlinks', 'lcc_pageid', 'bl_from', array( 'bl_to' => $title ), $fname );
}
}
@@ -355,7 +341,8 @@ class LinkCache {
global $wgEnablePersistentLC;
if ( $wgEnablePersistentLC ) {
$pid = intval( $pid );
- wfQuery("DELETE FROM linkscc WHERE lcc_pageid='{$pid}'", DB_WRITE);
+ $dbw =& wfGetDB( DB_WRITE );
+ $dbw->delete( 'linkscc', array( 'lcc_pageid' => $pid ) );
}
}
}
diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php
index da4f47cf5c30..64b9aafced24 100644
--- a/includes/LinksUpdate.php
+++ b/includes/LinksUpdate.php
@@ -9,7 +9,6 @@ class LinksUpdate {
{
$this->mId = $id;
$this->mTitle = $title;
- $this->mTitleEnc = wfStrencode( $title );
}
@@ -27,10 +26,11 @@ class LinksUpdate {
$del = array();
$add = array();
- if( $wgDBtransactions ) {
- $sql = "BEGIN";
- wfQuery( $sql, DB_WRITE, $fname );
- }
+ $dbw =& wfGetDB( DB_WRITE );
+ $links = $dbw->tableName( 'links' );
+ $brokenlinks = $dbw->tableName( 'brokenlinks' );
+ $imagelinks = $dbw->tableName( 'imagelinks' );
+ $categorylinks = $dbw->tableName( 'categorylinks' );
#------------------------------------------------------------------------------
# Good links
@@ -38,15 +38,14 @@ class LinksUpdate {
if ( $wgLinkCache->incrementalSetup( LINKCACHE_GOOD, $del, $add ) ) {
# Delete where necessary
if ( count( $del ) ) {
- $sql = "DELETE FROM links WHERE l_from={$this->mId} AND l_to IN(".
+ $sql = "DELETE FROM $links WHERE l_from={$this->mId} AND l_to IN(".
implode( ",", $del ) . ")";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->query( $sql, $fname );
}
} else {
# Delete everything
- $sql = "DELETE FROM links WHERE l_from={$this->mId}";
- wfQuery( $sql, DB_WRITE, $fname );
-
+ $dbw->delete( 'links', array( 'l_from' => $this->mId ), $fname );
+
# Get the addition list
$add = $wgLinkCache->getGoodLinks();
}
@@ -57,10 +56,9 @@ class LinksUpdate {
# The link cache was constructed without FOR UPDATE, so there may be collisions
# Ignoring for now, I'm not sure if that causes problems or not, but I'm fairly
# sure it's better than without IGNORE
- $sql = "INSERT IGNORE INTO links (l_from,l_to) VALUES ";
+ $sql = "INSERT IGNORE INTO $links (l_from,l_to) VALUES ";
$first = true;
foreach( $add as $lt => $lid ) {
-
if ( ! $first ) { $sql .= ","; }
$first = false;
@@ -68,7 +66,7 @@ class LinksUpdate {
}
}
if ( "" != $sql ) {
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->query( $sql, $fname );
}
#------------------------------------------------------------------------------
@@ -77,14 +75,21 @@ class LinksUpdate {
if ( $wgLinkCache->incrementalSetup( LINKCACHE_BAD, $del, $add ) ) {
# Delete where necessary
if ( count( $del ) ) {
- $sql = "DELETE FROM brokenlinks WHERE bl_from={$this->mId} AND bl_to IN('" .
- implode( "','", array_map( "wfStrencode", $del ) ) . "')";
- wfQuery( $sql, DB_WRITE, $fname );
+ $sql = "DELETE FROM $brokenlinks WHERE bl_from={$this->mId} AND bl_to IN(";
+ $first = true;
+ foreach( $del as $badTitle ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",";
+ }
+ $sql .= $dbw->addQuotes( $badTitle );
+ }
+ $dbw->query( $sql, $fname );
}
} else {
# Delete all
- $sql = "DELETE FROM brokenlinks WHERE bl_from={$this->mId}";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->delete( 'brokenlinks', array( 'bl_from' => $this->mId ) );
# Get addition list
$add = $wgLinkCache->getBadLinks();
@@ -93,10 +98,10 @@ class LinksUpdate {
# Do additions
$sql = "";
if ( 0 != count ( $add ) ) {
- $sql = "INSERT IGNORE INTO brokenlinks (bl_from,bl_to) VALUES ";
+ $sql = "INSERT IGNORE INTO $brokenlinks (bl_from,bl_to) VALUES ";
$first = true;
foreach( $add as $blt ) {
- $blt = wfStrencode( $blt );
+ $blt = $dbw->strencode( $blt );
if ( ! $first ) { $sql .= ","; }
$first = false;
@@ -104,13 +109,13 @@ class LinksUpdate {
}
}
if ( "" != $sql ) {
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->query( $sql, $fname );
}
#------------------------------------------------------------------------------
# Image links
- $sql = "DELETE FROM imagelinks WHERE il_from='{$this->mId}'";
- wfQuery( $sql, DB_WRITE, $fname );
+ $sql = "DELETE FROM $imagelinks WHERE il_from='{$this->mId}'";
+ $dbw->query( $sql, $fname );
# Get addition list
$add = $wgLinkCache->getImageLinks();
@@ -119,7 +124,7 @@ class LinksUpdate {
$sql = "";
$image = Namespace::getImage();
if ( 0 != count ( $add ) ) {
- $sql = "INSERT IGNORE INTO imagelinks (il_from,il_to) VALUES ";
+ $sql = "INSERT IGNORE INTO $imagelinks (il_from,il_to) VALUES ";
$first = true;
foreach( $add as $iname => $val ) {
# FIXME: Change all this to avoid unnecessary duplication
@@ -127,20 +132,22 @@ class LinksUpdate {
if( !$nt ) continue;
$nt->invalidateCache();
- $iname = wfStrencode( $iname );
+ $iname = $dbw->strencode( $iname );
if ( ! $first ) { $sql .= ","; }
$first = false;
$sql .= "({$this->mId},'{$iname}')";
}
}
- if ( "" != $sql ) { wfQuery( $sql, DB_WRITE, $fname ); }
+ if ( "" != $sql ) {
+ $dbw->query( $sql, $fname );
+ }
#------------------------------------------------------------------------------
# Category links
if( $wgUseCategoryMagic ) {
- $sql = "DELETE FROM categorylinks WHERE cl_from='{$this->mId}'";
- wfQuery( $sql, DB_WRITE, $fname );
+ $sql = "DELETE FROM $categorylinks WHERE cl_from='{$this->mId}'";
+ $dbw->query( $sql, $fname );
# Get addition list
$add = $wgLinkCache->getCategoryLinks();
@@ -148,7 +155,7 @@ class LinksUpdate {
# Do the insertion
$sql = "";
if ( 0 != count ( $add ) ) {
- $sql = "INSERT IGNORE INTO categorylinks (cl_from,cl_to,cl_sortkey) VALUES ";
+ $sql = "INSERT IGNORE INTO $categorylinks (cl_from,cl_to,cl_sortkey) VALUES ";
$first = true;
foreach( $add as $cname => $sortkey ) {
# FIXME: Change all this to avoid unnecessary duplication
@@ -159,19 +166,17 @@ class LinksUpdate {
if ( ! $first ) { $sql .= ","; }
$first = false;
- $sql .= "({$this->mId},'" . wfStrencode( $cname ) .
- "','" . wfStrencode( $sortkey ) . "')";
+ $sql .= "({$this->mId},'" . $dbw->strencode( $cname ) .
+ "','" . $dbw->strencode( $sortkey ) . "')";
}
}
- if ( "" != $sql ) { wfQuery( $sql, DB_WRITE, $fname ); }
+ if ( "" != $sql ) {
+ $dbw->query( $sql, $fname );
+ }
}
$this->fixBrokenLinks();
- if( $wgDBtransactions ) {
- $sql = "COMMIT";
- wfQuery( $sql, DB_WRITE, $fname );
- }
wfProfileOut( $fname );
}
@@ -179,23 +184,24 @@ class LinksUpdate {
{
# Old inefficient update function
# Used for rebuilding the link table
-
global $wgLinkCache, $wgDBtransactions, $wgUseCategoryMagic;
$fname = "LinksUpdate::doDumbUpdate";
wfProfileIn( $fname );
-
- if( $wgDBtransactions ) {
- $sql = "BEGIN";
- wfQuery( $sql, DB_WRITE, $fname );
- }
- $sql = "DELETE FROM links WHERE l_from={$this->mId}";
- wfQuery( $sql, DB_WRITE, $fname );
+
+ $dbw =& wfGetDB( DB_WRITE );
+ $links = $dbw->tableName( 'links' );
+ $brokenlinks = $dbw->tableName( 'brokenlinks' );
+ $imagelinks = $dbw->tableName( 'imagelinks' );
+ $categorylinks = $dbw->tableName( 'categorylinks' );
+
+ $sql = "DELETE FROM $links WHERE l_from={$this->mId}";
+ $dbw->query( $sql, $fname );
$a = $wgLinkCache->getGoodLinks();
$sql = "";
if ( 0 != count( $a ) ) {
- $sql = "INSERT IGNORE INTO links (l_from,l_to) VALUES ";
+ $sql = "INSERT IGNORE INTO $links (l_from,l_to) VALUES ";
$first = true;
foreach( $a as $lt => $lid ) {
if ( ! $first ) { $sql .= ","; }
@@ -204,47 +210,53 @@ class LinksUpdate {
$sql .= "({$this->mId},{$lid})";
}
}
- if ( "" != $sql ) { wfQuery( $sql, DB_WRITE, $fname ); }
+ if ( "" != $sql ) {
+ $dbw->query( $sql, $fname );
+ }
- $sql = "DELETE FROM brokenlinks WHERE bl_from={$this->mId}";
- wfQuery( $sql, DB_WRITE, $fname );
+ $sql = "DELETE FROM $brokenlinks WHERE bl_from={$this->mId}";
+ $dbw->query( $sql, $fname );
$a = $wgLinkCache->getBadLinks();
$sql = "";
if ( 0 != count ( $a ) ) {
- $sql = "INSERT IGNORE INTO brokenlinks (bl_from,bl_to) VALUES ";
+ $sql = "INSERT IGNORE INTO $brokenlinks (bl_from,bl_to) VALUES ";
$first = true;
foreach( $a as $blt ) {
- $blt = wfStrencode( $blt );
+ $blt = $dbw->strencode( $blt );
if ( ! $first ) { $sql .= ","; }
$first = false;
$sql .= "({$this->mId},'{$blt}')";
}
}
- if ( "" != $sql ) { wfQuery( $sql, DB_WRITE, $fname ); }
+ if ( "" != $sql ) {
+ $dbw->query( $sql, $fname );
+ }
- $sql = "DELETE FROM imagelinks WHERE il_from={$this->mId}";
- wfQuery( $sql, DB_WRITE, $fname );
+ $sql = "DELETE FROM $imagelinks WHERE il_from={$this->mId}";
+ $dbw->query( $sql, $fname );
$a = $wgLinkCache->getImageLinks();
$sql = "";
if ( 0 != count ( $a ) ) {
- $sql = "INSERT IGNORE INTO imagelinks (il_from,il_to) VALUES ";
+ $sql = "INSERT IGNORE INTO $imagelinks (il_from,il_to) VALUES ";
$first = true;
foreach( $a as $iname => $val ) {
- $iname = wfStrencode( $iname );
+ $iname = $dbw->strencode( $iname );
if ( ! $first ) { $sql .= ","; }
$first = false;
$sql .= "({$this->mId},'{$iname}')";
}
}
- if ( "" != $sql ) { wfQuery( $sql, DB_WRITE, $fname ); }
+ if ( "" != $sql ) {
+ $dbw->query( $sql, $fname );
+ }
if( $wgUseCategoryMagic ) {
- $sql = "DELETE FROM categorylinks WHERE cl_from='{$this->mId}'";
- wfQuery( $sql, DB_WRITE, $fname );
+ $sql = "DELETE FROM $categorylinks WHERE cl_from='{$this->mId}'";
+ $dbw->query( $sql, $fname );
# Get addition list
$add = $wgLinkCache->getCategoryLinks();
@@ -252,7 +264,7 @@ class LinksUpdate {
# Do the insertion
$sql = "";
if ( 0 != count ( $add ) ) {
- $sql = "INSERT IGNORE INTO categorylinks (cl_from,cl_to,cl_sortkey) VALUES ";
+ $sql = "INSERT IGNORE INTO $categorylinks (cl_from,cl_to,cl_sortkey) VALUES ";
$first = true;
foreach( $add as $cname => $sortkey ) {
# FIXME: Change all this to avoid unnecessary duplication
@@ -263,18 +275,15 @@ class LinksUpdate {
if ( ! $first ) { $sql .= ","; }
$first = false;
- $sql .= "({$this->mId},'" . wfStrencode( $cname ) .
- "','" . wfStrencode( $sortkey ) . "')";
+ $sql .= "({$this->mId},'" . $dbw->strencode( $cname ) .
+ "','" . $dbw->strencode( $sortkey ) . "')";
}
}
- if ( "" != $sql ) { wfQuery( $sql, DB_WRITE, $fname ); }
+ if ( "" != $sql ) {
+ $dbw->query( $sql, $fname );
+ }
}
$this->fixBrokenLinks();
-
- if( $wgDBtransactions ) {
- $sql = "COMMIT";
- wfQuery( $sql, DB_WRITE, $fname );
- }
wfProfileOut( $fname );
}
@@ -282,18 +291,22 @@ class LinksUpdate {
/* Update any brokenlinks *to* this page */
/* Call for a newly created page, or just to make sure state is consistent */
$fname = "LinksUpdate::fixBrokenLinks";
+
+ $dbw =& wfGetDB( DB_WRITE );
+ $cur = $dbw->tableName( 'cur' );
+ $links = $dbw->tableName( 'links' );
- $sql = "SELECT bl_from FROM brokenlinks WHERE bl_to='{$this->mTitleEnc}'";
- $res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) { return; }
+ $res = $dbw->select( 'brokenlinks', array( 'bl_from' ), array( 'bl_to' => $this->mTitle ),
+ $fname, 'FOR UPDATE' );
+ if ( 0 == $dbw->numRows( $res ) ) { return; }
# Ignore errors. If a link existed in both the brokenlinks table and the links
# table, that's an error which can be fixed at this stage by simply ignoring collisions
- $sql = "INSERT IGNORE INTO links (l_from,l_to) VALUES ";
+ $sql = "INSERT IGNORE INTO $links (l_from,l_to) VALUES ";
$now = wfTimestampNow();
- $sql2 = "UPDATE cur SET cur_touched='{$now}' WHERE cur_id IN (";
+ $sql2 = "UPDATE $cur SET cur_touched='{$now}' WHERE cur_id IN (";
$first = true;
- while ( $row = wfFetchObject( $res ) ) {
+ while ( $row = $dbw->fetchObject( $res ) ) {
if ( ! $first ) { $sql .= ","; $sql2 .= ","; }
$first = false;
@@ -301,13 +314,11 @@ class LinksUpdate {
$sql2 .= $row->bl_from;
}
$sql2 .= ")";
- wfQuery( $sql, DB_WRITE, $fname );
- wfQuery( $sql2, DB_WRITE, $fname );
+ $dbw->query( $sql, $fname );
+ $dbw->query( $sql2, $fname );
- $sql = "DELETE FROM brokenlinks WHERE bl_to='{$this->mTitleEnc}'";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->delete( 'brokenlinks', array( 'bl_to' => $this->mTitle ), $fname );
}
-
}
?>
diff --git a/includes/LoadBalancer.php b/includes/LoadBalancer.php
index 94f4f55cff0d..cfc389475be5 100644
--- a/includes/LoadBalancer.php
+++ b/includes/LoadBalancer.php
@@ -1,6 +1,8 @@
<?php
# Database load balancing object
+require_once( "Database.php" );
+
# Valid database indexes
# Operation-based indexes
define( "DB_READ", -1 ); # Read from the slave (or only server)
@@ -20,43 +22,41 @@ define( "DB_TASK_LAST", 1004) ; # Last in list
class LoadBalancer {
/* private */ var $mServers, $mConnections, $mLoads;
- /* private */ var $mUser, $mPassword, $mDbName, $mFailFunction;
+ /* private */ var $mFailFunction;
/* private */ var $mForce, $mReadIndex, $mLastConn;
function LoadBalancer()
{
$this->mServers = array();
- $this->mLoads = array();
$this->mConnections = array();
- $this->mUser = false;
- $this->mPassword = false;
- $this->mDbName = false;
$this->mFailFunction = false;
$this->mReadIndex = -1;
$this->mForce = -1;
$this->mLastConn = false;
}
- function newFromParams( $servers, $loads, $user, $password, $dbName, $failFunction = false )
+ function newFromParams( $servers, $failFunction = false )
{
$lb = new LoadBalancer;
- $lb->initialise( $servers, $loads, $user, $password, $dbName, $failFunction = false );
+ $lb->initialise( $servers, $failFunction = false );
return $lb;
}
- function initialise( $servers, $loads, $user, $password, $dbName, $failFunction = false )
+ function initialise( $servers, $failFunction = false )
{
$this->mServers = $servers;
- $this->mLoads = $loads;
- $this->mUser = $user;
- $this->mPassword = $password;
- $this->mDbName = $dbName;
$this->mFailFunction = $failFunction;
$this->mReadIndex = -1;
$this->mWriteIndex = -1;
$this->mForce = -1;
$this->mConnections = array();
$this->mLastConn = false;
+ $this->mLoads = array();
+
+ foreach( $servers as $i => $server ) {
+ $this->mLoads[$i] = $server['load'];
+ }
+
wfSeedRandom();
}
@@ -99,7 +99,7 @@ class LoadBalancer {
do {
$i = $this->pickRandom( $loads );
if ( $i !== false ) {
- wfDebug( "Using reader #$i: {$this->mServers[$i]}\n" );
+ wfDebug( "Using reader #$i: {$this->mServers[$i]['host']}\n" );
$conn =& $this->getConnection( $i );
if ( !$conn->isOpen() ) {
@@ -148,11 +148,10 @@ class LoadBalancer {
} else {
# Explicit index
if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) {
- $this->mConnections[$i] = Database::newFromParams( $this->mServers[$i], $this->mUser,
- $this->mPassword, $this->mDbName, 1 );
+ $this->mConnections[$i] = $this->makeConnection( $this->mServers[$i] );
}
if ( !$this->mConnections[$i]->isOpen() ) {
- wfDebug( "Failed to connect to database $i at {$this->mServers[$i]}\n" );
+ wfDebug( "Failed to connect to database $i at {$this->mServers[$i]['host']}\n" );
if ( $fail ) {
$this->reportConnectionError( $this->mConnections[$i] );
}
@@ -163,6 +162,18 @@ class LoadBalancer {
return $this->mLastConn;
}
+ /* private */ function makeConnection( &$server ) {
+ extract( $server );
+ # Get class for this database type
+ $class = 'Database' . ucfirst( $type );
+ if ( !class_exists( $class ) ) {
+ require_once( "$class.php" );
+ }
+
+ # Create object
+ return new $class( $host, $user, $password, $dbname, 1 );
+ }
+
function reportConnectionError( &$conn )
{
if ( !is_object( $conn ) ) {
diff --git a/includes/LogPage.php b/includes/LogPage.php
index 6be15fed9bd0..31f598c7a532 100644
--- a/includes/LogPage.php
+++ b/includes/LogPage.php
@@ -18,13 +18,16 @@ class LogPage {
function getContent( $defaulttext = "<ul>\n</ul>" )
{
- $sql = "SELECT cur_id,cur_text,cur_timestamp FROM cur " .
- "WHERE cur_namespace=" . Namespace::getWikipedia() . " AND " .
- "cur_title='" . wfStrencode($this->mTitle ) . "'";
- $res = wfQuery( $sql, DB_READ, "LogPage::getContent" );
+ $fname = 'LogPage::getContent';
- if( wfNumRows( $res ) > 0 ) {
- $s = wfFetchObject( $res );
+ $dbw =& wfGetDB( DB_WRITE );
+ $s = $dbw->getArray( 'cur',
+ array( 'cur_id','cur_text','cur_timestamp' ),
+ array( 'cur_namespace' => Namespace::getWikipedia(), 'cur_title' => $this->mTitle ),
+ $fname, 'FOR UPDATE'
+ );
+
+ if( $s !== false ) {
$this->mId = $s->cur_id;
$this->mContent = $s->cur_text;
$this->mTimestamp = $s->cur_timestamp;
@@ -52,31 +55,49 @@ class LogPage {
global $wgUser;
$fname = "LogPage::saveContent";
+
+ $dbw =& wfGetDB( DB_WRITE );
$uid = $wgUser->getID();
- $ut = wfStrencode( $wgUser->getName() );
if( !$this->mContentLoaded ) return false;
$this->mTimestamp = $now = wfTimestampNow();
$won = wfInvertTimestamp( $now );
if($this->mId == 0) {
- $sql = "INSERT INTO cur (cur_timestamp,cur_user,cur_user_text,
- cur_namespace,cur_title,cur_text,cur_comment,cur_restrictions,
- inverse_timestamp,cur_touched)
- VALUES ('{$now}', {$uid}, '{$ut}', " .
- Namespace::getWikipedia() . ", '" .
- wfStrencode( $this->mTitle ) . "', '" .
- wfStrencode( $this->mContent ) . "', '" .
- wfStrencode( $this->mComment ) . "', 'sysop', '{$won}','{$now}')";
- wfQuery( $sql, DB_WRITE, $fname );
- $this->mId = wfInsertId();
+ $seqVal = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
+
+ # Note: this query will deadlock if another thread has called getContent(),
+ # at least in MySQL 4.0.17 InnoDB
+ $dbw->insertArray( 'cur',
+ array(
+ 'cur_id' => $seqVal,
+ 'cur_timestamp' => $now,
+ 'cur_user' => $uid,
+ 'cur_user_text' => $wgUser->getName(),
+ 'cur_namespace' => NS_WIKIPEDIA,
+ 'cur_title' => $this->mTitle,
+ 'cur_text' => $this->mContent,
+ 'cur_comment' => $this->mComment,
+ 'cur_restrictions' => 'sysop',
+ 'inverse_timestamp' => $won,
+ 'cur_touched' => $now,
+ ), $fname
+ );
+ $this->mId = $dbw->insertId();
} else {
- $sql = "UPDATE cur SET cur_timestamp='{$now}', " .
- "cur_user={$uid}, cur_user_text='{$ut}', " .
- "cur_text='" . wfStrencode( $this->mContent ) . "', " .
- "cur_comment='" . wfStrencode( $this->mComment ) . "', " .
- "cur_restrictions='sysop', inverse_timestamp='{$won}', cur_touched='{$now}' " .
- "WHERE cur_id={$this->mId}";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->updateArray( 'cur',
+ array( /* SET */
+ 'cur_timestamp' => $now,
+ 'cur_user' => $uid,
+ 'cur_user_text' => $wgUser->getName(),
+ 'cur_text' => $this->mContent,
+ 'cur_comment' => $this->mComment,
+ 'cur_restrictions' => 'sysop',
+ 'inverse_timestamp' => $won,
+ 'cur_touched' => $now,
+ ), array( /* WHERE */
+ 'cur_id' => $this->mId
+ ), $fname
+ );
}
# And update recentchanges
diff --git a/includes/Math.php b/includes/Math.php
index 8b03af6adcbb..827c1167df91 100644
--- a/includes/Math.php
+++ b/includes/Math.php
@@ -54,10 +54,10 @@ class MathRenderer {
return $this->_error( "math_notexvc" );
}
$cmd = $wgTexvc." ".
- escapeshellarg($wgTmpDirectory)." ".
- escapeshellarg($wgMathDirectory)." ".
- escapeshellarg($this->tex)." ".
- escapeshellarg($wgInputEncoding);
+ wfEscapeShellArg($wgTmpDirectory)." ".
+ wfEscapeShellArg($wgMathDirectory)." ".
+ wfEscapeShellArg($this->tex)." ".
+ wfEscapeShellArg($wgInputEncoding);
wfDebug( "TeX: $cmd" );
$contents = `$cmd`;
@@ -79,9 +79,6 @@ class MathRenderer {
$this->html = substr($outdata, 0, $i);
$this->mathml = substr($outdata, $i+1);
-
- $sql_html = "'".wfStrencode($this->html)."'";
- $sql_mathml = "'".wfStrencode($this->mathml)."'";
} else if (($retval == "c") || ($retval == "m") || ($retval == "l")) {
$this->html = substr ($contents, 33);
if ($retval == "c")
@@ -90,20 +87,14 @@ class MathRenderer {
$this->conservativeness = 1;
else
$this->conservativeness = 0;
- $sql_html = "'".wfStrencode($this->html)."'";
- $this->mathml = '';
- $sql_mathml = 'NULL';
+ $this->mathml = NULL;
} else if ($retval == "X") {
- $outhtml = '';
+ $outhtml = NULL;
$this->mathml = substr ($contents, 33);
- $sql_html = 'NULL';
- $sql_mathml = "'".wfStrencode($this->mathml)."'";
$this->conservativeness = 0;
} else if ($retval == "+") {
- $this->outhtml = '';
- $this->mathml = '';
- $sql_html = 'NULL';
- $sql_mathml = 'NULL';
+ $this->outhtml = NULL;
+ $this->mathml = NULL;
$this->conservativeness = 0;
} else {
$errbit = htmlspecialchars( substr($contents, 1) );
@@ -125,13 +116,21 @@ class MathRenderer {
}
# Now save it back to the DB:
- $outmd5_sql = wfStrencode(pack("H32", $this->hash));
+ $outmd5_sql = pack("H32", $this->hash);
- $md5_sql = wfStrencode( pack("H32", $this->md5) ); # Binary packed, not hex
- $sql = "REPLACE INTO math VALUES ('".$md5_sql."', '".$outmd5_sql."', ".$this->conservativeness.", ".$sql_html.", ".$sql_mathml.")";
+ $md5_sql = pack("H32", $this->md5); # Binary packed, not hex
+
+ $dbw =& wfGetDB( DB_WRITE );
+ $dbw->replace( 'math', array( 'math_inputhash' ),
+ array(
+ 'math_inputhash' => $md5_sql,
+ 'math_outputhash' => $outmd5_sql,
+ 'math_html_conservativeness' => $this->conservativeness,
+ 'math_html' => $outhtml,
+ 'math_mathml' => $mathml,
+ ), $fname, array( 'IGNORE' )
+ );
- $res = wfQuery( $sql, DB_WRITE, "MathRenderer::render" );
- # we don't really care if it fails
}
return $this->_doRender();
@@ -147,14 +146,17 @@ class MathRenderer {
function _recall() {
global $wgMathDirectory;
-
+ $fname = 'MathRenderer::_recall';
+
$this->md5 = md5( $this->tex );
-
- $md5_sql = wfStrencode( pack("H32", $this->md5) ); # Binary packed, not hex
- $sql = "SELECT math_outputhash,math_html_conservativeness,math_html,math_mathml FROM math WHERE math_inputhash = '$md5_sql'";
- $res = wfQuery( $sql, DB_READ, "MathRenderer::_recall" );
-
- if( $rpage = wfFetchObject ( $res ) ) {
+ $dbr =& wfGetDB( DB_READ );
+ $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
+ $fname
+ );
+
+ if( $rpage !== false ) {
# Tailing 0x20s can get dropped by the database, add it back on if necessary:
$xhash = unpack( "H32md5", $rpage->math_outputhash . " " );
$this->hash = $xhash ['md5'];
diff --git a/includes/MessageCache.php b/includes/MessageCache.php
index 9462a520ac61..a6f00f5f910e 100755
--- a/includes/MessageCache.php
+++ b/includes/MessageCache.php
@@ -37,6 +37,7 @@ class MessageCache
global $wgAllMessagesEn;
if ( $this->mDisable ) {
+ wfDebug( "MessageCache::load(): disabled\n" );
return true;
}
@@ -47,6 +48,7 @@ class MessageCache
# If there's nothing in memcached, load all the messages from the database
if ( !$this->mCache ) {
+ 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 );
@@ -64,6 +66,7 @@ class MessageCache
}
if ( !is_array( $this->mCache ) ) {
+ wfMsg( "MessageCache::load(): individual message mode\n" );
# If it is 'loading' or 'error', switch to individual message mode, otherwise disable
# Causing too much DB load, disabling -- TS
$this->mDisable = true;
@@ -86,18 +89,20 @@ class MessageCache
# Loads all cacheable messages from the database
function loadFromDB()
{
- global $wgLoadBalancer;
$fname = "MessageCache::loadFromDB";
- $wgLoadBalancer->force(-1);
- $sql = "SELECT cur_title,cur_text FROM cur WHERE cur_is_redirect=0 AND cur_namespace=" . NS_MEDIAWIKI;
- $res = wfQuery( $sql, DB_READ, $fname );
- $wgLoadBalancer->force(0);
+ $dbr =& wfGetDB( DB_READ );
+ $res = $dbr->select( 'cur',
+ array( 'cur_title', 'cur_text' ),
+ array( 'cur_is_redirect' => 0, 'cur_namespace' => NS_MEDIAWIKI ),
+ $fname
+ );
+
$this->mCache = array();
- for ( $row = wfFetchObject( $res ); $row; $row = wfFetchObject( $res ) ) {
+ for ( $row = $dbr->fetchObject( $res ); $row; $row = $dbr->fetchObject( $res ) ) {
$this->mCache[$row->cur_title] = $row->cur_text;
}
- wfFreeResult( $res );
+ $dbr->freeResult( $res );
}
# Not really needed anymore
@@ -176,7 +181,8 @@ class MessageCache
# If it wasn't in the cache, load each message from the DB individually
if ( !$message && $useDB) {
- $result = wfGetArray( "cur", array("cur_text"),
+ $dbr =& wfGetDB( DB_READ );
+ $result = $dbr->getArray( "cur", array("cur_text"),
array( "cur_namespace" => NS_MEDIAWIKI, "cur_title" => $title ),
"MessageCache::get" );
if ( $result ) {
diff --git a/includes/ObjectCache.php b/includes/ObjectCache.php
index ce511ff37b10..5bcfde777fde 100644
--- a/includes/ObjectCache.php
+++ b/includes/ObjectCache.php
@@ -285,16 +285,20 @@ class /* abstract */ SqlBagOStuff extends BagOStuff {
class MediaWikiBagOStuff extends SqlBagOStuff {
function _doquery($sql) {
- return wfQuery($sql, DB_READ, "MediaWikiBagOStuff:_doquery");
+ $dbw = wfGetDB( DB_WRITE );
+ return $dbw->query($sql, "MediaWikiBagOStuff:_doquery");
}
function _fetchobject($result) {
- return wfFetchObject($result);
+ $dbw = wfGetDB( DB_WRITE );
+ return $dbw->fetchObject($result);
}
function _freeresult($result) {
- return wfFreeResult($result);
+ $dbw = wfGetDB( DB_WRITE );
+ return $dbw->freeResult($result);
}
function _dberror($result) {
- return wfLastError();
+ $dbw = wfGetDB( DB_WRITE );
+ return $dbw->lastError();
}
function _maxdatetime() {
return "9999-12-31 12:59:59";
@@ -303,7 +307,8 @@ class MediaWikiBagOStuff extends SqlBagOStuff {
return gmdate( "Y-m-d H:i:s", $ts );
}
function _strencode($s) {
- return wfStrEncode($s);
+ $dbw = wfGetDB( DB_WRITE );
+ return $dbw->strencode($s);
}
}
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index ac75966b7029..5e17bbf66415 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -307,7 +307,7 @@ class OutputPage {
{
global $wgUser, $wgLang, $wgDebugComments, $wgCookieExpiration;
global $wgInputEncoding, $wgOutputEncoding, $wgLanguageCode;
- global $wgDebugRedirects, $wgMimeType, $wgProfiling;
+ global $wgDebugRedirects, $wgMimeType, $wgProfiler;
if( $this->mDoNothing ){
return;
}
diff --git a/includes/PageHistory.php b/includes/PageHistory.php
index 3eeaa9d419fa..adc47907283c 100644
--- a/includes/PageHistory.php
+++ b/includes/PageHistory.php
@@ -17,7 +17,7 @@ class PageHistory {
function history()
{
- global $wgUser, $wgOut, $wgLang, $wgIsMySQL, $wgIsPg;
+ global $wgUser, $wgOut, $wgLang;
# If page hasn't changed, client can cache this
@@ -54,17 +54,20 @@ class PageHistory {
$namespace = $this->mTitle->getNamespace();
$title = $this->mTitle->getText();
- $use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":"";
- $oldtable=$wgIsPg?'"old"':'old';
+
+ $db =& wfGetDB( DB_READ );
+ $use_index = $db->useIndexClause( 'name_title_timestamp' );
+ $oldtable = $db->tableName( 'old' );
+
$sql = "SELECT old_id,old_user," .
"old_comment,old_user_text,old_timestamp,old_minor_edit ".
"FROM $oldtable $use_index " .
"WHERE old_namespace={$namespace} AND " .
- "old_title='" . wfStrencode( $this->mTitle->getDBkey() ) . "' " .
+ "old_title='" . $db->strencode( $this->mTitle->getDBkey() ) . "' " .
"ORDER BY inverse_timestamp".wfLimitResult($limitplus,$rawoffset);
- $res = wfQuery( $sql, DB_READ, $fname );
+ $res = $db->query( $sql, $fname );
- $revs = wfNumRows( $res );
+ $revs = $db->numRows( $res );
if( $revs < $limitplus ) // the sql above tries to fetch one extra
$this->linesonpage = $revs;
@@ -98,7 +101,7 @@ class PageHistory {
$counter++
);
}
- while ( $line = wfFetchObject( $res ) ) {
+ while ( $line = $db->fetchObject( $res ) ) {
$s .= $this->historyLine(
$line->old_timestamp, $line->old_user,
$line->old_user_text, $namespace,
diff --git a/includes/Parser.php b/includes/Parser.php
index 8a24bf178a89..53a5bcdecc2f 100644
--- a/includes/Parser.php
+++ b/includes/Parser.php
@@ -343,6 +343,8 @@ class Parser
# This method generates the list of subcategories and pages for a category
function oldCategoryMagic () {
global $wgLang , $wgUser ;
+ $fname = 'Parser::oldCategoryMagic';
+
if ( !$this->mOptions->getUseCategoryMagic() ) return ; # Doesn't use categories at all
$cns = Namespace::getCategory() ;
@@ -359,10 +361,15 @@ class Parser
$id = $this->mTitle->getArticleID() ;
# FIXME: add limits
- $t = wfStrencode( $this->mTitle->getDBKey() );
- $sql = "SELECT DISTINCT cur_title,cur_namespace FROM cur,categorylinks WHERE cl_to='$t' AND cl_from=cur_id ORDER BY cl_sortkey" ;
- $res = wfQuery ( $sql, DB_READ ) ;
- while ( $x = wfFetchObject ( $res ) ) $data[] = $x ;
+ $dbr =& wfGetDB( DB_READ );
+ $cur = $dbr->tableName( 'cur' );
+ $categorylinks = $dbr->tableName( 'categorylinks' );
+
+ $t = $dbr->strencode( $this->mTitle->getDBKey() );
+ $sql = "SELECT DISTINCT cur_title,cur_namespace FROM $cur,$categorylinks " .
+ "WHERE cl_to='$t' AND cl_from=cur_id ORDER BY cl_sortkey" ;
+ $res = $dbr->query( $sql, $fname ) ;
+ while ( $x = $dbr->fetchObject ( $res ) ) $data[] = $x ;
# For all pages that link to this category
foreach ( $data AS $x )
@@ -377,7 +384,7 @@ class Parser
array_push ( $articles , $sk->makeLink ( $t ) ) ; # Page in this category
}
}
- wfFreeResult ( $res ) ;
+ $dbr->freeResult ( $res ) ;
# Showing subcategories
if ( count ( $children ) > 0 ) {
@@ -393,7 +400,6 @@ class Parser
$r .= implode ( ', ' , $articles ) ;
}
-
return $r ;
}
@@ -419,12 +425,15 @@ class Parser
$id = $this->mTitle->getArticleID() ;
# FIXME: add limits
- $t = wfStrencode( $this->mTitle->getDBKey() );
- $sql = "SELECT DISTINCT cur_title,cur_namespace,cl_sortkey FROM
-cur,categorylinks WHERE cl_to='$t' AND cl_from=cur_id ORDER BY
-cl_sortkey" ;
- $res = wfQuery ( $sql, DB_READ ) ;
- while ( $x = wfFetchObject ( $res ) )
+ $dbr =& wfGetDB( DB_READ );
+ $cur = $dbr->tableName( 'cur' );
+ $categorylinks = $dbr->tableName( 'categorylinks' );
+
+ $t = $dbr->strencode( $this->mTitle->getDBKey() );
+ $sql = "SELECT DISTINCT cur_title,cur_namespace,cl_sortkey FROM " .
+ "$cur,$categorylinks WHERE cl_to='$t' AND cl_from=cur_id ORDER BY cl_sortkey" ;
+ $res = $dbr->query ( $sql ) ;
+ while ( $x = $dbr->fetchObject ( $res ) )
{
$t = $ns = $wgLang->getNsText ( $x->cur_namespace ) ;
if ( $t != '' ) $t .= ':' ;
@@ -448,7 +457,7 @@ cl_sortkey" ;
array_push ( $articles_start_char, $wgLang->firstChar( $x->cl_sortkey ) ) ;
}
}
- wfFreeResult ( $res ) ;
+ $dbr->freeResult ( $res ) ;
$ti = $this->mTitle->getText() ;
@@ -665,6 +674,9 @@ cl_sortkey" ;
# parse the wiki syntax used to render tables
function doTableStuff ( $t ) {
+ $fname = 'Parser::doTableStuff';
+ wfProfileIn( $fname );
+
$t = explode ( "\n" , $t ) ;
$td = array () ; # Is currently a td tag open?
$ltd = array () ; # Was it TD or TH?
@@ -760,6 +772,7 @@ cl_sortkey" ;
$t = implode ( "\n" , $t ) ;
# $t = $this->removeHTMLtags( $t );
+ wfProfileOut( $fname );
return $t ;
}
@@ -2025,9 +2038,14 @@ cl_sortkey" ;
# Return an HTML link for the "ISBN 123456" text
/* private */ function magicISBN( $text ) {
global $wgLang;
+ $fname = 'Parser::magicISBN';
+ wfProfileIn( $fname );
$a = split( 'ISBN ', " $text" );
- if ( count ( $a ) < 2 ) return $text;
+ if ( count ( $a ) < 2 ) {
+ wfProfileOut( $fname );
+ return $text;
+ }
$text = substr( array_shift( $a ), 1);
$valid = '0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZ';
@@ -2054,6 +2072,7 @@ cl_sortkey" ;
$text .= $x;
}
}
+ wfProfileOut( $fname );
return $text;
}
diff --git a/includes/Profiling.php b/includes/Profiling.php
index ed58bf08d80a..e27c766e0960 100755
--- a/includes/Profiling.php
+++ b/includes/Profiling.php
@@ -40,7 +40,7 @@ class Profiler
{
global $wgDebugFunctionEntry;
if ( $wgDebugFunctionEntry && function_exists( "wfDebug" ) ) {
- wfDebug( "Entering $functionname\n" );
+ wfDebug( str_repeat( " ", count( $this->mWorkStack ) ) . "Entering $functionname\n" );
}
array_push( $this->mWorkStack, array($functionname, count( $this->mWorkStack ), microtime() ) );
}
@@ -50,7 +50,7 @@ class Profiler
global $wgDebugProfiling, $wgDebugFunctionEntry;
if ( $wgDebugFunctionEntry && function_exists( "wfDebug" ) ) {
- wfDebug( "Exiting $functionname\n" );
+ wfDebug( str_repeat( " ", count( $this->mWorkStack ) - 1 ) . "Exiting $functionname\n" );
}
$bit = array_pop( $this->mWorkStack );
@@ -77,8 +77,11 @@ class Profiler
}
}
- function getOutput( $scriptStart, $scriptElapsed )
+ function getOutput()
{
+ global $wgDebugFunctionEntry;
+ $wgDebugFunctionEntry = false;
+
if( !count( $this->mStack ) ) {
return "No profiling output\n";
}
@@ -148,19 +151,21 @@ class Profiler
/* static */ function logToDB($name, $timeSum, $eventCount)
{
- $name = wfStrencode( $name );
- $sql = "UPDATE profiling ".
+ $dbw =& wfGetDB( DB_WRITE );
+ $profiling = $dbw->tableName( 'profiling' );
+
+ $name = $dbw->strencode( $name );
+ $sql = "UPDATE $profiling ".
"SET pf_count=pf_count+{$eventCount}, ".
"pf_time=pf_time + {$timeSum} ".
"WHERE pf_name='{$name}'";
- wfQuery($sql , DB_WRITE);
+ $dbw->query($sql);
- $rc = wfAffectedRows();
+ $rc = $dbw->affectedRows();
if( $rc == 0) {
- $sql = "INSERT IGNORE INTO profiling (pf_name,pf_count,pf_time) ".
+ $sql = "INSERT IGNORE INTO $profiling (pf_name,pf_count,pf_time) ".
"VALUES ('{$name}', {$eventCount}, {$timeSum}) ";
- wfQuery($sql , DB_WRITE);
- $rc = wfAffectedRows();
+ $dbw->query($sql , DB_WRITE);
}
// When we upgrade to mysql 4.1, the insert+update
// can be merged into just a insert with this construct added:
diff --git a/includes/QueryPage.php b/includes/QueryPage.php
index 43804cee26e8..77a55322ca5a 100644
--- a/includes/QueryPage.php
+++ b/includes/QueryPage.php
@@ -65,38 +65,67 @@ class QueryPage {
$sname = $this->getName();
$fname = get_class($this) . "::doQuery";
- $sql = $this->getSQL( $offset, $limit );
+ $sql = $this->getSQL();
+ $dbr =& wfGetDB( DB_READ );
+ $dbw =& wfGetDB( DB_WRITE );
+ $querycache = $dbr->tableName( 'querycache' );
$wgOut->setSyndicated( true );
+ $res = false;
if ( $this->isExpensive() ) {
- $type = wfStrencode( $sname );
$recache = $wgRequest->getBool( "recache" );
if( $recache ) {
# Clear out any old cached data
- $res = wfQuery( "DELETE FROM querycache WHERE qc_type='$type'", DB_WRITE, $fname );
-
- # Save results into the querycache table
+ $dbw->delete( 'querycache', array( 'qc_type' => $sname ), $fname );
+
+ # Do query on the (possibly out of date) slave server
$maxstored = 1000;
- $res = wfQuery(
- "INSERT INTO querycache(qc_type,qc_namespace,qc_title,qc_value) " .
- $this->getSQL() .
- $this->getOrderLimit( 0, $maxstored ),
- DB_WRITE, $fname );
+ $res = $dbr->query( $sql . $this->getOrderLimit( 0, $maxstored ), $fname );
+
+ # Fetch results
+ $insertSql = "INSERT INTO $querycache (qc_type,qc_namespace,qc_title,qc_value) VALUES ";
+ $first = true;
+ while ( $row = $dbr->fetchObject( $res ) ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $insertSql .= ",";
+ }
+ $insertSql .= "(" .
+ $dbw->addQuotes( $row->type ) . "," .
+ $dbw->addQuotes( $row->namespace ) . "," .
+ $dbw->addQuotes( $row->title ) . "," .
+ $dbw->addQuotes( $row->value ) . ")"
+ }
+
+ # Save results into the querycache table on the master
+ $dbw->query( $insertSql, $fname );
+
+ # Set result pointer to allow reading for display
+ $numRows = $dbr->numRows( $res );
+ if ( $numRows <= $offset ) {
+ $num = 0;
+ } else {
+ $dbr->dataSeek( $res, $offset );
+ $num = max( $limit, $numRows - $offset );
+ }
}
if( $wgMiserMode || $recache ) {
+ $type = $dbr->strencdode( $sname );
$sql =
"SELECT qc_type as type, qc_namespace as namespace,qc_title as title, qc_value as value
- FROM querycache WHERE qc_type='$type'";
+ FROM $querycache WHERE qc_type='$type'";
}
if( $wgMiserMode ) {
$wgOut->addWikiText( wfMsg( "perfcached" ) );
}
}
-
- $res = wfQuery( $sql . $this->getOrderLimit( $offset, $limit ), DB_READ, $fname );
+ if ( $res === false ) {
+ $res = $dbr->query( $sql . $this->getOrderLimit( $offset, $limit ), $fname );
+ $num = $dbr->numRows($res);
+ }
- $num = wfNumRows($res);
$sk = $wgUser->getSkin( );
@@ -110,11 +139,12 @@ class QueryPage {
$wgOut->addHTML( "<br />{$sl}</p>\n" );
$s = "<ol start='" . ( $offset + 1 ) . "'>";
- while ( $obj = wfFetchObject( $res ) ) {
+ # Only read at most $num rows, because $res may contain the whole 1000
+ for ( $i = 0; $i < $num && $obj = $dbr->fetchObject( $res ); $i++ ) {
$format = $this->formatResult( $sk, $obj );
$s .= "<li>{$format}</li>\n";
}
- wfFreeResult( $res );
+ $dbr->freeResult( $res );
$s .= "</ol>";
$wgOut->addHTML( $s );
$wgOut->addHTML( "<p>{$sl}</p>\n" );
@@ -131,13 +161,14 @@ class QueryPage {
$this->feedUrl() );
$feed->outHeader();
- $sql = $this->getSQL( 0, 50 );
- $res = wfQuery( $sql, DB_READ, "QueryPage::doFeed" );
- while( $obj = wfFetchObject( $res ) ) {
+ $dbr = wfGetDB( DB_READ );
+ $sql = $this->getSQL() . $this->getOrderLimit( 0, 50 );
+ $res = $dbr->query( $sql, "QueryPage::doFeed" );
+ while( $obj = $dbr->fetchObject( $res ) ) {
$item = $this->feedResult( $obj );
if( $item ) $feed->outItem( $item );
}
- wfFreeResult( $res );
+ $dbr->freeResult( $res );
$feed->outFooter();
return true;
diff --git a/includes/RawPage.php b/includes/RawPage.php
index 003ab452f782..9179a5e6b11d 100644
--- a/includes/RawPage.php
+++ b/includes/RawPage.php
@@ -56,13 +56,16 @@ class RawPage {
} else {
echo $this->getrawtext();
}
- wfAbruptExit();
+ $wgOut->disable();
}
function getrawtext () {
- global $wgInputEncoding, $wgLang, $wgIsPg;
+ global $wgInputEncoding, $wgLang;
+ $fname = 'RawPage::getrawtext';
+
if( !$this->mTitle ) return '';
- $t = wfStrencode( $this->mTitle->getDBKey() );
+ $dbr = wfGetDB( DB_READ );
+ $t = $dbr->strencode( $this->mTitle->getDBKey() );
$ns = $this->mTitle->getNamespace();
# special case
if($ns == NS_MEDIAWIKI) {
@@ -73,7 +76,7 @@ class RawPage {
}
# else get it from the DB
if(!empty($this->mOldId)) {
- $oldtable=$wgIsPg?'"old"':'old';
+ $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 " .
"WHERE old_id={$this->mOldId}";
@@ -82,8 +85,8 @@ class RawPage {
"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 ) ) {
+ $res = $dbr->query( $sql, $fname );
+ if( $s = $dbr->fetchObject( $res ) ) {
$rawtext = Article::getRevisionText( $s, "" );
if($wgInputEncoding != $this->mCharset)
$rawtext = $wgLang->iconv( $wgInputEncoding, $this->mCharset, $rawtext );
diff --git a/includes/SearchEngine.php b/includes/SearchEngine.php
index ff17c89958b9..bb2ed08b6ed2 100644
--- a/includes/SearchEngine.php
+++ b/includes/SearchEngine.php
@@ -157,21 +157,17 @@ class SearchEngine {
{
global $wgUser, $wgTitle, $wgOut, $wgLang, $wgRequest;
global $wgDisableTextSearch, $wgInputEncoding;
- global $wgLoadBalancer;
-
- $wgLoadBalancer->force(-1);
-
- $fname = "SearchEngine::showResults";
+ $fname = "SearchEngine::showResults";
$search = $wgRequest->getText( 'search' );
$powersearch = $this->powersearch(); /* Need side-effects here? */
$this->setupPage();
-
+
$sk = $wgUser->getSkin();
$header = wfMsg( "searchresulttext", $sk->makeKnownLink(
- wfMsg( "searchhelppage" ), wfMsg( "searchingwikipedia" ) ) );
+ wfMsg( "searchhelppage" ), wfMsg( "searchingwikipedia" ) ) );
$wgOut->addHTML( $header );
$this->parseQuery();
@@ -284,8 +280,7 @@ class SearchEngine {
$wgOut->addHTML( "<p>{$sl}</p>\n" );
$wgOut->addHTML( $powersearch );
}
- $wgLoadBalancer->force(0);
- }
+ }
function legalSearchChars()
{
diff --git a/includes/SearchUpdate.php b/includes/SearchUpdate.php
index c7b9c6103c32..55bad7907d1b 100644
--- a/includes/SearchUpdate.php
+++ b/includes/SearchUpdate.php
@@ -25,19 +25,21 @@ class SearchUpdate {
function doUpdate()
{
- global $wgDBminWordLen, $wgLang, $wgDisableSearchUpdate, $wgIsMySQL;
+ global $wgDBminWordLen, $wgLang, $wgDisableSearchUpdate;
if( $wgDisableSearchUpdate || !$this->mId ) {
return false;
}
$lc = SearchEngine::legalSearchChars() . "&#;";
+ $db =& wfGetDB( DB_WRITE );
+
if( $this->mText == false ) {
# Just update the title
- $lowpri=$wgIsMySQL?"LOW_PRIORITY":"";
+ $lowpri = $db->lowPriorityOption();
$sql = "UPDATE $lowpri searchindex SET si_title='" .
wfStrencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) .
"' WHERE si_page={$this->mId}";
- wfQuery( $sql, DB_WRITE, "SearchUpdate::doUpdate" );
+ $db->query( $sql, "SearchUpdate::doUpdate" );
return;
}
@@ -80,7 +82,7 @@ class SearchUpdate {
$sql = "REPLACE INTO searchindex (si_page,si_title,si_text) VALUES ({$this->mId},'" .
wfStrencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) . "','" .
wfStrencode( $text ) . "')";
- wfQuery( $sql, DB_WRITE, "SearchUpdate::doUpdate" );
+ $db->query( $sql, "SearchUpdate::doUpdate" );
}
}
diff --git a/includes/Setup.php b/includes/Setup.php
index 21d5ef39315e..90be866249ea 100644
--- a/includes/Setup.php
+++ b/includes/Setup.php
@@ -70,9 +70,10 @@ global $wgUser, $wgLang, $wgOut, $wgTitle;
global $wgArticle, $wgDeferredUpdateList, $wgLinkCache;
global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile;
global $wgMessageCache, $wgUseMemCached, $wgUseDatabaseMessages;
-global $wgMsgCacheExpiry, $wgDBname, $wgCommandLineMode;
+global $wgMsgCacheExpiry, $wgCommandLineMode;
global $wgBlockCache, $wgParserCache, $wgParser, $wgDBConnections;
-global $wgLoadBalancer, $wgDBservers, $wgDBloads, $wgDBuser, $wgDBpassword;
+global $wgLoadBalancer, $wgDBservers;
+global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype;
# Useful debug output
if ( $wgCommandLineMode ) {
@@ -146,10 +147,16 @@ wfProfileOut( $fname.'-memcached' );
wfProfileIn( $fname.'-database' );
if ( !$wgDBservers ) {
- $wgDBservers = array( $wgDBserver );
- $wgDBloads = array( 1 );
+ $wgDBservers = array(array(
+ 'host' => $wgDBserver,
+ 'user' => $wgDBuser,
+ 'password' => $wgDBpassword,
+ 'dbname' => $wgDBname,
+ 'type' => $wgDBtype,
+ 'load' => 1
+ ));
}
-$wgLoadBalancer = LoadBalancer::newFromParams( $wgDBservers, $wgDBloads, $wgDBuser, $wgDBpassword, $wgDBname );
+$wgLoadBalancer = LoadBalancer::newFromParams( $wgDBservers );
$wgLoadBalancer->force(0);
wfProfileOut( $fname.'-database' );
diff --git a/includes/SiteStatsUpdate.php b/includes/SiteStatsUpdate.php
index 900956b6398d..f8a6bb59315f 100644
--- a/includes/SiteStatsUpdate.php
+++ b/includes/SiteStatsUpdate.php
@@ -15,7 +15,6 @@ class SiteStatsUpdate {
function doUpdate()
{
- global $wgIsMySQL;
$a = array();
if ( $this->mViews < 0 ) { $m = "-1"; }
@@ -32,10 +31,12 @@ class SiteStatsUpdate {
else if ( $this->mGood > 0 ) { $m = "+1"; }
else $m = "";
array_push( $a, "ss_good_articles=(ss_good_articles$m)" );
- $lowpri=$wgIsMySQL?"LOW_PRIORITY":"";
+
+ $db =& wfGetDB( DB_WRITE );
+ $lowpri = $db->lowPriorityOption();
$sql = "UPDATE $lowpri site_stats SET " . implode ( ",", $a ) .
" WHERE ss_row_id=1";
- wfQuery( $sql, DB_WRITE, "SiteStatsUpdate::doUpdate" );
+ $db->query( $sql, "SiteStatsUpdate::doUpdate" );
}
}
diff --git a/includes/Skin.php b/includes/Skin.php
index c3dd2e6d8ce3..e739e97d4f18 100644
--- a/includes/Skin.php
+++ b/includes/Skin.php
@@ -1440,7 +1440,9 @@ class Skin {
# Pass a title object, not a title string
function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' )
{
- global $wgOut, $wgUser, $wgLoadBalancer;
+ global $wgOut, $wgUser;
+ $fname = 'Skin::makeLinkObj';
+
if ( $nt->isExternal() ) {
$u = $nt->getFullURL();
$link = $nt->getPrefixedURL();
@@ -1467,16 +1469,17 @@ class Skin {
} else {
$threshold = $wgUser->getOption('stubthreshold') ;
if ( $threshold > 0 ) {
- $wgLoadBalancer->force(-1);
- $res = wfQuery ( "SELECT LENGTH(cur_text) AS x, cur_namespace, cur_is_redirect FROM cur WHERE cur_id='{$aid}'", DB_READ ) ;
- $wgLoadBalancer->force(0);
- if ( wfNumRows( $res ) > 0 ) {
- $s = wfFetchObject( $res );
+ $s = $dbr->getArray( '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
}
- wfFreeResult( $res );
} else {
$size = $threshold*2 ; # Really big
}
diff --git a/includes/SkinPHPTal.php b/includes/SkinPHPTal.php
index 2a098c34c2c1..b7bb276a41bf 100644
--- a/includes/SkinPHPTal.php
+++ b/includes/SkinPHPTal.php
@@ -43,7 +43,9 @@
// interpolate variables
while (preg_match('/\$([0-9]*?)/sm', $value, $m)) {
list($src, $var) = $m;
- $varValue = @$this->_context[$var];
+ wfSuppressWarnings();
+ $varValue = $this->_context[$var];
+ wfRestoreWarnings();
$value = str_replace($src, $varValue, $value);
}
return $value;
diff --git a/includes/SpecialAllpages.php b/includes/SpecialAllpages.php
index 1cdeaa7de5ce..27b2b3b0fe56 100644
--- a/includes/SpecialAllpages.php
+++ b/includes/SpecialAllpages.php
@@ -2,12 +2,10 @@
function wfSpecialAllpages( $par=NULL )
{
- global $indexMaxperpage, $wgRequest, $wgLoadBalancer;
+ global $indexMaxperpage, $wgRequest;
$indexMaxperpage = 480;
$from = $wgRequest->getVal( 'from' );
- $wgLoadBalancer->force(-1);
-
if( $par ) {
indexShowChunk( $par );
} elseif( !is_null( $from ) ) {
@@ -15,8 +13,6 @@ function wfSpecialAllpages( $par=NULL )
} else {
indexShowToplevel();
}
-
- $wgLoadBalancer->force(0);
}
function indexShowToplevel()
diff --git a/includes/SpecialAncientpages.php b/includes/SpecialAncientpages.php
index 3aa93a54a47d..69d2d43eb83b 100644
--- a/includes/SpecialAncientpages.php
+++ b/includes/SpecialAncientpages.php
@@ -13,8 +13,8 @@ class AncientPagesPage extends QueryPage {
}
function getSQL() {
- global $wgIsMySQL;
- $use_index=$wgIsMySQL?"USE INDEX (cur_timestamp)":"";
+ $db = wfGetDB( DB_READ );
+ $use_index = $db->useIndexClause( 'cur_timestamp' );
return
"SELECT 'Ancientpages' as type,
cur_namespace as namespace,
diff --git a/includes/SpecialContributions.php b/includes/SpecialContributions.php
index 0dcd5ebfc3ae..5fd831ae4961 100644
--- a/includes/SpecialContributions.php
+++ b/includes/SpecialContributions.php
@@ -2,7 +2,7 @@
function wfSpecialContributions( $par = "" )
{
- global $wgUser, $wgOut, $wgLang, $wgRequest, $wgIsPg;
+ global $wgUser, $wgOut, $wgLang, $wgRequest;
$fname = "wfSpecialContributions";
$sysop = $wgUser->isSysop();
@@ -65,7 +65,7 @@ function wfSpecialContributions( $par = "" )
"&offset={$offset}&limit={$limit}&hideminor=1" );
}
- $oldtable=$wgIsPg?'"old"':'old';
+ $oldtable = wfTableName( 'old', DB_READ );
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} " .
diff --git a/includes/SpecialListadmins.php b/includes/SpecialListadmins.php
index 8518c43eafb0..ba5a579b769d 100644
--- a/includes/SpecialListadmins.php
+++ b/includes/SpecialListadmins.php
@@ -16,8 +16,7 @@ class ListAdminsPage extends PageQueryPage {
}
function getSQL() {
- global $wgIsPg;
- $usertable = $wgIsPg?'"user"':'user';
+ $usertable = wfTableName( 'user' );
$userspace = Namespace::getUser();
return 'SELECT user_rights as type,'.$userspace.' as namespace,'.
'user_name as title, user_name as value '.
diff --git a/includes/SpecialListusers.php b/includes/SpecialListusers.php
index e74f2a23a920..5a317f2a020b 100644
--- a/includes/SpecialListusers.php
+++ b/includes/SpecialListusers.php
@@ -13,8 +13,7 @@ class ListUsersPage extends QueryPage {
}
function getSQL() {
- global $wgIsPg;
- $usertable = $wgIsPg?'"user"':'user';
+ $usertable = wfTableName( 'user', DB_READ );
$userspace = Namespace::getUser();
return "SELECT user_rights as type, $userspace as namespace, user_name as title, user_name as value FROM $usertable";
}
@@ -36,7 +35,7 @@ class ListUsersPage extends QueryPage {
}
function wfSpecialListusers() {
- global $wgUser, $wgOut, $wgLang, $wgIsPg;
+ global $wgUser, $wgOut, $wgLang;
list( $limit, $offset ) = wfCheckLimits();
diff --git a/includes/SpecialMaintenance.php b/includes/SpecialMaintenance.php
index 3b16d6a2875d..6e3f2d0aa50b 100644
--- a/includes/SpecialMaintenance.php
+++ b/includes/SpecialMaintenance.php
@@ -10,46 +10,27 @@ function sns()
function wfSpecialMaintenance( $par=NULL )
{
global $wgUser, $wgOut, $wgLang, $wgTitle, $wgRequest, $wgLanguageCode;
- global $wgMiserMode, $wgLoadBalancer;
+ global $wgMiserMode;
if ( $wgMiserMode ) {
$wgOut->addWikiText( wfMsg( "perfdisabled" ) );
return;
}
- $wgLoadBalancer->force(-1);
-
$submitmll = $wgRequest->getVal( 'submitmll' );
-
+
if( $par )
$subfunction = $par;
else
$subfunction = $wgRequest->getText( 'subfunction' );
- $done = true;
-
- if ( $subfunction == "disambiguations" ) {
- wfSpecialDisambiguations() ;
- } elseif ( $subfunction == "doubleredirects" ) {
- wfSpecialDoubleRedirects() ;
- } elseif ( $subfunction == "brokenredirects" ) {
- wfSpecialBrokenRedirects() ;
- } elseif ( $subfunction == "selflinks" ) {
- wfSpecialSelfLinks() ;
- } elseif ( $subfunction == "mispeelings" ) {
- wfSpecialMispeelings() ;
- } elseif ( $subfunction == "missinglanguagelinks" ) {
- wfSpecialMissingLanguageLinks() ;
- } elseif ( !is_null( $submitmll ) ) {
- wfSpecialMissingLanguageLinks() ;
- } else {
- $done = false;
- }
-
- $wgLoadBalancer->force(0);
- if ( $done ) {
- return;
- }
+ if ( $subfunction == "disambiguations" ) return wfSpecialDisambiguations() ;
+ if ( $subfunction == "doubleredirects" ) return wfSpecialDoubleRedirects() ;
+ if ( $subfunction == "brokenredirects" ) return wfSpecialBrokenRedirects() ;
+ if ( $subfunction == "selflinks" ) return wfSpecialSelfLinks() ;
+ if ( $subfunction == "mispeelings" ) return wfSpecialMispeelings() ;
+ if ( $subfunction == "missinglanguagelinks" ) return wfSpecialMissingLanguageLinks() ;
+ if ( !is_null( $submitmll ) ) return wfSpecialMissingLanguageLinks() ;
$sk = $wgUser->getSkin();
$ns = $wgLang->getNamespaces() ;
@@ -59,7 +40,7 @@ function wfSpecialMaintenance( $par=NULL )
$r .= "<li>".getMPL("doubleredirects")."</li>\n" ;
$r .= "<li>".getMPL("brokenredirects")."</li>\n" ;
$r .= "<li>".getMPL("selflinks")."</li>\n" ;
- $r .= "<li>".getMPL("mispeelings")."</li>\n" ;
+ $r .= "<li>".getMPL("mispeelings")."</li>\n" ;
$r .= "<li>";
$l = getMPL("missinglanguagelinks");
@@ -77,7 +58,7 @@ function wfSpecialMaintenance( $par=NULL )
foreach ( $ak AS $k ) {
if ( $k != $wgLanguageCode )
$r .= "<option value='{$k}'>{$a[$k]}</option>\n" ;
- }
+ }
$r .= "</select>\n" ;
$r .= "</FORM>\n</li>" ;
@@ -278,69 +259,69 @@ function wfSpecialSelfLinks()
function wfSpecialMispeelings ()
{
- global $wgUser, $wgOut, $wgLang, $wgTitle;
- $sk = $wgUser->getSkin();
- $fname = "wfSpecialMispeelings";
-
- list( $limit, $offset ) = wfCheckLimits();
-
- # Determine page name
- $ms = wfMsg ( "mispeelingspage" ) ;
- $mss = wfStrencode( 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 = explode ( "\n" , $l ) ;
- $a = array () ;
- foreach ( $l as $x )
- if ( substr ( trim ( $x ) , 0 , 1 ) == "*" )
- $a[] = strtolower ( trim ( substr ( trim ( $x ) , 1 ) ) );
- asort ( $a ) ;
-
- $cnt = 0 ;
- $b = array () ;
- foreach ( $a AS $x ) {
- if ( $cnt < $offset+$limit && $x != "" ) {
- $y = $x ;
- $x = preg_replace( '/^(\S+).*$/', '$1', $x );
+ global $wgUser, $wgOut, $wgLang, $wgTitle;
+ $sk = $wgUser->getSkin();
+ $fname = "wfSpecialMispeelings";
+
+ list( $limit, $offset ) = wfCheckLimits();
+
+ # Determine page name
+ $ms = wfMsg ( "mispeelingspage" ) ;
+ $mss = wfStrencode( 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 = explode ( "\n" , $l ) ;
+ $a = array () ;
+ foreach ( $l as $x )
+ if ( substr ( trim ( $x ) , 0 , 1 ) == "*" )
+ $a[] = strtolower ( trim ( substr ( trim ( $x ) , 1 ) ) );
+ asort ( $a ) ;
+
+ $cnt = 0 ;
+ $b = array () ;
+ foreach ( $a AS $x ) {
+ 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 ) ) {
- if ( $cnt >= $offset AND $cnt < $offset+$limit ) {
- if ( $y != "" ) {
- if ( count ( $b ) > 0 ) $b[] = "</OL>\n" ;
- $b[] = "<H3>{$y}</H3>\n<OL start=".($cnt+1).">\n" ;
- $y = "" ;
- }
- $b[] = "<li>".
- $sk->makeKnownLink ( $obj->cur_title ).
- " (".
- $sk->makeBrokenLink ( $obj->cur_title , wfMsg ( "qbedit" ) ).
- ")</li>\n" ;
- }
- $cnt++ ;
- }
- }
- }
- $top = getMaintenancePageBacklink( "mispeelings" );
- $top .= "<p>".wfMsg( "mispeelingstext", $msl )."</p><br>\n";
- $top .= wfShowingResults( $offset, $limit );
- $wgOut->addHTML( "<p>{$top}\n" );
-
- $sl = wfViewPrevNext( $offset, $limit, "REPLACETHIS" ) ;
- $sl = str_replace ( "REPLACETHIS" , sns().":Maintenance&subfunction=mispeelings" , $sl ) ;
- $wgOut->addHTML( "<br>{$sl}\n" );
-
- $s = implode ( "" , $b ) ;
- if ( count ( $b ) > 0 ) $s .= "</ol>";
- $wgOut->addHTML( $s );
- $wgOut->addHTML( "<p>{$sl}\n" );
+ $res = wfQuery( $sql, DB_READ, $fname );
+ while ( $obj = wfFetchObject ( $res ) ) {
+ if ( $cnt >= $offset AND $cnt < $offset+$limit ) {
+ if ( $y != "" ) {
+ if ( count ( $b ) > 0 ) $b[] = "</OL>\n" ;
+ $b[] = "<H3>{$y}</H3>\n<OL start=".($cnt+1).">\n" ;
+ $y = "" ;
+ }
+ $b[] = "<li>".
+ $sk->makeKnownLink ( $obj->cur_title ).
+ " (".
+ $sk->makeBrokenLink ( $obj->cur_title , wfMsg ( "qbedit" ) ).
+ ")</li>\n" ;
+ }
+ $cnt++ ;
+ }
+ }
+ }
+ $top = getMaintenancePageBacklink( "mispeelings" );
+ $top .= "<p>".wfMsg( "mispeelingstext", $msl )."</p><br>\n";
+ $top .= wfShowingResults( $offset, $limit );
+ $wgOut->addHTML( "<p>{$top}\n" );
+
+ $sl = wfViewPrevNext( $offset, $limit, "REPLACETHIS" ) ;
+ $sl = str_replace ( "REPLACETHIS" , sns().":Maintenance&subfunction=mispeelings" , $sl ) ;
+ $wgOut->addHTML( "<br>{$sl}\n" );
+
+ $s = implode ( "" , $b ) ;
+ if ( count ( $b ) > 0 ) $s .= "</ol>";
+ $wgOut->addHTML( $s );
+ $wgOut->addHTML( "<p>{$sl}\n" );
}
diff --git a/includes/SpecialNewpages.php b/includes/SpecialNewpages.php
index 77940e96eba1..095bb7f77d2e 100644
--- a/includes/SpecialNewpages.php
+++ b/includes/SpecialNewpages.php
@@ -14,7 +14,7 @@ class NewPagesPage extends QueryPage {
#return parent::isExpensive();
}
- function getSQL( $offset, $limit ) {
+ function getSQL() {
return
"SELECT 'Newpages' as type,
rc_namespace AS namespace,
diff --git a/includes/SpecialRandompage.php b/includes/SpecialRandompage.php
index c795670f1d98..0dd4b60487a3 100644
--- a/includes/SpecialRandompage.php
+++ b/includes/SpecialRandompage.php
@@ -3,14 +3,15 @@
function wfSpecialRandompage()
{
- global $wgOut, $wgTitle, $wgArticle, $wgIsMySQL, $wgExtraRandompageSQL;
+ 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, ".", "" );
- $use_index=$wgIsMySQL?"USE INDEX (cur_random)":"";
+ $db =& wfGetDB( DB_READ );
+ $use_index = $db->useIndexClause( 'cur_random' );
if ( $wgExtraRandompageSQL ) {
$extra = "AND ($wgExtraRandompageSQL)";
} else {
@@ -22,8 +23,8 @@ function wfSpecialRandompage()
AND cur_random>$randstr
ORDER BY cur_random
LIMIT 1";
- $res = wfQuery( $sqlget, DB_READ, $fname );
- if( $s = wfFetchObject( $res ) ) {
+ $res = $db->query( $sqlget, $fname );
+ if( $s = $db->fetchObject( $res ) ) {
$rt = wfUrlEncode( $s->cur_title );
} else {
# No articles?!
diff --git a/includes/SpecialStatistics.php b/includes/SpecialStatistics.php
index f53cebc4ea49..883ef0fc71d7 100644
--- a/includes/SpecialStatistics.php
+++ b/includes/SpecialStatistics.php
@@ -2,22 +2,22 @@
function wfSpecialStatistics()
{
- global $wgUser, $wgOut, $wgLang, $wgIsPg, $wgLoadBalancer;
+ global $wgUser, $wgOut, $wgLang;
$fname = "wfSpecialStatistics";
- $wgLoadBalancer->force(-1);
-
$wgOut->addHTML( "<h2>" . wfMsg( "sitestats" ) . "</h2>\n" );
+
+ $db =& wfGetDB( DB_READ );
$sql = "SELECT COUNT(cur_id) AS total FROM cur";
- $res = wfQuery( $sql, DB_READ, $fname );
- $row = wfFetchObject( $res );
+ $res = $db->query( $sql, $fname );
+ $row = $db->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 = wfQuery( $sql, DB_READ, $fname );
- $row = wfFetchObject( $res );
+ $res = $db->query( $sql, $fname );
+ $row = $db->fetchObject( $res );
$views = $row->ss_total_views;
$edits = $row->ss_total_edits;
$good = $row->ss_good_articles;
@@ -33,16 +33,16 @@ function wfSpecialStatistics()
$wgOut->addWikiText( $text );
$wgOut->addHTML( "<h2>" . wfMsg( "userstats" ) . "</h2>\n" );
- $usertable=$wgIsPg?'"user"':'user';
+ $usertable = $db->tableName( 'user' );
$sql = "SELECT COUNT(user_id) AS total FROM $usertable";
- $res = wfQuery( $sql, DB_READ, $fname );
- $row = wfFetchObject( $res );
+ $res = $db->query( $sql, $fname );
+ $row = $db->fetchObject( $res );
$total = $row->total;
$sql = "SELECT COUNT(user_id) AS total FROM $usertable " .
"WHERE user_rights LIKE '%sysop%'";
- $res = wfQuery( $sql, DB_READ, $fname );
- $row = wfFetchObject( $res );
+ $res = $db->query( $sql, $fname );
+ $row = $db->fetchObject( $res );
$admins = $row->total;
$sk = $wgUser->getSkin();
@@ -53,7 +53,6 @@ function wfSpecialStatistics()
$wgLang->formatNum( $admins ), $ap );
$wgOut->addWikiText( $text );
- $wgLoadBalancer->force(0);
}
?>
diff --git a/includes/SpecialWatchlist.php b/includes/SpecialWatchlist.php
index aece38b20009..ba933092bf72 100644
--- a/includes/SpecialWatchlist.php
+++ b/includes/SpecialWatchlist.php
@@ -4,8 +4,8 @@ require_once( "WatchedItem.php" );
function wfSpecialWatchlist()
{
- global $wgUser, $wgOut, $wgLang, $wgTitle, $wgMemc, $wgLoadBalancer;
- global $wgUseWatchlistCache, $wgWLCacheTimeout, $wgDBname, $wgIsMySQL;
+ global $wgUser, $wgOut, $wgLang, $wgTitle, $wgMemc;
+ global $wgUseWatchlistCache, $wgWLCacheTimeout, $wgDBname;
global $days, $limit, $target; # From query string
$fname = "wfSpecialWatchlist";
@@ -51,19 +51,15 @@ function wfSpecialWatchlist()
}
}
- $wgLoadBalancer->force(-1);
$sql = "SELECT COUNT(*) AS n FROM watchlist WHERE wl_user=$uid";
$res = wfQuery( $sql, DB_READ );
$s = wfFetchObject( $res );
$nitems = $s->n;
- $wgLoadBalancer->force(0);
if($nitems == 0) {
$wgOut->addHTML( wfMsg( "nowatchlist" ) );
return;
}
- $wgLoadBalancer->force(-1);
-
if ( ! isset( $days ) ) {
$big = 1000;
if($nitems > $big) {
@@ -119,7 +115,6 @@ function wfSpecialWatchlist()
wfMsg( "removechecked" ) . "' />\n" .
"</form>\n" );
- $wgLoadBalancer->force(0);
return;
}
@@ -145,7 +140,7 @@ function wfSpecialWatchlist()
$wgLang->formatNum( $nitems ), $wgLang->formatNum( $npages ), $y,
$specialTitle->escapeLocalUrl( "magic=yes" ) ) . "</i><br />\n" );
- $use_index=$wgIsMySQL?"USE INDEX ($x)":"";
+ $use_index = wfUseIndexClause( $x, DB_READ );
$sql = "SELECT
cur_namespace,cur_title,cur_comment, cur_id,
cur_user,cur_user_text,cur_timestamp,cur_minor_edit,cur_is_new
@@ -171,7 +166,6 @@ function wfSpecialWatchlist()
if ( wfNumRows( $res ) == 0 ) {
$wgOut->addHTML( "<p><i>" . wfMsg( "watchnochange" ) . "</i></p>" );
- $wgLoadBalancer->force(0);
return;
}
@@ -193,7 +187,6 @@ function wfSpecialWatchlist()
$wgMemc->set( $memckey, $s, $wgWLCacheTimeout);
}
- $wgLoadBalancer->force(0);
}
diff --git a/includes/Title.php b/includes/Title.php
index 7acdc61cddce..14728c833843 100644
--- a/includes/Title.php
+++ b/includes/Title.php
@@ -88,7 +88,7 @@ class Title {
# From a URL-encoded title
/* static */ function newFromURL( $url )
{
- global $wgLang, $wgServer, $wgIsMySQL, $wgIsPg;
+ global $wgLang, $wgServer;
$t = new Title();
# For compatibility with old buggy URLs. "+" is not valid in titles,
@@ -109,20 +109,10 @@ class Title {
$t->mDbkeyform = str_replace( " ", "_", $s );
if( $t->secureAndSplit() ) {
- # check that lenght of title is < cur_title size
- if ($wgIsMySQL) {
- $sql = "SHOW COLUMNS FROM cur LIKE \"cur_title\";";
- $cur_title_object = wfFetchObject(wfQuery( $sql, DB_READ ));
-
- preg_match( "/\((.*)\)/", $cur_title_object->Type, $cur_title_type);
- $cur_title_size=$cur_title_type[1];
- } else {
- /* midom:FIXME pg_field_type does not return varchar length
- assume 255 */
- $cur_title_size=255;
- }
-
- if (strlen($t->mDbkeyform) > $cur_title_size ) {
+ # check that length of title is < cur_title size
+ $dbr =& wfGetDB( DB_READ );
+ $maxSize = $dbr->textFieldSize( 'cur', 'cur_title' );
+ if ( $maxSize != -1 && strlen( $t->mDbkeyform ) > $maxSize ) {
return NULL;
}
@@ -138,7 +128,8 @@ class Title {
/* static */ function newFromID( $id )
{
$fname = "Title::newFromID";
- $row = wfGetArray( "cur", array( "cur_namespace", "cur_title" ),
+ $dbr =& wfGetDB( DB_READ );
+ $row = $dbr->getArray( "cur", array( "cur_namespace", "cur_title" ),
array( "cur_id" => $id ), $fname );
if ( $row !== false ) {
$title = Title::makeTitle( $row->cur_namespace, $row->cur_title );
@@ -172,12 +163,12 @@ class Title {
# Get the prefixed DB key associated with an ID
/* static */ function nameOf( $id )
{
- $sql = "SELECT cur_namespace,cur_title FROM cur WHERE " .
- "cur_id={$id}";
- $res = wfQuery( $sql, DB_READ, "Article::nameOf" );
- if ( 0 == wfNumRows( $res ) ) { return NULL; }
+ $fname = 'Title::nameOf';
+ $dbr =& wfGetDB( DB_READ );
+
+ $s = $dbr->getArray( 'cur', array( 'cur_namespace','cur_title' ), array( 'cur_id' => $id ), $fname );
+ if ( $s === false ) { return NULL; }
- $s = wfFetchObject( $res );
$n = Title::makeName( $s->cur_namespace, $s->cur_title );
return $n;
}
@@ -244,8 +235,7 @@ class Title {
function getInterwikiLink( $key )
{
global $wgMemc, $wgDBname, $wgInterwikiExpiry, $wgTitleInterwikiCache;
- global $wgLoadBalancer;
-
+ $fname = 'Title::getInterwikiLink';
$k = "$wgDBname:interwiki:$key";
if( array_key_exists( $k, $wgTitleInterwikiCache ) )
@@ -257,17 +247,16 @@ class Title {
$wgTitleInterwikiCache[$k] = $s;
return $s->iw_url;
}
- $dkey = wfStrencode( $key );
- $wgLoadBalancer->force(-1);
- $query = "SELECT iw_url,iw_local FROM interwiki WHERE iw_prefix='$dkey'";
- $res = wfQuery( $query, DB_READ, "Title::getInterwikiLink" );
- $wgLoadBalancer->force(0);
+ $dbr =& wfGetDB( DB_READ );
+ $res = $dbr->select( 'interwiki', array( 'iw_url', 'iw_local' ), array( 'iw_prefix' => $key ), $fname );
if(!$res) return "";
- $s = wfFetchObject( $res );
+ $s = $dbr->fetchObject( $res );
if(!$s) {
+ # Cache non-existence: create a blank object and save it to memcached
$s = (object)false;
$s->iw_url = "";
+ $s->iw_local = 0;
}
$wgMemc->set( $k, $s, $wgInterwikiExpiry );
$wgTitleInterwikiCache[$k] = $s;
@@ -296,20 +285,21 @@ class Title {
if ( $timestamp == "" ) {
$timestamp = wfTimestampNow();
}
- $sql = "UPDATE cur SET cur_touched='{$timestamp}' WHERE cur_id IN (";
+ $dbw =& wfGetDB( DB_WRITE );
+ $cur = $dbw->tableName( 'cur' );
+ $sql = "UPDATE $cur SET cur_touched='{$timestamp}' WHERE cur_id IN (";
$first = true;
foreach ( $titles as $title ) {
if ( ! $first ) {
$sql .= ",";
}
-
$first = false;
$sql .= $title->getArticleID();
}
$sql .= ")";
if ( ! $first ) {
- wfQuery( $sql, DB_WRITE, "Title::touchArray" );
+ $dbw->query( $sql, "Title::touchArray" );
}
}
@@ -568,7 +558,8 @@ class Title {
if ( 0 == $id ) { return array(); }
if ( ! $this->mRestrictionsLoaded ) {
- $res = wfGetSQL( "cur", "cur_restrictions", "cur_id=$id" );
+ $dbr =& wfGetDB( DB_READ );
+ $res = $dbr->getField( "cur", "cur_restrictions", "cur_id=$id" );
$this->mRestrictions = explode( ",", trim( $res ) );
$this->mRestrictionsLoaded = true;
}
@@ -576,15 +567,13 @@ class Title {
}
# Is there a version of this page in the deletion archive?
+ # Returns the number of archived revisions
function isDeleted() {
- $ns = $this->getNamespace();
- $t = wfStrencode( $this->getDBkey() );
- $sql = "SELECT COUNT(*) AS n FROM archive WHERE ar_namespace=$ns AND ar_title='$t'";
- if( $res = wfQuery( $sql, DB_READ ) ) {
- $s = wfFetchObject( $res );
- return $s->n;
- }
- return 0;
+ $fname = 'Title::isDeleted';
+ $dbr =& wfGetDB( DB_READ );
+ $n = $dbr->getField( 'archive', 'COUNT(*)', array( 'ar_namespace' => $this->getNamespace(),
+ 'ar_title' => $this->getDBkey() ), $fname );
+ return (int)$n;
}
# Get the article ID from the link cache
@@ -616,10 +605,16 @@ class Title {
# Called from LinksUpdate.php
function invalidateCache() {
$now = wfTimestampNow();
- $ns = $this->getNamespace();
- $ti = wfStrencode( $this->getDBkey() );
- $sql = "UPDATE cur SET cur_touched='$now' WHERE cur_namespace=$ns AND cur_title='$ti'";
- return wfQuery( $sql, DB_WRITE, "Title::invalidateCache" );
+ $dbw =& wfGetDB( DB_WRITE );
+ $success = $dbw->updateArray( 'cur',
+ array( /* SET */
+ 'cur_touched' => wfTimestampNow()
+ ), array( /* WHERE */
+ 'cur_namespace' => $this->getNamespace() ,
+ 'cur_title' => $this->getDBkey()
+ ), 'Title::invalidateCache'
+ );
+ return $success;
}
# Prefixes some arbitrary text with the namespace or interwiki prefix of this object
@@ -640,8 +635,8 @@ class Title {
# Secure and split - main initialisation function for this object
#
# Assumes that mDbkeyform has been set, and is urldecoded
- # and uses undersocres, but not otherwise munged. This function
- # removes illegal characters, splits off the winterwiki and
+ # and uses underscores, but not otherwise munged. This function
+ # removes illegal characters, splits off the interwiki and
# namespace prefixes, sets the other forms, and canonicalizes
# everything.
#
@@ -733,6 +728,7 @@ class Title {
# Reject illegal characters.
#
if( preg_match( $rxTc, $r ) ) {
+ wfProfileOut( $fname );
return false;
}
@@ -743,6 +739,7 @@ class Title {
strpos( $r, "/./" !== false ) ||
strpos( $r, "/../" !== false ) ) )
{
+ wfProfileOut( $fname );
return false;
}
@@ -773,21 +770,31 @@ class Title {
# Get an array of Title objects linking to this title
# Also stores the IDs in the link cache
+ # $options may be FOR UPDATE
function getLinksTo( $options = '' ) {
global $wgLinkCache;
$id = $this->getArticleID();
- $sql = "SELECT cur_namespace,cur_title,cur_id FROM cur,links WHERE l_from=cur_id AND l_to={$id} $options";
- $res = wfQuery( $sql, DB_READ, "Title::getLinksTo" );
+
+ if ( $options ) {
+ $db =& wfGetDB( DB_WRITE );
+ } else {
+ $db =& wfGetDB( DB_READ );
+ }
+ $cur = $db->tableName( 'cur' );
+ $links = $db->tableName( 'links' );
+
+ $sql = "SELECT cur_namespace,cur_title,cur_id FROM $cur,$links WHERE l_from=cur_id AND l_to={$id} $options";
+ $res = $db->query( $sql, "Title::getLinksTo" );
$retVal = array();
- if ( wfNumRows( $res ) ) {
- while ( $row = wfFetchObject( $res ) ) {
+ if ( $db->numRows( $res ) ) {
+ while ( $row = $db->fetchObject( $res ) ) {
if ( $titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title ) ) {
$wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
$retVal[] = $titleObj;
}
}
}
- wfFreeResult( $res );
+ $db->freeResult( $res );
return $retVal;
}
@@ -795,19 +802,28 @@ class Title {
# Also stores the IDs in the link cache
function getBrokenLinksTo( $options = '' ) {
global $wgLinkCache;
- $encTitle = wfStrencode( $this->getPrefixedDBkey() );
- $sql = "SELECT cur_namespace,cur_title,cur_id FROM brokenlinks,cur " .
+
+ if ( $options ) {
+ $db =& wfGetDB( DB_WRITE );
+ } else {
+ $db =& wfGetDB( DB_READ );
+ }
+ $cur = $db->tableName( 'cur' );
+ $brokenlinks = $db->tableName( 'brokenlinks' );
+ $encTitle = $db->strencode( $this->getPrefixedDBkey() );
+
+ $sql = "SELECT cur_namespace,cur_title,cur_id FROM $brokenlinks,$cur " .
"WHERE bl_from=cur_id AND bl_to='$encTitle' $options";
- $res = wfQuery( $sql, DB_READ, "Title::getBrokenLinksTo" );
+ $res = $db->query( $sql, "Title::getBrokenLinksTo" );
$retVal = array();
- if ( wfNumRows( $res ) ) {
- while ( $row = wfFetchObject( $res ) ) {
+ if ( $db->numRows( $res ) ) {
+ while ( $row = $db->fetchObject( $res ) ) {
$titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title );
$wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
$retVal[] = $titleObj;
}
}
- wfFreeResult( $res );
+ $db->freeResult( $res );
return $retVal;
}
@@ -896,10 +912,11 @@ class Title {
$won = wfInvertTimestamp( $now );
$newid = $nt->getArticleID();
$oldid = $this->getArticleID();
-
+ $dbw =& wfGetDB( DB_WRITE );
+ $links = $dbw->tableName( 'links' );
+
# Change the name of the target page:
- wfUpdateArray(
- /* table */ 'cur',
+ $dbw->updateArray( 'cur',
/* SET */ array(
'cur_touched' => $now,
'cur_namespace' => $nt->getNamespace(),
@@ -914,8 +931,7 @@ class Title {
# by definition if we've got here it's rather uninteresting.
$redirectText = $wgMwRedir->getSynonym( 0 ) . " [[" . $nt->getPrefixedText() . "]]\n";
- wfUpdateArray(
- /* table */ 'cur',
+ $dbw->updateArray( 'cur',
/* SET */ array(
'cur_touched' => $now,
'cur_timestamp' => $now,
@@ -940,7 +956,7 @@ class Title {
# Fix the redundant names for the past revisions of the target page.
# The redirect should have no old revisions.
- wfUpdateArray(
+ $dbw->updateArray(
/* table */ 'old',
/* SET */ array(
'old_namespace' => $nt->getNamespace(),
@@ -962,12 +978,12 @@ class Title {
$linksToNew = $nt->getLinksTo( 'FOR UPDATE' );
# Delete them all
- $sql = "DELETE FROM links WHERE l_to=$oldid OR l_to=$newid";
- wfQuery( $sql, DB_WRITE, $fname );
+ $sql = "DELETE FROM $links WHERE l_to=$oldid OR l_to=$newid";
+ $dbw->query( $sql, $fname );
# Reinsert
if ( count( $linksToOld ) || count( $linksToNew )) {
- $sql = "INSERT INTO links (l_from,l_to) VALUES ";
+ $sql = "INSERT INTO $links (l_from,l_to) VALUES ";
$first = true;
# Insert links to old title
@@ -992,15 +1008,13 @@ class Title {
$sql .= "($id, $oldid)";
}
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->query( $sql, DB_WRITE, $fname );
}
# Now, we record the link from the redirect to the new title.
# It should have no other outgoing links...
- $sql = "DELETE FROM links WHERE l_from={$newid}";
- wfQuery( $sql, DB_WRITE, $fname );
- $sql = "INSERT INTO links (l_from,l_to) VALUES ({$newid},{$oldid})";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->delete( 'links', array( 'l_from' => $newid ) );
+ $dbw->insertArray( 'links', array( 'l_from' => $newid, 'l_to' => $oldid ) );
# Clear linkscc
LinkCache::linksccClearLinksTo( $oldid );
@@ -1027,10 +1041,10 @@ class Title {
$won = wfInvertTimestamp( $now );
$newid = $nt->getArticleID();
$oldid = $this->getArticleID();
+ $dbw =& wfGetDB( DB_WRITE );
# Rename cur entry
- wfUpdateArray(
- /* table */ 'cur',
+ $dbw->updateArray( 'cur',
/* SET */ array(
'cur_touched' => $now,
'cur_namespace' => $nt->getNamespace(),
@@ -1043,7 +1057,7 @@ class Title {
$wgLinkCache->clearLink( $nt->getPrefixedDBkey() );
# Insert redirct
- wfInsertArray( 'cur', array(
+ $dbw->insertArray( 'cur', array(
'cur_namespace' => $this->getNamespace(),
'cur_title' => $this->getDBkey(),
'cur_comment' => $comment,
@@ -1054,13 +1068,13 @@ class Title {
'cur_touched' => $now,
'cur_is_redirect' => 1,
'cur_is_new' => 1,
- 'cur_text' => "#REDIRECT [[" . $nt->getPrefixedText() . "]]\n" )
+ 'cur_text' => "#REDIRECT [[" . $nt->getPrefixedText() . "]]\n" ), $fname
);
- $newid = wfInsertId();
+ $newid = $dbw->insertId();
$wgLinkCache->clearLink( $this->getPrefixedDBkey() );
# Rename old entries
- wfUpdateArray(
+ $dbw->updateArray(
/* table */ 'old',
/* SET */ array(
'old_namespace' => $nt->getNamespace(),
@@ -1079,13 +1093,11 @@ class Title {
Article::onArticleCreate( $nt );
# Any text links to the old title must be reassigned to the redirect
- $sql = "UPDATE links SET l_to={$newid} WHERE l_to={$oldid}";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->updateArray( 'links', array( 'l_to' => $newid ), array( 'l_to' => $oldid ), $fname );
LinkCache::linksccClearLinksTo( $oldid );
# Record the just-created redirect's linking to the page
- $sql = "INSERT INTO links (l_from,l_to) VALUES ({$newid},{$oldid})";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->insertArray( 'links', array( 'l_from' => $newid, 'l_to' => $oldid ), $fname );
# Non-existent target may have had broken links to it; these must
# now be removed and made into good links.
@@ -1106,19 +1118,18 @@ class Title {
}
# Checks if $this can be moved to $nt
- # Both titles must exist in the database, otherwise it will blow up
+ # Selects for update, so don't call it unless you mean business
function isValidMoveTarget( $nt )
{
$fname = "Title::isValidMoveTarget";
+ $dbw =& wfGetDB( DB_WRITE );
# Is it a redirect?
$id = $nt->getArticleID();
- $sql = "SELECT cur_is_redirect,cur_text FROM cur " .
- "WHERE cur_id={$id}";
- $res = wfQuery( $sql, DB_READ, $fname );
- $obj = wfFetchObject( $res );
+ $obj = $dbw->getArray( 'cur', array( 'cur_is_redirect','cur_text' ),
+ array( 'cur_id' => $id ), $fname, 'FOR UPDATE' );
- if ( 0 == $obj->cur_is_redirect ) {
+ if ( !$obj || 0 == $obj->cur_is_redirect ) {
# Not a redirect
return false;
}
@@ -1132,9 +1143,11 @@ class Title {
}
# Does the article have a history?
- $row = wfGetArray( 'old', array( 'old_id' ), array(
- 'old_namespace' => $nt->getNamespace(),
- 'old_title' => $nt->getDBkey() )
+ $row = $dbw->getArray( 'old', array( 'old_id' ),
+ array(
+ 'old_namespace' => $nt->getNamespace(),
+ 'old_title' => $nt->getDBkey()
+ ), $fname, 'FOR UPDATE'
);
# Return true if there was no history
@@ -1149,10 +1162,14 @@ class Title {
return false;
}
+ $fname = "Title::createRedirect";
+ $dbw =& wfGetDB( DB_WRITE );
$now = wfTimestampNow();
$won = wfInvertTimestamp( $now );
+ $seqVal = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
- wfInsertArray( 'cur', array(
+ $dbw->insertArray( 'cur', array(
+ 'cur_id' => $seqVal,
'cur_namespace' => $this->getNamespace(),
'cur_title' => $this->getDBkey(),
'cur_comment' => $comment,
@@ -1164,21 +1181,25 @@ class Title {
'cur_is_redirect' => 1,
'cur_is_new' => 1,
'cur_text' => "#REDIRECT [[" . $dest->getPrefixedText() . "]]\n"
- ));
- $newid = wfInsertId();
+ ), $fname );
+ $newid = $dbw->insertId();
$this->resetArticleID( $newid );
# Link table
if ( $dest->getArticleID() ) {
- wfInsertArray( 'links', array(
- 'l_to' => $dest->getArticleID(),
- 'l_from' => $newid
- ));
+ $dbw->insertArray( 'links',
+ array(
+ 'l_to' => $dest->getArticleID(),
+ 'l_from' => $newid
+ ), $fname
+ );
} else {
- wfInsertArray( 'brokenlinks', array(
- 'bl_to' => $dest->getPrefixedDBkey(),
- 'bl_from' => $newid
- ));
+ $dbw->insertArray( 'brokenlinks',
+ array(
+ 'bl_to' => $dest->getPrefixedDBkey(),
+ 'bl_from' => $newid
+ ), $fname
+ );
}
Article::onArticleCreate( $this );
@@ -1191,21 +1212,23 @@ class Title {
{
global $wgLang,$wgUser;
- #$titlekey = wfStrencode( $this->getArticleID() );
$titlekey = $this->getArticleId();
$cns = Namespace::getCategory();
$sk =& $wgUser->getSkin();
$parents = array();
-
+ $dbr =& wfGetDB( DB_READ );
+ $cur = $dbr->tableName( 'cur' );
+ $categorylinks = $dbr->tableName( 'categorylinks' );
+
# get the parents categories of this title from the database
- $sql = "SELECT DISTINCT cur_id FROM cur,categorylinks
+ $sql = "SELECT DISTINCT cur_id FROM $cur,$categorylinks
WHERE cl_from='$titlekey' AND cl_to=cur_title AND cur_namespace='$cns'
ORDER BY cl_sortkey" ;
- $res = wfQuery ( $sql, DB_READ ) ;
+ $res = $dbr->query ( $sql ) ;
- if(wfNumRows($res) > 0) {
- while ( $x = wfFetchObject ( $res ) ) $data[] = $x ;
- wfFreeResult ( $res ) ;
+ if($dbr->numRows($res) > 0) {
+ while ( $x = $dbr->fetchObject ( $res ) ) $data[] = $x ;
+ $dbr->freeResult ( $res ) ;
} else {
$data = '';
}
diff --git a/includes/ViewCountUpdate.php b/includes/ViewCountUpdate.php
index 16976f11b0f2..470fa69f61d4 100644
--- a/includes/ViewCountUpdate.php
+++ b/includes/ViewCountUpdate.php
@@ -12,12 +12,13 @@ class ViewCountUpdate {
function doUpdate()
{
- global $wgDisableCounters, $wgIsMySQL;
+ global $wgDisableCounters;
if ( $wgDisableCounters ) { return; }
- $lowpri=$wgIsMySQL?"LOW_PRIORITY":"";
+ $db =& wfGetDB( DB_WRITE );
+ $lowpri = $db->lowPriorityOption();
$sql = "UPDATE $lowpri cur SET cur_counter=(1+cur_counter)," .
"cur_timestamp=cur_timestamp WHERE cur_id={$this->mPageID}";
- $res = wfQuery( $sql, DB_WRITE, "ViewCountUpdate::doUpdate" );
+ $res = $db->query( $sql, "ViewCountUpdate::doUpdate" );
}
}
?>
diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php
index 23ad2804e1de..e2d9506f79e6 100644
--- a/includes/WatchedItem.php
+++ b/includes/WatchedItem.php
@@ -36,24 +36,17 @@ class WatchedItem {
function addWatch()
{
- global $wgIsMySQL;
+ $fname = "WatchedItem::addWatch";
# REPLACE instead of INSERT because occasionally someone
# accidentally reloads a watch-add operation.
- if ($wgIsMySQL) {
- $sql = "REPLACE INTO watchlist (wl_user, wl_namespace,wl_title) ".
- "VALUES ($this->id,$this->ns,'$this->eti')";
- $res = wfQuery( $sql, DB_WRITE );
- } else {
- $sql = "DELETE FROM watchlist WHERE wl_user=$this->id AND
- wl_namespace=$this->ns AND wl_title='$this->eti'";
- wfQuery( $sql, DB_WRITE);
- $sql = "INSERT INTO watchlist (wl_user, wl_namespace,wl_title) ".
- "VALUES ($this->id,$this->ns,'$this->eti')";
- $res = wfQuery( $sql, DB_WRITE );
- }
+ $dbw =& wfGetDB( DB_WRITE );
+ $dbw->replace( 'watchlist', array(array('wl_user', 'wl_namespace', 'wl_title')),
+ array(
+ 'wl_user' => $this->id,
+ 'wl_namespace' => $this->ns,
+ 'wl_title' => $this->eti,
+ ), $fname );
- if( $res === false ) return false;
-
global $wgMemc;
$wgMemc->set( $this->watchkey(), 1 );
return true;
diff --git a/index.php b/index.php
index 992a28b1936f..075e721b10e8 100644
--- a/index.php
+++ b/index.php
@@ -95,7 +95,8 @@ if ( $search = $wgRequest->getText( 'search' ) ) {
$wgArticle = new Article( $wgTitle );
}
- wfQuery("BEGIN", DB_WRITE);
+ $db =& wfGetDB( DB_WRITE );
+ $db->query("BEGIN", DB_WRITE);
switch( $action ) {
case "view":
$wgOut->setSquidMaxage( $wgSquidMaxage );
@@ -165,7 +166,7 @@ if ( $search = $wgRequest->getText( 'search' ) ) {
default:
$wgOut->errorpage( "nosuchaction", "nosuchactiontext" );
}
- wfQuery("COMMIT", DB_WRITE);
+ $db->query("COMMIT");
}
$wgOut->output();
diff --git a/install-utils.inc b/install-utils.inc
index 040c34dc8191..2ee841f4596c 100644
--- a/install-utils.inc
+++ b/install-utils.inc
@@ -132,7 +132,8 @@ function dbsource( $fname, $database = false ) {
# Obsolete, use Database::fieldExists()
function field_exists( $table, $field ) {
$fname = "Update script: field_exists";
- $res = wfQuery( "DESCRIBE $table", $fname );
+ $db =& wfGetDB( DB_READ );
+ $res = $db->query( "DESCRIBE $table", $fname );
$found = false;
while ( $row = wfFetchObject( $res ) ) {
diff --git a/texvc.phtml b/texvc.phtml
index 7a9127185227..7f5e1a04721e 100644
--- a/texvc.phtml
+++ b/texvc.phtml
@@ -7,148 +7,160 @@ print "?xml version=\"1.0\" encoding=\"utf-8\"?";
print ">";
?>
<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>texvc</title></head><body>
<?php
print "<form method=\"post\" action=\"{$wgServer}{$wgScriptPath}/texvc_cgi.phtml\">"
?>
<textarea name='math' rows='10' cols='80'><?
- global $math;
- $math = preg_replace ("/\\\\\\\\/", '\\', $math);
- print $math;
+ global $math;
+ $math = preg_replace ("/\\\\\\\\/", '\\', $math);
+ print $math;
?></textarea><br /><input type="submit" value="Preview" name="preview" /></form>
<?php
function xlinkToMathImage ( $tex, $outputhash )
{
- global $wgMathPath;
- return "<img src=\"".$wgMathPath."/".$outputhash.".png\" alt=\"".wfEscapeHTML($tex)."\" />";
+ global $wgMathPath;
+ return "<img src=\"".$wgMathPath."/".$outputhash.".png\" alt=\"".wfEscapeHTML($tex)."\" />";
}
function texvc_cgi_renderMath( $tex )
{
- global $wgMathDirectory, $wgTmpDirectory, $wgInputEncoding;
- $mf = wfMsg( "math_failure" );
- $munk = wfMsg( "math_unknown_error" );
-
- $image = "";
- $outhtml = "";
- $outtex = "";
-
- $fname = "texvc_cgi_renderMath";
-
- $md5 = md5($tex);
- $md5_sql = mysql_escape_string(pack("H32", $md5));
- $sql = "SELECT math_outputhash,math_html_conservativeness,math_html,math_mathml FROM math WHERE math_inputhash = '".$md5_sql."'";
-
- $res = wfQuery( $sql, 0, $fname );
- if ( wfNumRows( $res ) == 0 )
- {
- $cmd = "./math/texvc ".escapeshellarg($wgTmpDirectory)." ".
- escapeshellarg($wgMathDirectory)." ".escapeshellarg($tex)." ".escapeshellarg($wgInputEncoding);
- $contents = `$cmd`;
-
- if (strlen($contents) == 0)
- return "<h3>".$mf." (".$munk."): ".wfEscapeHTML($tex)."</h3>";
- $retval = substr ($contents, 0, 1);
-
- if (($retval == "C") || ($retval == "M") || ($retval == "L")) {
- if ($retval == "C")
- $conservativeness = 2;
- else if ($retval == "M")
- $conservativeness = 1;
- else
- $conservativeness = 0;
- $outdata = substr ($contents, 33);
-
- $i = strpos($outdata, "\000");
-
- $outhtml = substr($outdata, 0, $i);
- $mathml = substr($outdata, $i+1);
-
- $sql_html = "'".mysql_escape_string($outhtml)."'";
- $sql_mathml = "'".mysql_escape_string($mathml)."'";
- } else if (($retval == "c") || ($retval == "m") || ($retval == "l")) {
- $outhtml = substr ($contents, 33);
- if ($retval == "c")
- $conservativeness = 2;
- else if ($retval == "m")
- $conservativeness = 1;
- else
- $conservativeness = 0;
- $sql_html = "'".mysql_escape_string($outhtml)."'";
- $mathml = '';
- $sql_mathml = 'NULL';
- } else if ($retval == "X") {
- $outhtml = '';
- $mathml = substr ($contents, 33);
- $sql_html = 'NULL';
- $sql_mathml = "'".mysql_escape_string($mathml)."'";
- $conservativeness = 0;
- } else if ($retval == "+") {
- $outhtml = '';
- $mathml = '';
- $sql_html = 'NULL';
- $sql_mathml = 'NULL';
- $conservativeness = 0;
+ global $wgMathDirectory, $wgTmpDirectory, $wgInputEncoding;
+ $dbr =& wfGetDB( DB_READ );
+ $mf = wfMsg( "math_failure" );
+ $munk = wfMsg( "math_unknown_error" );
+
+ $image = "";
+ $outhtml = "";
+ $outtex = "";
+
+ $fname = "texvc_cgi_renderMath";
+
+ $md5 = md5($tex);
+ $md5_sql = pack("H32", $md5);
+
+ $mathTable = $dbr->tableName( 'math' );
+ $rpage = $dbr->getArray( 'math', array('math_outputhash','math_html_conservativeness','math_html','math_mathml'),
+ array( 'math_inputhash' => $md5_sql ) );
+
+ if ( $rpage === false )
+ {
+ $cmd = "./math/texvc ".wfEscapeShellArg($wgTmpDirectory)." ".
+ wfEscapeShellArg($wgMathDirectory)." ".wfEscapeShellArg($tex)." ".wfEscapeShellArg($wgInputEncoding);
+ $contents = `$cmd`;
+
+ if (strlen($contents) == 0)
+ return "<h3>".$mf." (".$munk."): ".wfEscapeHTML($tex)."</h3>";
+ $retval = substr ($contents, 0, 1);
+
+ if (($retval == "C") || ($retval == "M") || ($retval == "L")) {
+ if ($retval == "C")
+ $conservativeness = 2;
+ else if ($retval == "M")
+ $conservativeness = 1;
+ else
+ $conservativeness = 0;
+ $outdata = substr ($contents, 33);
+
+ $i = strpos($outdata, "\000");
+
+ $outhtml = substr($outdata, 0, $i);
+ $mathml = substr($outdata, $i+1);
+
+ #$sql_html = "'".mysql_escape_string($outhtml)."'";
+ #$sql_mathml = "'".mysql_escape_string($mathml)."'";
+ } else if (($retval == "c") || ($retval == "m") || ($retval == "l")) {
+ $outhtml = substr ($contents, 33);
+ if ($retval == "c")
+ $conservativeness = 2;
+ else if ($retval == "m")
+ $conservativeness = 1;
+ else
+ $conservativeness = 0;
+ #$sql_html = "'".mysql_escape_string($outhtml)."'";
+ $mathml = NULL;
+ #$sql_mathml = 'NULL';
+ } else if ($retval == "X") {
+ $outhtml = NULL;
+ $mathml = substr ($contents, 33);
+ #$sql_html = 'NULL';
+ #$sql_mathml = "'".mysql_escape_string($mathml)."'";
+ $conservativeness = 0;
+ } else if ($retval == "+") {
+ $outhtml = NULL;
+ $mathml = NULL;
+ #$sql_html = 'NULL';
+ #$sql_mathml = 'NULL';
+ $conservativeness = 0;
+ } else {
+ if ($retval == "E")
+ $errmsg = wfMsg( "math_lexing_error" );
+ else if ($retval == "S")
+ $errmsg = wfMsg( "math_syntax_error" );
+ else if ($retval == "F")
+ $errmsg = wfMsg( "math_unknown_function" );
+ else
+ $errmsg = $munk;
+ return "<h3>".$mf." (".$errmsg.substr($contents, 1)."): ".wfEscapeHTML($tex)."</h3>";
+ }
+
+ $outmd5 = substr ($contents, 1, 32);
+ if (!preg_match("/^[a-f0-9]{32}$/", $outmd5))
+ return "<h3>".$mf." (".$munk."): ".wfEscapeHTML($tex)."</h3>";
+
+ $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->insertArray( 'math',
+ array(
+ 'math_inputhash' => $md5_sql,
+ 'math_outputhash' => $outmd5_sql,
+ 'math_html_conservativeness' => $conservativeness,
+ 'math_html' => $outhtml,
+ 'math_mathml' => $mathml,
+ ), $fname, array( 'IGNORE' )
+ );
+
+// we don't really care if it fails
} else {
- if ($retval == "E")
- $errmsg = wfMsg( "math_lexing_error" );
- else if ($retval == "S")
- $errmsg = wfMsg( "math_syntax_error" );
- else if ($retval == "F")
- $errmsg = wfMsg( "math_unknown_function" );
- else
- $errmsg = $munk;
- return "<h3>".$mf." (".$errmsg.substr($contents, 1)."): ".wfEscapeHTML($tex)."</h3>";
+ $rpage = $dbr->fetchObject ( $res );
+ $outmd5 = unpack ("H32md5", $rpage->math_outputhash);
+ $outmd5 = $outmd5 ['md5'];
+ $outhtml = $rpage->math_html;
+ $conservativeness = $rpage->math_html_conservativeness;
+ $mathml = $rpage->math_mathml;
}
-
- $outmd5 = substr ($contents, 1, 32);
- if (!preg_match("/^[a-f0-9]{32}$/", $outmd5))
- return "<h3>".$mf." (".$munk."): ".wfEscapeHTML($tex)."</h3>";
-
- $outmd5_sql = mysql_escape_string(pack("H32", $outmd5));
-
- $sql = "INSERT INTO math VALUES ('".$md5_sql."', '".$outmd5_sql."', ".$conservativeness.", ".$sql_html.", ".$sql_mathml.")";
-
- $res = wfQuery( $sql, 0, $fname );
-// we don't really care if it fails
- } else {
- $rpage = wfFetchObject ( $res );
- $outmd5 = unpack ("H32md5", $rpage->math_outputhash);
- $outmd5 = $outmd5 ['md5'];
- $outhtml = $rpage->math_html;
- $conservativeness = $rpage->math_html_conservativeness;
- $mathml = $rpage->math_mathml;
- }
- if ($mathml == '')
- $mathml = "<h3>Failed to generate MathML</h3>";
- else
- $mathml = "<h3>MathML</h3><math xmlns=\"http://www.w3.org/1998/Math/MathML\">$mathml</math>";
- $image = "<h3>Image</h3>" . xlinkToMathImage ( $tex, $outmd5 );
- $cmd = "./math/texvc_tex ".escapeshellarg($tex)." ".escapeshellarg($wgInputEncoding);
- $outtex = `$cmd`;
-
- if ( $outhtml == '' )
- $outhtml = "<h3>Failed to generate HTML</h3>";
- else
- if ( $conservativeness == 2)
- $outhtml = "<h3>HTML (conservative)</h3>" . $outhtml;
- else if ( $conservativeness == 1)
- $outhtml = "<h3>HTML (moderate)</h3>" . $outhtml;
+ if ( is_null( $mathml ) || $mathml === '' )
+ $mathml = "<h3>Failed to generate MathML</h3>";
else
- $outhtml = "<h3>HTML (liberal)</h3>" . $outhtml;
+ $mathml = "<h3>MathML</h3><math xmlns=\"http://www.w3.org/1998/Math/MathML\">$mathml</math>";
+ $image = "<h3>Image</h3>" . xlinkToMathImage ( $tex, $outmd5 );
+ $cmd = "./math/texvc_tex ".escapeshellarg($tex)." ".escapeshellarg($wgInputEncoding);
+ $outtex = `$cmd`;
- if ( $outtex == '' )
- $outtex = "<h3>Failed to generate TeX</h3>";
- else
- $outtex = "<h3>TeX</h3>" . wfEscapeHTML($outtex);
+ if ( is_null( $outhtml ) || $outhtml === '' )
+ $outhtml = "<h3>Failed to generate HTML</h3>";
+ else
+ if ( $conservativeness == 2)
+ $outhtml = "<h3>HTML (conservative)</h3>" . $outhtml;
+ else if ( $conservativeness == 1)
+ $outhtml = "<h3>HTML (moderate)</h3>" . $outhtml;
+ else
+ $outhtml = "<h3>HTML (liberal)</h3>" . $outhtml;
+
+ if ( $outtex == '' )
+ $outtex = "<h3>Failed to generate TeX</h3>";
+ else
+ $outtex = "<h3>TeX</h3>" . wfEscapeHTML($outtex);
- return $outtex . $outhtml . $mathml . $image;
+ return $outtex . $outhtml . $mathml . $image;
}
global $math;
if ($math != '')
- print texvc_cgi_renderMath($math);
+ print texvc_cgi_renderMath($math);
?>
</body></html>