ported site_stats change from 1.4
authorTim Starling <tstarling@users.mediawiki.org>
Sun, 19 Jun 2005 00:21:49 +0000 (00:21 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sun, 19 Jun 2005 00:21:49 +0000 (00:21 +0000)
includes/Article.php
includes/Database.php
includes/SiteStatsUpdate.php
includes/SpecialMovepage.php
includes/SpecialStatistics.php
includes/SpecialUserlogin.php
includes/Title.php
maintenance/archives/patch-ss_total_articles.sql [new file with mode: 0644]
maintenance/tables.sql
maintenance/updaters.inc

index 3d95135..7884185 100644 (file)
@@ -28,7 +28,7 @@ class Article {
         */
        var $mContent, $mContentLoaded;
        var $mUser, $mTimestamp, $mUserText;
-       var $mCounter, $mComment, $mCountAdjustment;
+       var $mCounter, $mComment, $mGoodAdjustment, $mTotalAdjustment;
        var $mMinorEdit, $mRedirectedFrom;
        var $mTouched, $mFileCache, $mTitle;
        var $mId, $mTable;
@@ -65,7 +65,7 @@ class Article {
                $this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded
                $this->mRedirectedFrom = $this->mUserText =
                $this->mTimestamp = $this->mComment = $this->mFileCache = '';
-               $this->mCountAdjustment = 0;
+               $this->mGoodAdjustment = $this->mTotalAdjustment = 0;
                $this->mTouched = '19700101000000';
                $this->mForUpdate = false;
                $this->mIsRedirect = false;
@@ -906,7 +906,8 @@ class Article {
 
                $fname = 'Article::insertNewArticle';
 
-               $this->mCountAdjustment = $this->isCountable( $text );
+               $this->mGoodAdjustment = $this->isCountable( $text );
+               $this->mTotalAdjustment = 1;
 
                $ns = $this->mTitle->getNamespace();
                $ttl = $this->mTitle->getDBkey();
@@ -1120,8 +1121,9 @@ class Article {
                $lastRevision = 0;
 
                if ( 0 != strcmp( $text, $oldtext ) ) {
-                       $this->mCountAdjustment = $this->isCountable( $text )
+                       $this->mGoodAdjustment = $this->isCountable( $text )
                          - $this->isCountable( $oldtext );
+                       $this->mTotalAdjustment = 0;
                        $now = wfTimestampNow();
 
                        $lastRevision = $dbw->selectField(
@@ -1749,7 +1751,7 @@ class Article {
                        return false;
                }
 
-               $u = new SiteStatsUpdate( 0, 1, -$this->isCountable( $this->getContent( true ) ) );
+               $u = new SiteStatsUpdate( 0, 1, -$this->isCountable( $this->getContent( true ) ), -1 );
                array_push( $wgDeferredUpdateList, $u );
 
                $linksTo = $this->mTitle->getLinksTo();
@@ -1985,11 +1987,10 @@ class Article {
                $title = $this->mTitle->getPrefixedDBkey();
                $shortTitle = $this->mTitle->getDBkey();
 
-               $adj = $this->mCountAdjustment;
                if ( 0 != $id ) {
                        $u = new LinksUpdate( $id, $title );
                        array_push( $wgDeferredUpdateList, $u );
-                       $u = new SiteStatsUpdate( 0, 1, $adj );
+                       $u = new SiteStatsUpdate( 0, 1, $this->mGoodAdjustment, $this->mTotalAdjustment );
                        array_push( $wgDeferredUpdateList, $u );
                        $u = new SearchUpdate( $id, $title, $text );
                        array_push( $wgDeferredUpdateList, $u );
index 6509c7d..d46b4cd 100644 (file)
@@ -921,7 +921,9 @@ class Database {
        function update( $table, $values, $conds, $fname = 'Database::update' ) {
                $table = $this->tableName( $table );
                $sql = "UPDATE $table SET " . $this->makeList( $values, LIST_SET );
-               $sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
+               if ( $conds != '*' ) {
+                       $sql .= " WHERE " . $this->makeList( $conds, LIST_AND );
+               }
                $this->query( $sql, $fname );
        }
        
index d4c4b2e..00e5494 100644 (file)
  */
 class SiteStatsUpdate {
 
-       var $mViews, $mEdits, $mGood;
+       var $mViews, $mEdits, $mGood, $mPages, $mUsers;
 
-       function SiteStatsUpdate( $views, $edits, $good ) {
+       function SiteStatsUpdate( $views, $edits, $good, $pages = 0, $users = 0 ) {
                $this->mViews = $views;
                $this->mEdits = $edits;
                $this->mGood = $good;
+               $this->mPages = $pages;
+               $this->mUsers = $users;
        }
 
+       function appendUpdate( &$sql, $field, $delta ) {
+               if ( $delta ) {
+                       if ( $sql ) {
+                               $sql .= ',';
+                       }
+                       if ( $delta < 0 ) {
+                               $sql .= "$field=$field-1";
+                       } else {
+                               $sql .= "$field=$field+1";
+                       }
+               }
+       }
+       
        function doUpdate() {
-               $a = array();
-
-               if ( $this->mViews < 0 ) { $m = '-1'; }
-               else if ( $this->mViews > 0 ) { $m = '+1'; }
-               else $m = '';
-               array_push( $a, "ss_total_views=(ss_total_views$m)" );
-
-               if ( $this->mEdits < 0 ) { $m = '-1'; }
-               else if ( $this->mEdits > 0 ) { $m = '+1'; }
-               else $m = '';
-               array_push( $a, "ss_total_edits=(ss_total_edits$m)" );
-
-               if ( $this->mGood < 0 ) { $m = '-1'; }
-               else if ( $this->mGood > 0 ) { $m = '+1'; }
-               else $m = '';
-               array_push( $a, "ss_good_articles=(ss_good_articles$m)" );
-
-               $db =& wfGetDB( DB_MASTER );
-               $site_stats = $db->tableName( 'site_stats' );
-               $lowpri = $db->lowPriorityOption();
-
-               $sql = "UPDATE $lowpri $site_stats SET " . implode ( ',', $a ) .
-                 ' WHERE ss_row_id=1';
-               $db->query( $sql, 'SiteStatsUpdate::doUpdate' );
+               global $wgDBname;
+               $fname = 'SiteStatsUpdate::doUpdate';
+               $dbw =& wfGetDB( DB_MASTER );
+
+               # First retrieve the row just to find out which schema we're in
+               $row = $dbw->selectRow( 'site_stats', '*', false, $fname );
+
+               $updates = '';
+               
+               $this->appendUpdate( $updates, 'ss_total_views', $this->mViews );
+               $this->appendUpdate( $updates, 'ss_total_edits', $this->mEdits );
+               $this->appendUpdate( $updates, 'ss_good_articles', $this->mGood );
+
+               if ( isset( $row->ss_total_pages ) ) {
+                       # Update schema if required
+                       if ( $row->ss_total_pages == -1 && !$this->mViews ) {
+                               $dbr =& wfGetDB( DB_SLAVE, array( 'SpecialStatistics', 'vslow') );
+                               extract( $dbr->tableNames( 'page', 'user' ) );
+
+                               $sql = "SELECT COUNT(page_namespace) AS total FROM $page";
+                               $res = $dbr->query( $sql, $fname );
+                               $pageRow = $dbr->fetchObject( $res );
+                               $pages = $pageRow->total + $this->mPages;
+
+                               $sql = "SELECT COUNT(user_id) AS total FROM $user";
+                               $res = $dbr->query( $sql, $fname );
+                               $userRow = $dbr->fetchObject( $res );
+                               $users = $userRow->total + $this->mUsers;
+                               
+                               if ( $updates ) {
+                                       $updates .= ',';
+                               }
+                               $updates .= "ss_total_pages=$pages, ss_users=$users";
+                       } else {        
+                               $this->appendUpdate( $updates, 'ss_total_pages', $this->mPages );
+                               $this->appendUpdate( $updates, 'ss_users', $this->mUsers );
+                       }
+               }
+               if ( $updates ) {
+                       $site_stats = $dbw->tableName( 'site_stats' );
+                       $sql = "UPDATE $site_stats SET $updates LIMIT 1";
+                       $dbw->query( $sql, $fname );
+               }
        }
 }
-?>
\ No newline at end of file
+?>
index 39e5fac..9fbf2b1 100644 (file)
@@ -201,26 +201,6 @@ class MovePageForm {
                        $this->showForm( $error );
                        return;
                }
-
-               # Update counters if the article got moved into or out of NS_MAIN namespace
-               $ons = $ot->getNamespace();
-               $nns = $nt->getNamespace();
-               
-               # moved out of article namespace?
-               if ( $ons == NS_MAIN and $nns != NS_MAIN ) {
-                       $u = new SiteStatsUpdate( 0, 1, -1); # not viewed, edited, removing
-               }
-               # moved into article namespace?
-               elseif ( $ons != NS_MAIN and $nns == NS_MAIN ) {
-                       $u = new SiteStatsUpdate( 0, 1, +1 ); # not viewed, edited, adding
-               } else {
-                       $u = false;
-               }
-               if ( $u !== false ) {
-                       # save it for later update
-                       array_push( $wgDeferredUpdateList, $u );
-                       unset($u);
-               }
                
                # Move talk page if
                # (1) the checkbox says to,
index bb17934..73e6eb2 100644 (file)
@@ -1,13 +1,13 @@
 <?php
 /**
- *
- * @package MediaWiki
- * @subpackage SpecialPage
- */
+*
+* @package MediaWiki
+* @subpackage SpecialPage
+*/
 
 /**
- * constructor
- */
+* constructor
+*/
 function wfSpecialStatistics() {
        global $wgUser, $wgOut, $wgLang;
        $fname = 'wfSpecialStatistics';
@@ -15,19 +15,38 @@ function wfSpecialStatistics() {
        $dbr =& wfGetDB( DB_SLAVE );
        extract( $dbr->tableNames( 'page', 'site_stats', 'user', 'user_groups' ) );
 
-       $sql = "SELECT COUNT(page_namespace) AS total FROM $page";
-       $res = $dbr->query( $sql, $fname );
-       $row = $dbr->fetchObject( $res );
-       $total = $row->total;
-
-       $sql = "SELECT ss_total_views, ss_total_edits, ss_good_articles " .
-         "FROM $site_stats WHERE ss_row_id=1";
-       $res = $dbr->query( $sql, $fname );
-       $row = $dbr->fetchObject( $res );
+       $row = $dbr->selectRow( 'site_stats', '*', false, 'wfSpecialStatistics' );
        $views = $row->ss_total_views;
        $edits = $row->ss_total_edits;
        $good = $row->ss_good_articles;
 
+       # This code is somewhat schema-agnostic, because I'm changing it in a minor release -- TS
+       if ( isset( $row->ss_total_pages ) && $row->ss_total_pages == -1 ) {
+               # Update schema
+               $u = new SiteStatsUpdate( 0, 0, 0 );
+               $u->doUpdate();
+               $row = $dbr->selectRow( 'site_stats', '*', false, 'wfSpecialStatistics' );
+       }
+
+       if ( isset( $row->ss_total_pages ) ) {
+               $total = $row->ss_total_pages;
+       } else {
+               $sql = "SELECT COUNT(page_namespace) AS total FROM $page";
+               $res = $dbr->query( $sql, $fname );
+               $pageRow = $dbr->fetchObject( $res );
+               $total = $pageRow->total;
+       }
+
+       if ( isset( $row->ss_users ) ) {
+               $totalUsers = $row->ss_users;
+       } else {
+               $sql = "SELECT MAX(user_id) AS total FROM $user";
+               $res = $dbr->query( $sql, $fname );
+               $userRow = $dbr->fetchObject( $res );
+               $totalUsers = $userRow->total;
+       }       
+
+
        $text = '==' . wfMsg( 'sitestats' ) . "==\n" ;
        $text .= wfMsg( 'sitestatstext',
                $wgLang->formatNum( $total ),
@@ -39,18 +58,13 @@ function wfSpecialStatistics() {
 
        $text .= "\n==" . wfMsg( 'userstats' ) . "==\n";
 
-       $sql = "SELECT COUNT(user_id) AS total FROM $user";
-       $res = $dbr->query( $sql, $fname );
-       $row = $dbr->fetchObject( $res );
-       $total = $row->total;
-
        $sql = "SELECT COUNT(*) AS total FROM $user_groups WHERE ug_group='sysop'";
        $res = $dbr->query( $sql, $fname );
        $row = $dbr->fetchObject( $res );
        $admins = $row->total;
 
        $text .= wfMsg( 'userstatstext',
-               $wgLang->formatNum( $total ),
+               $wgLang->formatNum( $totalUsers ),
                $wgLang->formatNum( $admins ),
                '[[' . wfMsg( 'administrators' ) . ']]',
                // should logically be after #admins, danm backwards compatability!
index 1913bbe..b1d4886 100644 (file)
@@ -239,6 +239,10 @@ class LoginForm {
                        return false;
                }
 
+               # Update user count
+               $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
+               $ssUpdate->doUpdate();
+
                return $this->initUser( $u );
        }
        
index 92d813a..e84c236 100644 (file)
@@ -1536,8 +1536,10 @@ class Title {
                $pageid = $this->getArticleID();
                if( $nt->exists() ) {
                        $this->moveOverExistingRedirect( $nt, $reason );
+                       $pageCountChange = 0;
                } else { # Target didn't exist, do normal move.
                        $this->moveToNewTitle( $nt, $newid, $reason );
+                       $pageCountChange = 1;
                }
                $redirid = $this->getArticleID();
 
@@ -1565,6 +1567,25 @@ class Title {
                $u->doUpdate();
                $u = new SearchUpdate( $redirid, $this->getPrefixedDBkey(), '' );
                $u->doUpdate();
+               
+               # Update site_stats
+               if ( $this->getNamespace() == NS_MAIN and $nt->getNamespace() != NS_MAIN ) {
+                       # Moved out of main namespace
+                       # not viewed, edited, removing
+                       $u = new SiteStatsUpdate( 0, 1, -1, $pageCountChange); 
+               } elseif ( $this->getNamespace() != NS_MAIN and $nt->getNamespace() == NS_MAIN ) {
+                       # Moved into main namespace
+                       # not viewed, edited, adding
+                       $u = new SiteStatsUpdate( 0, 1, +1, $pageCountChange ); 
+               } elseif ( $pageCountChange ) {
+                       # Added redirect
+                       $u = new SiteStatsUpdate( 0, 0, 0, 1 );
+               } else{
+                       $u = false;
+               }
+               if ( $u ) {
+                       $u->doUpdate();
+               }
 
                wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) );
                return true;
diff --git a/maintenance/archives/patch-ss_total_articles.sql b/maintenance/archives/patch-ss_total_articles.sql
new file mode 100644 (file)
index 0000000..b4a48cf
--- /dev/null
@@ -0,0 +1,6 @@
+-- Faster statistics, as of 1.4.3
+
+ALTER TABLE /*$wgDBprefix*/site_stats
+  ADD ss_total_pages bigint(20) default -1,
+  ADD ss_users bigint(20) default -1,
+  ADD ss_admins int(10) default -1;
index c03a3b8..3521b63 100644 (file)
@@ -437,6 +437,15 @@ CREATE TABLE /*$wgDBprefix*/site_stats (
   -- See isCountable() in includes/Article.php
   ss_good_articles bigint(20) unsigned default '0',
   
+  -- Total pages, theoretically equal to SELECT COUNT(*) FROM cur; except faster
+  ss_total_pages bigint(20) default -1,
+
+  -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
+  ss_users bigint(20) default -1,
+
+  -- Deprecated, no longer updated as of 1.5
+  ss_admins int(10) default -1,
+
   UNIQUE KEY ss_row_id (ss_row_id)
 
 ) TYPE=InnoDB;
index e17cb5c..5978eed 100644 (file)
@@ -45,6 +45,7 @@ $wgNewFields = array(
        array( 'image',         'img_metadata',     'patch-img_metadata.sql' ),
        array( 'image',         'img_media_type',   'patch-img_media_type.sql' ),
        array( 'validate',      'val_ip',           'patch-val_ip.sql' ),
+       array( 'site_stats',    'ss_total_articles', 'patch-ss_total_articles.sql' ),
 );
 
 function rename_table( $from, $to, $patch ) {