jenkins-bot has submitted this change and it was merged.

Change subject: Move WatchedItem::duplicateEntries to WatchedItemStore
......................................................................


Move WatchedItem::duplicateEntries to WatchedItemStore

This removes static logic from WatchedItem into a
class that we can slowly fill with watchlist database
and storage things.

This also removes the dual namespace handling in
the new implementation.

Change-Id: Ia67ab1d200ac393c65013b2091e61acefcb3defb
---
M autoload.php
M includes/WatchedItem.php
A includes/WatchedItemStore.php
A tests/phpunit/includes/WatchedItemStoreTest.php
4 files changed, 185 insertions(+), 55 deletions(-)

Approvals:
  Daniel Kinzler: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/autoload.php b/autoload.php
index 83ca3b3..87d0c7c 100644
--- a/autoload.php
+++ b/autoload.php
@@ -1401,6 +1401,7 @@
        'WantedTemplatesPage' => __DIR__ . 
'/includes/specials/SpecialWantedtemplates.php',
        'WatchAction' => __DIR__ . '/includes/actions/WatchAction.php',
        'WatchedItem' => __DIR__ . '/includes/WatchedItem.php',
+       'WatchedItemStore' => __DIR__ . '/includes/WatchedItemStore.php',
        'WatchlistCleanup' => __DIR__ . '/maintenance/cleanupWatchlist.php',
        'WebInstaller' => __DIR__ . '/includes/installer/WebInstaller.php',
        'WebInstallerComplete' => __DIR__ . 
'/includes/installer/WebInstallerComplete.php',
diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php
index 2c400d0..b597f99 100644
--- a/includes/WatchedItem.php
+++ b/includes/WatchedItem.php
@@ -379,63 +379,15 @@
        }
 
        /**
-        * Check if the given title already is watched by the user, and if so
-        * add watches on a new title. To be used for page renames and such.
+        * @deprecated since 1.27. See WatchedItemStore::duplicateEntry
         *
-        * @param Title $ot Page title to duplicate entries from, if present
-        * @param Title $nt Page title to add watches on
+        * @param Title $oldTitle
+        * @param Title $newTitle
         */
-       public static function duplicateEntries( $ot, $nt ) {
-               WatchedItem::doDuplicateEntries( $ot->getSubjectPage(), 
$nt->getSubjectPage() );
-               WatchedItem::doDuplicateEntries( $ot->getTalkPage(), 
$nt->getTalkPage() );
+       public static function duplicateEntries( Title $oldTitle, Title 
$newTitle ) {
+               $store = WatchedItemStore::getDefaultInstance();
+               $store->duplicateEntry( $oldTitle->getSubjectPage(), 
$newTitle->getSubjectPage() );
+               $store->duplicateEntry( $oldTitle->getTalkPage(), 
$newTitle->getTalkPage() );
        }
 
-       /**
-        * Handle duplicate entries. Backend for duplicateEntries().
-        *
-        * @param Title $ot
-        * @param Title $nt
-        *
-        * @return bool
-        */
-       private static function doDuplicateEntries( $ot, $nt ) {
-               $oldnamespace = $ot->getNamespace();
-               $newnamespace = $nt->getNamespace();
-               $oldtitle = $ot->getDBkey();
-               $newtitle = $nt->getDBkey();
-
-               $dbw = wfGetDB( DB_MASTER );
-               $res = $dbw->select( 'watchlist',
-                       [ 'wl_user', 'wl_notificationtimestamp' ],
-                       [ 'wl_namespace' => $oldnamespace, 'wl_title' => 
$oldtitle ],
-                       __METHOD__, 'FOR UPDATE'
-               );
-               # Construct array to replace into the watchlist
-               $values = [];
-               foreach ( $res as $s ) {
-                       $values[] = [
-                               'wl_user' => $s->wl_user,
-                               'wl_namespace' => $newnamespace,
-                               'wl_title' => $newtitle,
-                               'wl_notificationtimestamp' => 
$s->wl_notificationtimestamp,
-                       ];
-               }
-
-               if ( empty( $values ) ) {
-                       // Nothing to do
-                       return true;
-               }
-
-               # Perform replace
-               # Note that multi-row replace is very efficient for MySQL but 
may be inefficient for
-               # some other DBMSes, mostly due to poor simulation by us
-               $dbw->replace(
-                       'watchlist',
-                       [ [ 'wl_user', 'wl_namespace', 'wl_title' ] ],
-                       $values,
-                       __METHOD__
-               );
-
-               return true;
-       }
 }
diff --git a/includes/WatchedItemStore.php b/includes/WatchedItemStore.php
new file mode 100644
index 0000000..83a5856
--- /dev/null
+++ b/includes/WatchedItemStore.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * Storage layer class for WatchedItems.
+ * Database interaction
+ *
+ * @author Addshore
+ *
+ * @since 1.27
+ */
+class WatchedItemStore {
+
+       /**
+        * @var LoadBalancer
+        */
+       private $loadBalancer;
+
+       public function __construct( LoadBalancer $loadBalancer ) {
+               $this->loadBalancer = $loadBalancer;
+       }
+
+       /**
+        * @return self
+        */
+       public static function getDefaultInstance() {
+               static $instance;
+               if ( !$instance ) {
+                       $instance = new self( wfGetLB() );
+               }
+               return $instance;
+       }
+
+       /**
+        * Check if the given title already is watched by the user, and if so
+        * add a watch for the new title.
+        *
+        * To be used for page renames and such.
+        * This must be called separately for Subject and Talk pages
+        *
+        * @param LinkTarget $oldTarget
+        * @param LinkTarget $newTarget
+        */
+       public function duplicateEntry( LinkTarget $oldTarget, LinkTarget 
$newTarget ) {
+               $dbw = $this->loadBalancer->getConnection( DB_MASTER, [ 
'watchlist' ] );
+
+               $result = $dbw->select(
+                       'watchlist',
+                       [ 'wl_user', 'wl_notificationtimestamp' ],
+                       [
+                               'wl_namespace' => $oldTarget->getNamespace(),
+                               'wl_title' => $oldTarget->getDBkey(),
+                       ],
+                       __METHOD__,
+                       [ 'FOR UPDATE' ]
+               );
+
+               $newNamespace = $newTarget->getNamespace();
+               $newDBkey = $newTarget->getDBkey();
+
+               # Construct array to replace into the watchlist
+               $values = [];
+               foreach ( $result as $row ) {
+                       $values[] = [
+                               'wl_user' => $row->wl_user,
+                               'wl_namespace' => $newNamespace,
+                               'wl_title' => $newDBkey,
+                               'wl_notificationtimestamp' => 
$row->wl_notificationtimestamp,
+                       ];
+               }
+
+               if ( !empty( $values ) ) {
+                       # Perform replace
+                       # Note that multi-row replace is very efficient for 
MySQL but may be inefficient for
+                       # some other DBMSes, mostly due to poor simulation by us
+                       $dbw->replace(
+                               'watchlist',
+                               [ [ 'wl_user', 'wl_namespace', 'wl_title' ] ],
+                               $values,
+                               __METHOD__
+                       );
+               }
+
+               $this->loadBalancer->reuseConnection( $dbw );
+       }
+
+}
diff --git a/tests/phpunit/includes/WatchedItemStoreTest.php 
b/tests/phpunit/includes/WatchedItemStoreTest.php
new file mode 100644
index 0000000..fc132b0
--- /dev/null
+++ b/tests/phpunit/includes/WatchedItemStoreTest.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @author Addshore
+ *
+ * @covers WatchedItemStore
+ */
+class WatchedItemStoreTest extends PHPUnit_Framework_TestCase {
+
+       /**
+        * @return PHPUnit_Framework_MockObject_MockObject|IDatabase
+        */
+       private function getMockDb() {
+               return $this->getMock( 'IDatabase' );
+       }
+
+       /**
+        * @return PHPUnit_Framework_MockObject_MockObject|LoadBalancer
+        */
+       private function getMockLoadBalancer( $mockDb ) {
+               $mock = $this->getMockBuilder( 'LoadBalancer' )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mock->expects( $this->any() )
+                       ->method( 'getConnection' )
+                       ->will( $this->returnValue( $mockDb ) );
+               return $mock;
+       }
+
+       private function getFakeRow( $userId, $timestamp ) {
+               $fakeRow = new stdClass();
+               $fakeRow->wl_user = $userId;
+               $fakeRow->wl_notificationtimestamp = $timestamp;
+               return $fakeRow;
+       }
+
+       public function testDuplicateEntry_nothingToDuplicate() {
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->exactly( 1 ) )
+                       ->method( 'select' )
+                       ->will( $this->returnValue( new FakeResultWrapper( [] ) 
) );
+
+               $store = new WatchedItemStore( $this->getMockLoadBalancer( 
$mockDb ) );
+
+               $store->duplicateEntry(
+                       Title::newFromText( 'Old_Title' ),
+                       Title::newFromText( 'New_Title' )
+               );
+       }
+
+       public function testDuplicateEntry_somethingToDuplicate() {
+               $fakeRows = [
+                       $this->getFakeRow( 1, '20151212010101' ),
+                       $this->getFakeRow( 2, null ),
+               ];
+
+               $mockDb = $this->getMockDb();
+               $mockDb->expects( $this->at( 0 ) )
+                       ->method( 'select' )
+                       ->will( $this->returnValue( new FakeResultWrapper( 
$fakeRows ) ) );
+               $mockDb->expects( $this->at( 1 ) )
+                       ->method( 'replace' )
+                       ->with(
+                               'watchlist',
+                               [ [ 'wl_user', 'wl_namespace', 'wl_title' ] ],
+                               [
+                                       [
+                                               'wl_user' => 1,
+                                               'wl_namespace' => 0,
+                                               'wl_title' => 'New_Title',
+                                               'wl_notificationtimestamp' => 
'20151212010101',
+                                       ],
+                                       [
+                                               'wl_user' => 2,
+                                               'wl_namespace' => 0,
+                                               'wl_title' => 'New_Title',
+                                               'wl_notificationtimestamp' => 
null,
+                                       ],
+                               ],
+                               $this->isType( 'string' )
+                       );
+
+               $store = new WatchedItemStore( $this->getMockLoadBalancer( 
$mockDb ) );
+
+               $store->duplicateEntry(
+                       Title::newFromText( 'Old_Title' ),
+                       Title::newFromText( 'New_Title' )
+               );
+       }
+
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/266524
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia67ab1d200ac393c65013b2091e61acefcb3defb
Gerrit-PatchSet: 17
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Addshore <addshorew...@gmail.com>
Gerrit-Reviewer: Aaron Schulz <asch...@wikimedia.org>
Gerrit-Reviewer: Addshore <addshorew...@gmail.com>
Gerrit-Reviewer: Anomie <bjor...@wikimedia.org>
Gerrit-Reviewer: Aude <aude.w...@gmail.com>
Gerrit-Reviewer: Bene <benestar.wikime...@gmail.com>
Gerrit-Reviewer: Catrope <roan.katt...@gmail.com>
Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de>
Gerrit-Reviewer: Fhocutt <fhoc...@wikimedia.org>
Gerrit-Reviewer: Hoo man <h...@online.de>
Gerrit-Reviewer: Kai Nissen (WMDE) <kai.nis...@wikimedia.de>
Gerrit-Reviewer: Kaldari <rkald...@wikimedia.org>
Gerrit-Reviewer: Legoktm <legoktm.wikipe...@gmail.com>
Gerrit-Reviewer: Niharika29 <nihar...@wikimedia.org>
Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de>
Gerrit-Reviewer: WMDE-Fisch <christoph.fisc...@wikimedia.de>
Gerrit-Reviewer: WMDE-leszek <leszek.mani...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to