/**
  * Deletes a range of subscriptions.
  *
  * @param string $minId Entity id string indicating the first element in the deletion range
  * @param string $maxId Entity id string indicating the last element in the deletion range
  */
 private function deleteSubscriptionRange($minId, $maxId)
 {
     $dbw = $this->repoConnectionManager->beginAtomicSection(__METHOD__);
     $conditions = array('cs_subscriber_id' => $this->subscriberWikiId, 'cs_entity_id >= ' . $dbw->addQuotes($minId), 'cs_entity_id <= ' . $dbw->addQuotes($maxId));
     $dbw->delete('wb_changes_subscription', $conditions, __METHOD__);
     $this->repoConnectionManager->commitAtomicSection($dbw, __METHOD__);
 }
 /**
  * @see UsageLookup::getUnusedEntities
  *
  * @param EntityId[] $entityIds
  *
  * @return EntityId[]
  * @throws UsageTrackerException
  */
 public function getUnusedEntities(array $entityIds)
 {
     if (empty($entityIds)) {
         return array();
     }
     $db = $this->connectionManager->getReadConnection();
     $usageTable = $this->newUsageTable($db);
     $unused = $usageTable->getUnusedEntities($entityIds);
     $this->connectionManager->releaseConnection($db);
     return $unused;
 }
 /**
  * Checks if a recent change entry already exists in the recentchanges table
  *
  * @since 0.4
  *
  * @param RecentChange $change
  *
  * @throws MWException
  * @return bool
  */
 public function changeExists(RecentChange $change)
 {
     $attribs = $change->getAttributes();
     //XXX: need to check master?
     $db = $this->connectionManager->getReadConnection();
     $res = $db->select('recentchanges', array('rc_id', 'rc_timestamp', 'rc_type', 'rc_params'), array('rc_namespace' => $attribs['rc_namespace'], 'rc_title' => $attribs['rc_title'], 'rc_timestamp' => $attribs['rc_timestamp'], 'rc_type' => RC_EXTERNAL), __METHOD__);
     if ($res->numRows() === 0) {
         return false;
     }
     $changeMetadata = $this->getMetadata($attribs['rc_params']);
     $changeRevId = $changeMetadata['rev_id'];
     $changeParentId = $changeMetadata['parent_id'];
     foreach ($res as $rc) {
         $metadata = $this->getMetadata($rc->rc_params);
         $parent_id = $metadata['parent_id'];
         $rev_id = $metadata['rev_id'];
         if ($rev_id === $changeRevId && $parent_id === $changeParentId) {
             return true;
         }
     }
     $this->connectionManager->releaseConnection($db);
     return false;
 }
 /**
  * @see SubscriptionManager::unsubscribe
  *
  * @param string $subscriber Global site ID of the client
  * @param EntityId[] $entityIds The entities to subscribe to.
  *
  * @throws InvalidArgumentException
  * @throws UsageTrackerException
  * @throws Exception
  */
 public function unsubscribe($subscriber, array $entityIds)
 {
     if (!is_string($subscriber)) {
         throw new InvalidArgumentException('$subscriber must be a string.');
     }
     $unsubscriptions = $this->idsToString($entityIds);
     $db = $this->connectionManager->beginAtomicSection(__METHOD__);
     try {
         $oldSubscriptions = $this->querySubscriptions($db, $subscriber, $unsubscriptions);
         $obsoleteSubscriptions = array_intersect($unsubscriptions, $oldSubscriptions);
         $this->deleteSubscriptions($db, $subscriber, $obsoleteSubscriptions);
         $this->connectionManager->commitAtomicSection($db, __METHOD__);
     } catch (Exception $ex) {
         $this->connectionManager->rollbackAtomicSection($db, __METHOD__);
         if ($ex instanceof DBError) {
             throw new UsageTrackerException($ex->getMessage(), $ex->getCode(), $ex);
         } else {
             throw $ex;
         }
     }
 }
 public function testRollbackAtomicSection()
 {
     $connection = $this->getConnectionMock();
     $lb = $this->getLoadBalancerMock();
     $lb->expects($this->once())->method('reuseConnection')->with($connection)->will($this->returnValue(null));
     $connection->expects($this->once())->method('rollback')->will($this->returnValue(null));
     $manager = new ConsistentReadConnectionManager($lb);
     $manager->rollbackAtomicSection($connection, 'TEST');
 }