Merge "Remove un-needed cast for array key in WatchedItemStore"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 26 Apr 2016 18:36:47 +0000 (18:36 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 26 Apr 2016 18:36:47 +0000 (18:36 +0000)
1  2 
includes/WatchedItemStore.php

@@@ -1,7 -1,5 +1,7 @@@
  <?php
  
 +use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 +use MediaWiki\Linker\LinkTarget;
  use Wikimedia\Assert\Assert;
  
  /**
   *
   * @since 1.27
   */
 -class WatchedItemStore {
 +class WatchedItemStore implements StatsdAwareInterface {
 +
 +      const SORT_DESC = 'DESC';
 +      const SORT_ASC = 'ASC';
  
        /**
         * @var LoadBalancer
         */
        private $revisionGetTimestampFromIdCallback;
  
 +      /**
 +       * @var StatsdDataFactoryInterface
 +       */
 +      private $stats;
 +
        /**
         * @var self|null
         */
        ) {
                $this->loadBalancer = $loadBalancer;
                $this->cache = $cache;
 +              $this->stats = new NullStatsdDataFactory();
                $this->deferredUpdatesAddCallableUpdateCallback = [ 'DeferredUpdates', 'addCallableUpdate' ];
                $this->revisionGetTimestampFromIdCallback = [ 'Revision', 'getTimestampFromId' ];
        }
  
 +      public function setStatsdDataFactory( StatsdDataFactoryInterface $stats ) {
 +              $this->stats = $stats;
 +      }
 +
        /**
         * Overrides the DeferredUpdates::addCallableUpdate callback
         * This is intended for use while testing and will fail if MW_PHPUNIT_TEST is not defined.
                                wfGetLB(),
                                new HashBagOStuff( [ 'maxKeys' => 100 ] )
                        );
 +                      self::$instance->setStatsdDataFactory( RequestContext::getMain()->getStats() );
                }
                return self::$instance;
        }
                $key = $this->getCacheKey( $user, $target );
                $this->cache->set( $key, $item );
                $this->cacheIndex[$target->getNamespace()][$target->getDBkey()][$user->getId()] = $key;
 +              $this->stats->increment( 'WatchedItemStore.cache' );
        }
  
        private function uncache( User $user, LinkTarget $target ) {
                $this->cache->delete( $this->getCacheKey( $user, $target ) );
                unset( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()][$user->getId()] );
 +              $this->stats->increment( 'WatchedItemStore.uncache' );
        }
  
        private function uncacheLinkTarget( LinkTarget $target ) {
                if ( !isset( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()] ) ) {
                        return;
                }
 +              $this->stats->increment( 'WatchedItemStore.uncacheLinkTarget' );
                foreach ( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()] as $key ) {
 +                      $this->stats->increment( 'WatchedItemStore.uncacheLinkTarget.items' );
                        $this->cache->delete( $key );
                }
        }
  
                $cached = $this->getCached( $user, $target );
                if ( $cached ) {
 +                      $this->stats->increment( 'WatchedItemStore.getWatchedItem.cached' );
                        return $cached;
                }
 +              $this->stats->increment( 'WatchedItemStore.getWatchedItem.load' );
                return $this->loadWatchedItem( $user, $target );
        }
  
         * @param User $user
         * @param array $options Allowed keys:
         *        'forWrite' => bool defaults to false
 +       *        'sort' => string optional sorting by namespace ID and title
 +       *                     one of the self::SORT_* constants
         *
         * @return WatchedItem[]
         */
        public function getWatchedItemsForUser( User $user, array $options = [] ) {
                $options += [ 'forWrite' => false ];
  
 +              $dbOptions = [];
 +              if ( array_key_exists( 'sort', $options ) ) {
 +                      Assert::parameter(
 +                              ( in_array( $options['sort'], [ self::SORT_ASC, self::SORT_DESC ] ) ),
 +                              '$options[\'sort\']',
 +                              'must be SORT_ASC or SORT_DESC'
 +                      );
 +                      $dbOptions['ORDER BY'] = [
 +                              "wl_namespace {$options['sort']}",
 +                              "wl_title {$options['sort']}"
 +                      ];
 +              }
                $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_SLAVE );
 +
                $res = $db->select(
                        'watchlist',
                        [ 'wl_namespace', 'wl_title', 'wl_notificationtimestamp' ],
                        [ 'wl_user' => $user->getId() ],
 -                      __METHOD__
 +                      __METHOD__,
 +                      $dbOptions
                );
                $this->reuseConnection( $db );
  
                $this->reuseConnection( $dbr );
  
                foreach ( $res as $row ) {
-                       $timestamps[(int)$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
+                       $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
                }
  
                return $timestamps;
         * @param LinkTarget $target
         */
        public function addWatch( User $user, LinkTarget $target ) {
 -              $this->addWatchBatch( [ [ $user, $target ] ] );
 +              $this->addWatchBatchForUser( $user, [ $target ] );
        }
  
        /**
 -       * @param array[] $userTargetCombinations array of arrays containing [0] => User [1] => LinkTarget
 +       * @param User $user
 +       * @param LinkTarget[] $targets
         *
         * @return bool success
         */
 -      public function addWatchBatch( array $userTargetCombinations ) {
 +      public function addWatchBatchForUser( User $user, array $targets ) {
                if ( $this->loadBalancer->getReadOnlyReason() !== false ) {
                        return false;
                }
 +              // Only loggedin user can have a watchlist
 +              if ( $user->isAnon() ) {
 +                      return false;
 +              }
 +
 +              if ( !$targets ) {
 +                      return true;
 +              }
  
                $rows = [];
 -              foreach ( $userTargetCombinations as list( $user, $target ) ) {
 -                      /**
 -                       * @var User $user
 -                       * @var LinkTarget $target
 -                       */
 -
 -                      // Only loggedin user can have a watchlist
 -                      if ( $user->isAnon() ) {
 -                              continue;
 -                      }
 +              foreach ( $targets as $target ) {
                        $rows[] = [
                                'wl_user' => $user->getId(),
                                'wl_namespace' => $target->getNamespace(),
                        $this->uncache( $user, $target );
                }
  
 -              if ( !$rows ) {
 -                      return false;
 -              }
 -
                $dbw = $this->getConnection( DB_MASTER );
                foreach ( array_chunk( $rows, 100 ) as $toInsert ) {
                        // Use INSERT IGNORE to avoid overwriting the notification timestamp
         * @param LinkTarget $newTarget
         */
        public function duplicateAllAssociatedEntries( LinkTarget $oldTarget, LinkTarget $newTarget ) {
 -              if ( !$oldTarget instanceof Title ) {
 -                      $oldTarget = Title::newFromLinkTarget( $oldTarget );
 -              }
 -              if ( !$newTarget instanceof Title ) {
 -                      $newTarget = Title::newFromLinkTarget( $newTarget );
 -              }
 +              $oldTarget = Title::newFromLinkTarget( $oldTarget );
 +              $newTarget = Title::newFromLinkTarget( $newTarget );
  
                $this->duplicateEntry( $oldTarget->getSubjectPage(), $newTarget->getSubjectPage() );
                $this->duplicateEntry( $oldTarget->getTalkPage(), $newTarget->getTalkPage() );