/**
  * @param array $updates Array of arrays each containing two keys, 'primaryKey'
  *  and 'changes'. primaryKey must contain a map of column names to values
  *  sufficient to uniquely identify the row changes must contain a map of column
  *  names to update values to apply to the row.
  */
 public function write(array $updates)
 {
     $this->db->begin();
     foreach ($updates as $update) {
         $this->db->update($this->table, $update['changes'], $update['primaryKey'], __METHOD__);
     }
     $this->db->commit();
     wfWaitForSlaves(false, false, $this->clusterName);
 }
Example #2
0
 function updateUserWikiCount(DatabaseBase $db, $userId, $wikiCount)
 {
     $res = $db->update("webmaster_user_accounts", array("wikis_number" => $wikiCount), array("user_id" => $userId));
     if (!$res) {
         throw new Exception("Failed to update User id=" . $userId . " count = " . $wikiCount);
     }
 }
Example #3
0
 /**
  * Merge page histories
  *
  * @param integer $id The page_id
  * @param Title $newTitle The new title
  * @return bool
  */
 private function mergePage($row, Title $newTitle)
 {
     $id = $row->page_id;
     // Construct the WikiPage object we will need later, while the
     // page_id still exists. Note that this cannot use makeTitleSafe(),
     // we are deliberately constructing an invalid title.
     $sourceTitle = Title::makeTitle($row->page_namespace, $row->page_title);
     $sourceTitle->resetArticleID($id);
     $wikiPage = new WikiPage($sourceTitle);
     $wikiPage->loadPageData('fromdbmaster');
     $destId = $newTitle->getArticleId();
     $this->beginTransaction($this->db, __METHOD__);
     $this->db->update('revision', array('rev_page' => $destId), array('rev_page' => $id), __METHOD__);
     $this->db->delete('page', array('page_id' => $id), __METHOD__);
     /* Call LinksDeletionUpdate to delete outgoing links from the old title,
      * and update category counts.
      *
      * Calling external code with a fake broken Title is a fairly dubious
      * idea. It's necessary because it's quite a lot of code to duplicate,
      * but that also makes it fragile since it would be easy for someone to
      * accidentally introduce an assumption of title validity to the code we
      * are calling.
      */
     $update = new LinksDeletionUpdate($wikiPage);
     $update->doUpdate();
     $this->commitTransaction($this->db, __METHOD__);
     return true;
 }
 /**
  * @param ResultWrapper $res
  * @param DatabaseBase $dbw
  * @return null|int
  */
 function convertOptionBatch($res, $dbw)
 {
     $id = null;
     foreach ($res as $row) {
         $this->mConversionCount++;
         $insertRows = array();
         foreach (explode("\n", $row->user_options) as $s) {
             $m = array();
             if (!preg_match("/^(.[^=]*)=(.*)\$/", $s, $m)) {
                 continue;
             }
             // MW < 1.16 would save even default values. Filter them out
             // here (as in User) to avoid adding many unnecessary rows.
             $defaultOption = User::getDefaultOption($m[1]);
             if (is_null($defaultOption) || $m[2] != $defaultOption) {
                 $insertRows[] = array('up_user' => $row->user_id, 'up_property' => $m[1], 'up_value' => $m[2]);
             }
         }
         if (count($insertRows)) {
             $dbw->insert('user_properties', $insertRows, __METHOD__, array('IGNORE'));
         }
         $dbw->update('user', array('user_options' => ''), array('user_id' => $row->user_id), __METHOD__);
         $id = $row->user_id;
     }
     return $id;
 }
 /**
  * Resolve a given conflict
  *
  * @param $row Object: row from the old broken entry
  * @param $table String: table to update
  * @param $prefix String: prefix for column name, like page or ar
  * @return bool
  */
 private function resolveConflictOn($row, $table, $prefix)
 {
     $this->output("... resolving on {$table}... ");
     $newTitle = Title::makeTitleSafe($row->namespace, $row->title);
     $this->db->update($table, array("{$prefix}_namespace" => $newTitle->getNamespace(), "{$prefix}_title" => $newTitle->getDBkey()), array("{$prefix}_id" => $row->id), __METHOD__);
     $this->output("ok.\n");
     return true;
 }
Example #6
0
 /**
  * Sets the number of active users in the site_stats table
  */
 protected function doActiveUsersInit()
 {
     $activeUsers = $this->db->selectField('site_stats', 'ss_active_users', false, __METHOD__);
     if ($activeUsers == -1) {
         $activeUsers = $this->db->selectField('recentchanges', 'COUNT( DISTINCT rc_user_text )', array('rc_user != 0', 'rc_bot' => 0, "rc_log_type != 'newusers'"), __METHOD__);
         $this->db->update('site_stats', array('ss_active_users' => intval($activeUsers)), array('ss_row_id' => 1), __METHOD__, array('LIMIT' => 1));
     }
     $this->output("...ss_active_users user count set...\n");
 }
 /**
  * @see PropertyStatisticsStore::setUsageCount
  *
  * @since 1.9
  *
  * @param integer $propertyId
  * @param integer $value
  *
  * @return boolean Success indicator
  * @throws MWException
  */
 public function setUsageCount($propertyId, $value)
 {
     if (!is_int($value) || $value < 0) {
         throw new MWException('The value to add must be a positive integer');
     }
     if (!is_int($propertyId) || $propertyId <= 0) {
         throw new MWException('The property id to add must be a positive integer');
     }
     return $this->dbConnection->update($this->table, array('usage_count' => $value), array('p_id' => $propertyId), __METHOD__);
 }
 /**
  * Merge page histories
  *
  * @param integer $id The page_id
  * @param Title $newTitle The new title
  */
 private function mergePage($id, Title $newTitle)
 {
     $destId = $newTitle->getArticleId();
     $this->db->begin(__METHOD__);
     $this->db->update('revision', array('rev_page' => $destId), array('rev_page' => $id), __METHOD__);
     $this->db->delete('page', array('page_id' => $id), __METHOD__);
     // @fixme Need WikiPage::doDeleteUpdates() or similar to avoid orphan
     // rows in the links tables.
     $this->db->commit(__METHOD__);
     return true;
 }
 /**
  * Refreshes a batch of recentchanges entries
  *
  * @param DatabaseBase $dbw
  * @param int[optional] $continue The next batch starting at rc_id
  * @return int Start id for the next batch
  */
 public function refreshBatch(DatabaseBase $dbw, $continue = null)
 {
     $rows = $dbw->select('recentchanges', array('rc_id', 'rc_params'), array("rc_id > {$continue}", 'rc_type' => RC_FLOW), __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => 'rc_id'));
     $continue = null;
     foreach ($rows as $row) {
         $continue = $row->rc_id;
         // build params
         wfSuppressWarnings();
         $params = unserialize($row->rc_params);
         wfRestoreWarnings();
         if (!$params) {
             $params = array();
         }
         // Don't fix entries that have been dealt with already
         if (!isset($params['flow-workflow-change']['type'])) {
             continue;
         }
         // Set action, based on older 'type' values
         switch ($params['flow-workflow-change']['type']) {
             case 'flow-rev-message-edit-title':
             case 'flow-edit-title':
                 $params['flow-workflow-change']['action'] = 'edit-title';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-new-post':
             case 'flow-new-post':
                 $params['flow-workflow-change']['action'] = 'new-post';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-edit-post':
             case 'flow-edit-post':
                 $params['flow-workflow-change']['action'] = 'edit-post';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-reply':
             case 'flow-reply':
                 $params['flow-workflow-change']['action'] = 'reply';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-restored-post':
             case 'flow-post-restored':
                 $params['flow-workflow-change']['action'] = 'restore-post';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-hid-post':
             case 'flow-post-hidden':
                 $params['flow-workflow-change']['action'] = 'hide-post';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-deleted-post':
             case 'flow-post-deleted':
                 $params['flow-workflow-change']['action'] = 'delete-post';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-censored-post':
             case 'flow-post-censored':
                 $params['flow-workflow-change']['action'] = 'suppress-post';
                 $params['flow-workflow-change']['block'] = 'topic';
                 $params['flow-workflow-change']['revision_type'] = 'PostRevision';
                 break;
             case 'flow-rev-message-edit-header':
             case 'flow-edit-summary':
                 $params['flow-workflow-change']['action'] = 'edit-header';
                 $params['flow-workflow-change']['block'] = 'header';
                 $params['flow-workflow-change']['revision_type'] = 'Header';
                 break;
             case 'flow-rev-message-create-header':
             case 'flow-create-summary':
             case 'flow-create-header':
                 $params['flow-workflow-change']['action'] = 'create-header';
                 $params['flow-workflow-change']['block'] = 'header';
                 $params['flow-workflow-change']['revision_type'] = 'Header';
                 break;
         }
         unset($params['flow-workflow-change']['type']);
         // update log entry
         $dbw->update('recentchanges', array('rc_params' => serialize($params)), array('rc_id' => $row->rc_id));
         $this->completeCount++;
     }
     return $continue;
 }
 public function updateRevision($columnPrefix, DatabaseBase $dbw, $continue = null)
 {
     $rows = $dbw->select('flow_revision', array('rev_id', 'rev_type'), array('rev_id > ' . $dbw->addQuotes($continue), "{$columnPrefix}_id > 0", "{$columnPrefix}_ip IS NOT NULL"), __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => 'rev_id'));
     $ids = $objs = array();
     foreach ($rows as $row) {
         $id = UUID::create($row->rev_id);
         $type = self::$types[$row->rev_type];
         $om = $this->storage->getStorage($type);
         $obj = $om->get($id);
         if ($obj) {
             $om->merge($obj);
             $ids[] = $row->rev_id;
             $objs[] = $obj;
         } else {
             $this->error(__METHOD__ . ": Failed loading {$type}: " . $id->getAlphadecimal());
         }
     }
     if (!$ids) {
         return null;
     }
     $dbw->update('flow_revision', array("{$columnPrefix}_ip" => null), array('rev_id' => $ids), __METHOD__);
     foreach ($objs as $obj) {
         $this->storage->cachePurge($obj);
     }
     $this->completeCount += count($ids);
     return end($ids);
 }
Example #11
0
 /**
  * Update the page record to point to a newly saved revision.
  *
  * @param DatabaseBase $dbw
  * @param Revision $revision For ID number, and text used to set
  *   length and redirect status fields
  * @param int $lastRevision If given, will not overwrite the page field
  *   when different from the currently set value.
  *   Giving 0 indicates the new page flag should be set on.
  * @param bool $lastRevIsRedirect If given, will optimize adding and
  *   removing rows in redirect table.
  * @return bool True on success, false on failure
  */
 public function updateRevisionOn($dbw, $revision, $lastRevision = null, $lastRevIsRedirect = null)
 {
     global $wgContentHandlerUseDB;
     wfProfileIn(__METHOD__);
     $content = $revision->getContent();
     $len = $content ? $content->getSize() : 0;
     $rt = $content ? $content->getUltimateRedirectTarget() : null;
     $conditions = array('page_id' => $this->getId());
     if (!is_null($lastRevision)) {
         // An extra check against threads stepping on each other
         $conditions['page_latest'] = $lastRevision;
     }
     $now = wfTimestampNow();
     $row = array('page_latest' => $revision->getId(), 'page_touched' => $dbw->timestamp($now), 'page_is_new' => $lastRevision === 0 ? 1 : 0, 'page_is_redirect' => $rt !== null ? 1 : 0, 'page_len' => $len);
     if ($wgContentHandlerUseDB) {
         $row['page_content_model'] = $revision->getContentModel();
     }
     $dbw->update('page', $row, $conditions, __METHOD__);
     $result = $dbw->affectedRows() > 0;
     if ($result) {
         $this->updateRedirectOn($dbw, $rt, $lastRevIsRedirect);
         $this->setLastEdit($revision);
         $this->setCachedLastEditTime($now);
         $this->mLatest = $revision->getId();
         $this->mIsRedirect = (bool) $rt;
         // Update the LinkCache.
         LinkCache::singleton()->addGoodLinkObj($this->getId(), $this->mTitle, $len, $this->mIsRedirect, $this->mLatest, $revision->getContentModel());
     }
     wfProfileOut(__METHOD__);
     return $result;
 }
Example #12
0
 /**
  * @param array $updates Array of arrays each containing two keys, 'primaryKey' and 'changes'.
  *   primaryKey must contain a map of column names to values sufficient to uniquely identify the row
  *   changes must contain a map of column names to update values to apply to the row
  */
 public function write(array $updates)
 {
     $this->db->begin();
     foreach ($updates as $id => $update) {
         //echo "Updating: ";var_dump( $update['primaryKey'] );
         //echo "With values: ";var_dump( $update['changes'] );
         $this->db->update($this->table, $update['changes'], $update['primaryKey'], __METHOD__);
     }
     $this->db->commit();
     wfWaitForSlaves(false, false, $this->clusterName);
 }
 /**
  * Helper function to saveAdInternal() for saving basic ad metadata
  * @param DatabaseBase $db
  */
 protected function saveBasicData($db)
 {
     if ($this->dirtyFlags['basic']) {
         $db->update('pr_ads', array('ad_display_anon' => (int) $this->allocateAnon, 'ad_display_user' => (int) $this->allocateUser, 'ad_title' => $this->adCaption, 'ad_mainlink' => $this->adLink), array('ad_id' => $this->id), __METHOD__);
     }
 }
 /**
  * Change the usage count for the property of the given ID by the given
  * value. The method does nothing if the count is 0.
  *
  * @since 1.8
  * @param integer $propertyId
  * @param integer $value
  * @param DatabaseBase $dbw used for writing
  * @return boolean success indicator
  */
 protected function addToPropertyUsageCount($propertyId, $value, DatabaseBase $dbw)
 {
     if ($value == 0) {
         return true;
     }
     return $dbw->update(SMWSQLStore3::PROPERTY_STATISTICS_TABLE, array('usage_count = usage_count + ' . $dbw->addQuotes($value)), array('p_id' => $propertyId), __METHOD__);
 }
 public function updateRevision(DatabaseBase $dbw, $continue = null)
 {
     $rows = $dbw->select('flow_revision', array('rev_id', 'rev_user_id', 'rev_user_text', 'rev_mod_user_id', 'rev_mod_user_text', 'rev_edit_user_id', 'rev_edit_user_text'), array('rev_id > ' . $dbw->addQuotes($continue), $dbw->makeList(array('rev_user_id' => 0, 'rev_mod_user_id' => 0, 'rev_edit_user_id' => 0), LIST_OR)), __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => 'rev_id'));
     $continue = null;
     foreach ($rows as $row) {
         $continue = $row->rev_id;
         $updates = array();
         if ($row->rev_user_id == 0) {
             $updates['rev_user_ip'] = $row->rev_user_text;
         }
         if ($row->rev_mod_user_id == 0) {
             $updates['rev_mod_user_ip'] = $row->rev_mod_user_text;
         }
         if ($row->rev_edit_user_id == 0) {
             $updates['rev_edit_user_ip'] = $row->rev_edit_user_text;
         }
         if ($updates) {
             $dbw->update('flow_revision', $updates, array('rev_id' => $row->rev_id), __METHOD__);
         }
     }
     return $continue;
 }
 /**
  * @param DatabaseBase $dbw
  * @return bool|mixed
  */
 public static function cacheUpdate($dbw)
 {
     global $wgActiveUserDays;
     $dbr = wfGetDB(DB_SLAVE, 'vslow');
     # Get non-bot users than did some recent action other than making accounts.
     # If account creation is included, the number gets inflated ~20+ fold on enwiki.
     $activeUsers = $dbr->selectField('recentchanges', 'COUNT( DISTINCT rc_user_text )', array('rc_user != 0', 'rc_bot' => 0, 'rc_log_type != ' . $dbr->addQuotes('newusers') . ' OR rc_log_type IS NULL', 'rc_timestamp >= ' . $dbr->addQuotes($dbr->timestamp(wfTimestamp(TS_UNIX) - $wgActiveUserDays * 24 * 3600))), __METHOD__);
     $dbw->update('site_stats', array('ss_active_users' => intval($activeUsers)), array('ss_row_id' => 1), __METHOD__);
     return $activeUsers;
 }
Example #17
0
 /**
  * Update the page record to point to a newly saved revision.
  *
  * @param DatabaseBase $dbw
  * @param Revision $revision For ID number, and text used to set
  *   length and redirect status fields
  * @param int $lastRevision If given, will not overwrite the page field
  *   when different from the currently set value.
  *   Giving 0 indicates the new page flag should be set on.
  * @param bool $lastRevIsRedirect If given, will optimize adding and
  *   removing rows in redirect table.
  * @return bool True on success, false on failure
  */
 public function updateRevisionOn($dbw, $revision, $lastRevision = null, $lastRevIsRedirect = null)
 {
     global $wgContentHandlerUseDB;
     // Assertion to try to catch T92046
     if ((int) $revision->getId() === 0) {
         throw new InvalidArgumentException(__METHOD__ . ': Revision has ID ' . var_export($revision->getId(), 1));
     }
     $content = $revision->getContent();
     $len = $content ? $content->getSize() : 0;
     $rt = $content ? $content->getUltimateRedirectTarget() : null;
     $conditions = array('page_id' => $this->getId());
     if (!is_null($lastRevision)) {
         // An extra check against threads stepping on each other
         $conditions['page_latest'] = $lastRevision;
     }
     $row = array('page_latest' => $revision->getId(), 'page_touched' => $dbw->timestamp($revision->getTimestamp()), 'page_is_new' => $lastRevision === 0 ? 1 : 0, 'page_is_redirect' => $rt !== null ? 1 : 0, 'page_len' => $len);
     if ($wgContentHandlerUseDB) {
         $row['page_content_model'] = $revision->getContentModel();
     }
     $dbw->update('page', $row, $conditions, __METHOD__);
     $result = $dbw->affectedRows() > 0;
     if ($result) {
         $this->updateRedirectOn($dbw, $rt, $lastRevIsRedirect);
         $this->setLastEdit($revision);
         $this->mLatest = $revision->getId();
         $this->mIsRedirect = (bool) $rt;
         // Update the LinkCache.
         LinkCache::singleton()->addGoodLinkObj($this->getId(), $this->mTitle, $len, $this->mIsRedirect, $this->mLatest, $revision->getContentModel());
     }
     return $result;
 }
 protected function populateRevisionOrArchive(DatabaseBase $dbw, $table, $ns)
 {
     $prefix = $table === 'archive' ? 'ar' : 'rev';
     $model_column = "{$prefix}_content_model";
     $format_column = "{$prefix}_content_format";
     $key = "{$prefix}_id";
     if ($table === 'archive') {
         $selectTables = 'archive';
         $fields = array('ar_namespace', 'ar_title');
         $join_conds = array();
         $where = $ns === 'all' ? array() : array('ar_namespace' => $ns);
     } else {
         // revision
         $selectTables = array('revision', 'page');
         $fields = array('page_title', 'page_namespace');
         $join_conds = array('page' => array('INNER JOIN', 'rev_page=page_id'));
         $where = $ns === 'all' ? array() : array('page_namespace' => $ns);
     }
     $toSave = array();
     $lastId = 0;
     do {
         $rows = $dbw->select($selectTables, array_merge($fields, array($model_column, $format_column, $key)), array($model_column => null, "{$key} > " . $dbw->addQuotes($lastId)) + $where, __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => "{$key} ASC"), $join_conds);
         $this->output("Fetched {$rows->numRows()} rows.\n");
         foreach ($rows as $row) {
             if ($table === 'archive') {
                 $title = Title::makeTitle($row->ar_namespace, $row->ar_title);
             } else {
                 $title = Title::newFromRow($row);
             }
             $lastId = $row->{$key};
             try {
                 $handler = ContentHandler::getForTitle($title);
             } catch (MWException $e) {
                 $this->error("Invalid content model for {$title}");
                 continue;
             }
             $defaultModel = $handler->getModelID();
             $defaultFormat = $handler->getDefaultFormat();
             $dbModel = $row->{$model_column};
             $dbFormat = $row->{$format_column};
             $id = $row->{$key};
             if ($dbModel === null && $dbFormat === null) {
                 // Set the defaults
                 $toSave[$defaultModel][] = $row->{$key};
             } else {
                 // $dbModel === null, $dbFormat set.
                 if ($dbFormat === $defaultFormat) {
                     $toSave[$defaultModel][] = $row->{$key};
                 } else {
                     // non-default format, just update now
                     $this->output("Updating model to match format for {$table} {$id} of {$title}... ");
                     $dbw->update($table, array($model_column => $defaultModel), array($key => $id), __METHOD__);
                     wfWaitForSlaves();
                     $this->output("done.\n");
                     continue;
                 }
             }
             if (count($toSave[$defaultModel]) >= $this->mBatchSize) {
                 $this->updateRevisionOrArchiveRows($dbw, $toSave[$defaultModel], $defaultModel, $table);
                 unset($toSave[$defaultModel]);
             }
         }
     } while ($rows->numRows() >= $this->mBatchSize);
     foreach ($toSave as $model => $ids) {
         $this->updateRevisionOrArchiveRows($dbw, $ids, $model, $table);
     }
 }
 protected function updateStatus($name, $wiki, $status)
 {
     $this->db->update('users_to_rename', array('utr_status' => $status), array('utr_wiki' => $wiki, 'utr_name' => $name), __METHOD__);
 }
Example #20
0
 /**
  * Changes the page title
  * 
  * @param $id int Page id of the page
  * @param $title Title New title of the page
  */
 public function moveTo($id, $title)
 {
     $this->db->update('globalimagelinks', array('gil_page_namespace_id' => $title->getNamespace(), 'gil_page_namespace' => $title->getNsText(), 'gil_page_title' => $title->getDBkey()), array('gil_wiki' => $this->interwiki, 'gil_page' => $id), __METHOD__);
 }