From: Alexandre Emsenhuber Date: Fri, 10 Feb 2012 19:35:14 +0000 (+0000) Subject: * Don't issue a write query to the database if the wl_notificationtimestamp is alread... X-Git-Tag: 1.31.0-rc.0~24793 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=commitdiff_plain;h=e6441b8f6c1b40508cfd4b29b01bcfca0961deab;p=lhc%2Fweb%2Fwiklou.git * Don't issue a write query to the database if the wl_notificationtimestamp is already null, so we don't to do at COMMIT et al. on every view request on an user watching the page * Made WatchedItem select wl_notificationtimestamp instead of "1" * Added loading mechanism, accessor to wl_notificationtimestamp and method to reset that timestamp --- diff --git a/includes/User.php b/includes/User.php index 9ac1ef2e3f..cfceae0eac 100644 --- a/includes/User.php +++ b/includes/User.php @@ -2635,28 +2635,15 @@ class User { // The query to find out if it is watched is cached both in memcached and per-invocation, // and when it does have to be executed, it can be on a slave // If this is the user's newtalk page, we always update the timestamp - if( $title->getNamespace() == NS_USER_TALK && + $force = ''; + if ( $title->getNamespace() == NS_USER_TALK && $title->getText() == $this->getName() ) { - $watched = true; - } else { - $watched = $this->isWatched( $title ); + $force = 'force'; } - // If the page is watched by the user (or may be watched), update the timestamp on any - // any matching rows - if ( $watched ) { - $dbw = wfGetDB( DB_MASTER ); - $dbw->update( 'watchlist', - array( /* SET */ - 'wl_notificationtimestamp' => null - ), array( /* WHERE */ - 'wl_title' => $title->getDBkey(), - 'wl_namespace' => $title->getNamespace(), - 'wl_user' => $this->getID() - ), __METHOD__ - ); - } + $wi = WatchedItem::fromUserTitle( $this, $title ); + $wi->resetNotificationTimestamp( $force ); } /** diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php index 031b2b48b0..ecff5b55a4 100644 --- a/includes/WatchedItem.php +++ b/includes/WatchedItem.php @@ -9,6 +9,7 @@ */ class WatchedItem { var $mTitle, $mUser, $id, $ns, $ti; + private $loaded = false, $watched, $timestamp; /** * Create a WatchedItem object with the given user and title @@ -32,18 +33,83 @@ class WatchedItem { } /** - * Is mTitle being watched by mUser? - * @return bool + * Return an array of conditions to select or update the appropriate database + * row. + * + * @return array */ - public function isWatched() { + private function dbCond() { + return array( 'wl_user' => $this->id, 'wl_namespace' => $this->ns, 'wl_title' => $this->ti ); + } + + /** + * Load the object from the database + */ + private function load() { + if ( $this->loaded ) { + return; + } + $this->loaded = true; + # Pages and their talk pages are considered equivalent for watching; # remember that talk namespaces are numbered as page namespace+1. $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'watchlist', 1, array( 'wl_user' => $this->id, 'wl_namespace' => $this->ns, - 'wl_title' => $this->ti ), __METHOD__ ); - $iswatched = ($dbr->numRows( $res ) > 0) ? 1 : 0; - return $iswatched; + $row = $dbr->selectRow( 'watchlist', 'wl_notificationtimestamp', + $this->dbCond(), __METHOD__ ); + + if ( $row === false ) { + $this->watched = false; + } else { + $this->watched = true; + $this->timestamp = $row->wl_notificationtimestamp; + } + } + + /** + * Is mTitle being watched by mUser? + * @return bool + */ + public function isWatched() { + $this->load(); + return $this->watched; + } + + /** + * Get the notification timestamp of this entry. + * + * @return false|null|string: false if the page is not watched, the value of + * the wl_notificationtimestamp field otherwise + */ + public function getNotificationTimestamp() { + $this->load(); + if ( $this->watched ) { + return $this->timestamp; + } else { + return false; + } + } + + /** + * Reset the notification timestamp of this entry + * + * @param $force Whether to force the write query to be executed even if the + * page is not watched or the notification timestamp is already NULL. + */ + public function resetNotificationTimestamp( $force = '' ) { + if ( $force != 'force' ) { + $this->load(); + if ( !$this->watched || $this->timestamp === null ) { + return; + } + } + + // If the page is watched by the user (or may be watched), update the timestamp on any + // any matching rows + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( 'watchlist', array( 'wl_notificationtimestamp' => null ), + $this->dbCond(), __METHOD__ ); + $this->timestamp = null; } /** @@ -75,6 +141,8 @@ class WatchedItem { 'wl_notificationtimestamp' => null ), __METHOD__, 'IGNORE' ); + $this->watched = true; + wfProfileOut( __METHOD__ ); return true; } @@ -115,6 +183,8 @@ class WatchedItem { $success = true; } + $this->watched = false; + wfProfileOut( __METHOD__ ); return $success; } @@ -139,7 +209,7 @@ class WatchedItem { * * @return bool */ - private static function doDuplicateEntries( $ot, $nt ) { + private static function doDuplicateEntries( $ot, $nt ) { $oldnamespace = $ot->getNamespace(); $newnamespace = $nt->getNamespace(); $oldtitle = $ot->getDBkey();