[MediaWiki-commits] [Gerrit] Use WatchedItemStore in ApiQueryInfo::getWatchedInfo - change (mediawiki/core)
jenkins-bot has submitted this change and it was merged. Change subject: Use WatchedItemStore in ApiQueryInfo::getWatchedInfo .. Use WatchedItemStore in ApiQueryInfo::getWatchedInfo Adds a method for getting watchlist's notification timestamps for a batch of LinkTargets. Bug: T129482 Change-Id: I1f84212e7879a84b34bb3b53859069fcea282bba --- M includes/WatchedItemStore.php M includes/api/ApiQueryInfo.php M tests/phpunit/includes/WatchedItemStoreIntegrationTest.php M tests/phpunit/includes/WatchedItemStoreUnitTest.php 4 files changed, 332 insertions(+), 23 deletions(-) Approvals: Addshore: Looks good to me, approved jenkins-bot: Verified diff --git a/includes/WatchedItemStore.php b/includes/WatchedItemStore.php index 4e2dfa5..8a3f205 100644 --- a/includes/WatchedItemStore.php +++ b/includes/WatchedItemStore.php @@ -503,6 +503,61 @@ } /** +* @param User $user +* @param LinkTarget[] $targets +* +* @return array multi-dimensional like $return[$namespaceId][$titleString] = $timestamp, +* where $timestamp is: +* - string|null value of wl_notificationtimestamp, +* - false if $target is not watched by $user. +*/ + public function getNotificationTimestampsBatch( User $user, array $targets ) { + $timestamps = []; + foreach ( $targets as $target ) { + $timestamps[$target->getNamespace()][$target->getDBkey()] = false; + } + + if ( $user->isAnon() ) { + return $timestamps; + } + + $targetsToLoad = []; + foreach ( $targets as $target ) { + $cachedItem = $this->getCached( $user, $target ); + if ( $cachedItem ) { + $timestamps[$target->getNamespace()][$target->getDBkey()] = + $cachedItem->getNotificationTimestamp(); + } else { + $targetsToLoad[] = $target; + } + } + + if ( !$targetsToLoad ) { + return $timestamps; + } + + $dbr = $this->getConnection( DB_SLAVE ); + + $lb = new LinkBatch( $targetsToLoad ); + $res = $dbr->select( + 'watchlist', + [ 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ], + [ + $lb->constructSet( 'wl', $dbr ), + 'wl_user' => $user->getId(), + ], + __METHOD__ + ); + $this->reuseConnection( $dbr ); + + foreach ( $res as $row ) { + $timestamps[(int)$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp; + } + + return $timestamps; + } + + /** * Must be called separately for Subject & Talk namespaces * * @param User $user diff --git a/includes/api/ApiQueryInfo.php b/includes/api/ApiQueryInfo.php index 2d382dd..ea1b94e 100644 --- a/includes/api/ApiQueryInfo.php +++ b/includes/api/ApiQueryInfo.php @@ -448,8 +448,8 @@ ApiResult::setIndexedTagName( $pageInfo['restrictiontypes'], 'rt' ); } - if ( $this->fld_watched ) { - $pageInfo['watched'] = isset( $this->watched[$ns][$dbkey] ); + if ( $this->fld_watched && $this->watched !== null ) { + $pageInfo['watched'] = $this->watched[$ns][$dbkey]; } if ( $this->fld_watchers ) { @@ -470,7 +470,7 @@ if ( $this->fld_notificationtimestamp ) { $pageInfo['notificationtimestamp'] = ''; - if ( isset( $this->notificationtimestamps[$ns][$dbkey] ) ) { + if ( $this->notificationtimestamps[$ns][$dbkey] ) { $pageInfo['notificationtimestamp'] = wfTimestamp( TS_ISO_8601, $this->notificationtimestamps[$ns][$dbkey] ); } @@ -758,29 +758,22 @@ $this->watched = []; $this->notificationtimestamps = []; - $db = $this->getDB(); - $lb = new LinkBatch( $this->everything ); + $store = WatchedItemStore::getDefaultInstance(); + $timestamps = $store->getNotificationTimestampsBatch( $user, $this->everything ); - $this->resetQueryParams(); - $this->addTables( [ 'watchlist' ] ); - $this->addFields( [ 'wl_title', 'wl_namespace' ] ); - $this->addFieldsIf( 'wl_notificationtimestamp',
[MediaWiki-commits] [Gerrit] Use WatchedItemStore in ApiQueryInfo::getWatchedInfo - change (mediawiki/core)
WMDE-leszek has uploaded a new change for review. https://gerrit.wikimedia.org/r/278283 Change subject: Use WatchedItemStore in ApiQueryInfo::getWatchedInfo .. Use WatchedItemStore in ApiQueryInfo::getWatchedInfo Adds a method for getting WatchedItem objects for a batch of LinkTargets. Bug: T129482 Change-Id: I1f84212e7879a84b34bb3b53859069fcea282bba --- M includes/WatchedItemStore.php M includes/api/ApiQueryInfo.php M tests/phpunit/includes/WatchedItemStoreIntegrationTest.php M tests/phpunit/includes/WatchedItemStoreUnitTest.php 4 files changed, 287 insertions(+), 17 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/83/278283/1 diff --git a/includes/WatchedItemStore.php b/includes/WatchedItemStore.php index 4e2dfa5..deeaf79 100644 --- a/includes/WatchedItemStore.php +++ b/includes/WatchedItemStore.php @@ -491,6 +491,61 @@ } /** +* Get items for targets +* +* @param User $user +* @param LinkTarget[] $targets +* +* @return WatchedItem[] +*/ + public function getWatchedItems( User $user, array $targets ) { + if ( $user->isAnon() ) { + return []; + } + + $watchedItems = []; + $targetsToLoad = []; + foreach ( $targets as $target ) { + $cachedItem = $this->getCached( $user, $target ); + if ( $cachedItem ) { + $watchedItems[] = $cachedItem; + } else { + $targetsToLoad[] = $target; + } + } + + if ( !$targetsToLoad ) { + return $watchedItems; + } + + $dbr = $this->getConnection( DB_SLAVE ); + + $lb = new LinkBatch( $targetsToLoad ); + $res = $dbr->select( + 'watchlist', + [ 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ], + [ + $lb->constructSet( 'wl', $dbr ), + 'wl_user' => $user->getId(), + ], + __METHOD__ + ); + $this->reuseConnection( $dbr ); + + foreach ( $res as $row ) { + $item = new WatchedItem( + $user, + new TitleValue( (int)$row->wl_namespace, $row->wl_title ), + $row->wl_notificationtimestamp + ); + $this->cache( $item ); + $watchedItems[] = $item; + } + + return $watchedItems; + } + + /** * Must be called separately for Subject & Talk namespaces * * @param User $user diff --git a/includes/api/ApiQueryInfo.php b/includes/api/ApiQueryInfo.php index 2d382dd..62cdcc9 100644 --- a/includes/api/ApiQueryInfo.php +++ b/includes/api/ApiQueryInfo.php @@ -758,28 +758,17 @@ $this->watched = []; $this->notificationtimestamps = []; - $db = $this->getDB(); - $lb = new LinkBatch( $this->everything ); + $items = WatchedItemStore::getDefaultInstance()->getWatchedItems( $user, $this->everything ); - $this->resetQueryParams(); - $this->addTables( [ 'watchlist' ] ); - $this->addFields( [ 'wl_title', 'wl_namespace' ] ); - $this->addFieldsIf( 'wl_notificationtimestamp', $this->fld_notificationtimestamp ); - $this->addWhere( [ - $lb->constructSet( 'wl', $db ), - 'wl_user' => $user->getId() - ] ); - - $res = $this->select( __METHOD__ ); - - foreach ( $res as $row ) { + foreach ( $items as $item ) { + $target = $item->getLinkTarget(); if ( $this->fld_watched ) { - $this->watched[$row->wl_namespace][$row->wl_title] = true; + $this->watched[$target->getNamespace()][$target->getDBkey()] = true; } if ( $this->fld_notificationtimestamp ) { - $this->notificationtimestamps[$row->wl_namespace][$row->wl_title] = - $row->wl_notificationtimestamp; + $this->notificationtimestamps[$target->getNamespace()][$target->getDBkey()] = + $item->getNotificationTimestamp(); } } } diff --git a/tests/phpunit/includes/WatchedItemStoreIntegrationTest.php