Merge "(bug 41171) Refactor User::edits() and User::incEditCount()"
authorIAlex <ialex.wiki@gmail.com>
Sat, 20 Oct 2012 16:13:42 +0000 (16:13 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sat, 20 Oct 2012 16:13:42 +0000 (16:13 +0000)
1  2 
includes/User.php

diff --combined includes/User.php
@@@ -1168,9 -1168,7 +1168,9 @@@ class User 
        }
  
        /**
 -       * Clear various cached data stored in this object.
 +       * Clear various cached data stored in this object. The cache of the user table
 +       * data (i.e. self::$mCacheVars) is not cleared unless $reloadFrom is given.
 +       *
         * @param $reloadFrom bool|String Reload user and user_groups table data from a
         *   given source. May be "name", "id", "defaults", "session", or false for
         *   no reload.
                $this->mEffectiveGroups = null;
                $this->mImplicitGroups = null;
                $this->mOptions = null;
 +              $this->mOptionsLoaded = false;
                $this->mEditCount = null;
  
                if ( $reloadFrom ) {
  
                                if( $count === null ) {
                                        // it has not been initialized. do so.
-                                       $dbw = wfGetDB( DB_MASTER );
-                                       $count = $dbr->selectField(
-                                               'revision', 'count(*)',
-                                               array( 'rev_user' => $this->mId ),
-                                               __METHOD__
-                                       );
-                                       $dbw->update(
-                                               'user',
-                                               array( 'user_editcount' => $count ),
-                                               array( 'user_id' => $this->mId ),
-                                               __METHOD__
-                                       );
+                                       $count = $this->initEditCount();
                                }
                                wfProfileOut( __METHOD__ );
                                $this->mEditCount = $count;
        }
  
        /**
 -       * Add this existing user object to the database. If the user already 
 -       * exists, a fatal status object is returned, and the user object is 
 +       * Add this existing user object to the database. If the user already
 +       * exists, a fatal status object is returned, and the user object is
         * initialised with the data from the database.
         *
         * Previously, this function generated a DB error due to a key conflict
         *   }
         *   // do something with $user...
         *
 -       * However, this was vulnerable to a race condition (bug 16020). By 
 +       * However, this was vulnerable to a race condition (bug 16020). By
         * initialising the user object if the user exists, we aim to support this
         * calling sequence as far as possible.
         *
         * Note that if the user exists, this function will acquire a write lock,
 -       * so it is still advisable to make the call conditional on isLoggedIn(), 
 +       * so it is still advisable to make the call conditional on isLoggedIn(),
         * and to commit the transaction after calling.
         *
         * @return Status
                        array( 'IGNORE' )
                );
                if ( !$dbw->affectedRows() ) {
 -                      $this->mId = $dbw->selectField( 'user', 'user_id', 
 +                      $this->mId = $dbw->selectField( 'user', 'user_id',
                                array( 'user_name' => $this->mName ), __METHOD__ );
                        $loaded = false;
                        if ( $this->mId ) {
        public function incEditCount() {
                if( !$this->isAnon() ) {
                        $dbw = wfGetDB( DB_MASTER );
-                       $dbw->update( 'user',
+                       $dbw->update(
+                               'user',
                                array( 'user_editcount=user_editcount+1' ),
                                array( 'user_id' => $this->getId() ),
-                               __METHOD__ );
+                               __METHOD__
+                       );
  
                        // Lazy initialization check...
                        if( $dbw->affectedRows() == 0 ) {
-                               // Pull from a slave to be less cruel to servers
-                               // Accuracy isn't the point anyway here
-                               $dbr = wfGetDB( DB_SLAVE );
-                               $count = $dbr->selectField( 'revision',
-                                       'COUNT(rev_user)',
-                                       array( 'rev_user' => $this->getId() ),
-                                       __METHOD__ );
                                // Now here's a goddamn hack...
+                               $dbr = wfGetDB( DB_SLAVE );
                                if( $dbr !== $dbw ) {
                                        // If we actually have a slave server, the count is
                                        // at least one behind because the current transaction
                                        // has not been committed and replicated.
-                                       $count++;
+                                       $this->initEditCount( 1 );
                                } else {
                                        // But if DB_SLAVE is selecting the master, then the
                                        // count we just read includes the revision that was
                                        // just added in the working transaction.
+                                       $this->initEditCount();
                                }
-                               $dbw->update( 'user',
-                                       array( 'user_editcount' => $count ),
-                                       array( 'user_id' => $this->getId() ),
-                                       __METHOD__ );
                        }
                }
                // edit count in user cache too
                $this->invalidateCache();
        }
  
+       /**
+        * Initialize user_editcount from data out of the revision table
+        *
+        * @param $add Integer Edits to add to the count from the revision table
+        * @return Integer Number of edits
+        */
+       protected function initEditCount( $add = 0 ) {
+               // Pull from a slave to be less cruel to servers
+               // Accuracy isn't the point anyway here
+               $dbr = wfGetDB( DB_SLAVE );
+               $count = $dbr->selectField(
+                       'revision',
+                       'COUNT(rev_user)',
+                       array( 'rev_user' => $this->getId() ),
+                       __METHOD__
+               );
+               $count = $count + $add;
+               $dbw = wfGetDB( DB_MASTER );
+               $dbw->update(
+                       'user',
+                       array( 'user_editcount' => $count ),
+                       array( 'user_id' => $this->getId() ),
+                       __METHOD__
+               );
+               return $count;
+       }
        /**
         * Get the description of a given right
         *