Esempio n. 1
0
 /**
  * Remove a batch of users
  *
  * @param DatabaseBase $dbw
  * @param int[] $batch list of user IDs to remove
  */
 private function removeBatch(DatabaseBase $dbw, array $batch)
 {
     $rows = 0;
     $dbw->begin(__METHOD__);
     // remove entries from user table
     $dbw->delete(self::USER_TABLE, ['user_id' => $batch], __METHOD__);
     $rows += $dbw->affectedRows();
     // remove entries from user_properties table
     $dbw->delete('user_properties', ['up_user' => $batch], __METHOD__);
     $rows += $dbw->affectedRows();
     $dbw->commit(__METHOD__);
     $this->info('Batch removed', ['batch' => count($batch), 'rows' => $rows]);
 }
Esempio n. 2
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;
 }
 /**
  * Delete one or more revisions from the database
  * Do this inside a transaction
  *
  * @param array $id Array of revision id values
  * @param DatabaseBase $dbw DatabaseBase class (needs to be a master)
  */
 private function deleteRevs($id, &$dbw)
 {
     if (!is_array($id)) {
         $id = array($id);
     }
     $dbw->delete('revision', array('rev_id' => $id), __METHOD__);
 }
Esempio n. 4
0
 /**
  * Empty all tables so they can be repopulated for tests
  */
 private function resetDB()
 {
     if ($this->db) {
         if ($this->db->getType() == 'oracle') {
             if (self::$useTemporaryTables) {
                 wfGetLB()->closeAll();
                 $this->db = wfGetDB(DB_MASTER);
             } else {
                 foreach ($this->tablesUsed as $tbl) {
                     if ($tbl == 'interwiki') {
                         continue;
                     }
                     $this->db->query('TRUNCATE TABLE ' . $this->db->tableName($tbl), __METHOD__);
                 }
             }
         } else {
             foreach ($this->tablesUsed as $tbl) {
                 if ($tbl == 'interwiki' || $tbl == 'user') {
                     continue;
                 }
                 $this->db->delete($tbl, '*', __METHOD__);
             }
         }
     }
 }
Esempio n. 5
0
 /**
  * Purge the objectcache table
  */
 protected function purgeCache()
 {
     # We can't guarantee that the user will be able to use TRUNCATE,
     # but we know that DELETE is available to us
     $this->output("Purging caches...");
     $this->db->delete('objectcache', '*', __METHOD__);
     $this->output("done.\n");
 }
 /**
  * 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;
 }
Esempio n. 7
0
 /**
  * Empty all tables so they can be repopulated for tests
  */
 private function resetDB()
 {
     if ($this->db) {
         foreach ($this->listTables() as $tbl) {
             if ($tbl == 'interwiki' || $tbl == 'user') {
                 continue;
             }
             $this->db->delete($tbl, '*', __METHOD__);
         }
     }
 }
Esempio n. 8
0
	/**
	 * Purge the objectcache table
	 */
	public function purgeCache() {
		global $wgLocalisationCacheConf;
		# We can't guarantee that the user will be able to use TRUNCATE,
		# but we know that DELETE is available to us
		$this->output( "Purging caches..." );
		$this->db->delete( 'objectcache', '*', __METHOD__ );
		if ( $wgLocalisationCacheConf['manualRecache'] ) {
			$this->rebuildLocalisationCache();
		}
		MessageBlobStore::clear();
		$this->output( "done.\n" );
	}
Esempio n. 9
0
 /**
  * Perform a cleanup for a set of wikis
  *
  * @param DatabaseBase $db database handler
  * @param string $table name of table to clean up
  * @param string $wiki_id_column table column name to use when querying for wiki ID
  * @param Array $city_ids IDs of wikis to remove from the table
  */
 private function doTableCleanup(DatabaseBase $db, $table, array $city_ids, $wiki_id_column = 'wiki_id')
 {
     $start = microtime(true);
     $db->delete($table, [$wiki_id_column => $city_ids], __METHOD__);
     $rows = $db->affectedRows();
     // just in case MW decides to start a transaction automagically
     $db->commit(__METHOD__);
     Wikia\Logger\WikiaLogger::instance()->info(__METHOD__, ['table' => $table, 'cities' => join(', ', $city_ids), 'count' => count($city_ids), 'took' => round(microtime(true) - $start, 4), 'rows' => $rows]);
     $this->output(sprintf("%s: %s - removed %d rows\n", date('Y-m-d H:i:s'), $table, $rows));
     // throttle delete queries
     if ($rows > 0) {
         sleep(5);
     }
 }
Esempio n. 10
0
 public function delete($table, $conds, $fname = 'DatabaseOracle::delete')
 {
     global $wgContLang;
     if ($wgContLang != null && $conds != null && $conds != '*') {
         $conds2 = array();
         $conds = !is_array($conds) ? array($conds) : $conds;
         foreach ($conds as $col => $val) {
             $col_info = $this->fieldInfoMulti($table, $col);
             $col_type = $col_info != false ? $col_info->type() : 'CONSTANT';
             if ($col_type == 'CLOB') {
                 $conds2['TO_CHAR(' . $col . ')'] = $wgContLang->checkTitleEncoding($val);
             } else {
                 if (is_array($val)) {
                     $conds2[$col] = $val;
                     foreach ($conds2[$col] as &$val2) {
                         $val2 = $wgContLang->checkTitleEncoding($val2);
                     }
                 } else {
                     $conds2[$col] = $wgContLang->checkTitleEncoding($val);
                 }
             }
         }
         return parent::delete($table, $conds2, $fname);
     } else {
         return parent::delete($table, $conds, $fname);
     }
 }
Esempio n. 11
0
 public function delete($table, $conds, $fname = __METHOD__)
 {
     $this->mScrollableCursor = false;
     try {
         parent::delete($table, $conds, $fname);
     } catch (Exception $e) {
         $this->mScrollableCursor = true;
         throw $e;
     }
     $this->mScrollableCursor = true;
 }
Esempio n. 12
0
 /**
  * Update one property table by inserting or deleting rows, and compute
  * the changes that this entails for the property usage counts. The
  * given rows are inserted into the table if $insert is true; otherwise
  * they are deleted. The property usage counts are recorded in the
  * call-by-ref parameter $propertyUseIncrements.
  *
  * The method assumes that all of the given rows are about the same
  * subject. This is ensured by callers.
  *
  * @since 1.8
  * @param array $propertyUseIncrements
  * @param SMWSQLStore3Table $propertyTable
  * @param array $rows array of rows to insert/delete
  * @param boolean $insert
  * @param DatabaseBase $dbw used for writing
  */
 protected function writePropertyTableRowUpdates(array &$propertyUseIncrements, SMWSQLStore3Table $propertyTable, array $rows, $insert, DatabaseBase $dbw)
 {
     if (empty($rows)) {
         //print "Nothing to " . ( $insert ? 'insert' : 'delete' ) . " for table {$propertyTable->getName()}.\n"; //DEBUG
         return;
     }
     //print ( $insert ? 'Inserting ' : 'Deleting ' ) . count( $rows ) . " row(s) in table {$propertyTable->getName()}.\n"; //DEBUG
     //print var_export( $rows, true ) . "\n"; //DEBUG
     if (!$propertyTable->usesIdSubject()) {
         // does not occur, but let's be strict
         throw new InvalidArgumentException('Operation not supported for tables without subject IDs.');
     }
     if ($insert) {
         $dbw->insert($propertyTable->getName(), array_values($rows), "SMW::writePropertyTableRowUpdates-insert-{$propertyTable->getName()}");
     } else {
         $condition = '';
         // We build a condition that mentions s_id only once,
         // since it must be the same for all rows. This should
         // help the DBMS in selecting the rows (it would not be
         // easy for to detect that all tuples share one s_id).
         $sid = false;
         foreach ($rows as $row) {
             if ($sid === false) {
                 $sid = $row['s_id'];
                 // 's_id' exists for all tables with $propertyTable->usesIdSubject()
             }
             unset($row['s_id']);
             if ($condition != '') {
                 $condition .= ' OR ';
             }
             $condition .= '(' . $dbw->makeList($row, LIST_AND) . ')';
         }
         $condition = "s_id=" . $dbw->addQuotes($sid) . " AND ({$condition})";
         $dbw->delete($propertyTable->getName(), array($condition), "SMW::writePropertyTableRowUpdates-delete-{$propertyTable->getName()}");
     }
     if ($propertyTable->isFixedPropertyTable()) {
         $property = new SMWDIProperty($propertyTable->getFixedProperty());
         $pid = $this->store->smwIds->makeSMWPropertyID($property);
     }
     foreach ($rows as $row) {
         if (!$propertyTable->isFixedPropertyTable()) {
             $pid = $row['p_id'];
         }
         if (!array_key_exists($pid, $propertyUseIncrements)) {
             $propertyUseIncrements[$pid] = 0;
         }
         $propertyUseIncrements[$pid] += $insert ? 1 : -1;
     }
 }
 /**
  * @see PropertyStatisticsStore::deleteAll
  *
  * @since 1.9
  *
  * @return boolean Success indicator
  */
 public function deleteAll()
 {
     return $this->dbConnection->delete($this->table, '*', __METHOD__);
 }
 protected function acceptRequest_rollback(DatabaseBase $dbw, $user_id, $acd_id)
 {
     $dbw->begin();
     # DELETE the user in case something caused a COMMIT already somewhere.
     if ($user_id) {
         $dbw->delete('user', array('user_id' => $user_id), __METHOD__);
         $dbw->delete('user_groups', array('ug_user' => $user_id), __METHOD__);
     }
     # DELETE the new account_credentials row likewise.
     if ($acd_id) {
         $dbw->delete('account_credentials', array('acd_id' => $acd_id), __METHOD__);
     }
     $dbw->commit();
 }
 /**
  * Save the user into a centralauth database
  * @param DatabaseBase $db
  */
 public function save(DatabaseBase $db)
 {
     // Setup local wiki user
     if ($this->createLocal) {
         $user = User::newFromName($this->username);
         if ($user->idForName() == 0) {
             $user->addToDatabase();
             $user->setPassword($this->password);
             $user->saveSettings();
         }
     }
     // Setup global user
     $row = array('gu_name' => $this->username, 'gu_id' => $this->guId, 'gu_password' => $this->passHash, 'gu_salt' => $this->salt, 'gu_auth_token' => $this->authToken, 'gu_locked' => $this->locked, 'gu_hidden' => $this->hidden, 'gu_registration' => $this->registration, 'gu_email' => $this->email, 'gu_email_authenticated' => $this->emailAuthenticated, 'gu_home_db' => $this->homeDb, 'gu_enabled' => $this->enabled, 'gu_enabled_method' => $this->enabledMethod);
     $db->insert('globaluser', $row, __METHOD__);
     // Attach global to local accounts
     $db->delete('localuser', array('lu_name' => $this->username), __METHOD__);
     if (count($this->wikis)) {
         $db->insert('localuser', $this->wikis, __METHOD__);
     }
 }
Esempio n. 16
0
 /**
  * Add row to the redirect table if this is a redirect, remove otherwise.
  *
  * @param DatabaseBase $dbw
  * @param Title $redirectTitle Title object pointing to the redirect target,
  *   or NULL if this is not a redirect
  * @param null|bool $lastRevIsRedirect If given, will optimize adding and
  *   removing rows in redirect table.
  * @return bool True on success, false on failure
  * @private
  */
 public function updateRedirectOn($dbw, $redirectTitle, $lastRevIsRedirect = null)
 {
     // Always update redirects (target link might have changed)
     // Update/Insert if we don't know if the last revision was a redirect or not
     // Delete if changing from redirect to non-redirect
     $isRedirect = !is_null($redirectTitle);
     if (!$isRedirect && $lastRevIsRedirect === false) {
         return true;
     }
     if ($isRedirect) {
         $this->insertRedirectEntry($redirectTitle);
     } else {
         // This is not a redirect, remove row from redirect table
         $where = array('rd_from' => $this->getId());
         $dbw->delete('redirect', $where, __METHOD__);
     }
     if ($this->getTitle()->getNamespace() == NS_FILE) {
         RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect($this->getTitle());
     }
     return $dbw->affectedRows() != 0;
 }
Esempio n. 17
0
 public function delete($table, $conds, $fname = 'DatabaseOracle::delete')
 {
     if (is_array($conds)) {
         $conds = $this->wrapConditionsForWhere($table, $conds);
     }
     // a hack for deleting pages, users and images (which have non-nullable FKs)
     // all deletions on these tables have transactions so final failure rollbacks these updates
     $table = $this->tableName($table);
     if ($table == $this->tableName('user')) {
         $this->update('archive', array('ar_user' => 0), array('ar_user' => $conds['user_id']), $fname);
         $this->update('ipblocks', array('ipb_user' => 0), array('ipb_user' => $conds['user_id']), $fname);
         $this->update('image', array('img_user' => 0), array('img_user' => $conds['user_id']), $fname);
         $this->update('oldimage', array('oi_user' => 0), array('oi_user' => $conds['user_id']), $fname);
         $this->update('filearchive', array('fa_deleted_user' => 0), array('fa_deleted_user' => $conds['user_id']), $fname);
         $this->update('filearchive', array('fa_user' => 0), array('fa_user' => $conds['user_id']), $fname);
         $this->update('uploadstash', array('us_user' => 0), array('us_user' => $conds['user_id']), $fname);
         $this->update('recentchanges', array('rc_user' => 0), array('rc_user' => $conds['user_id']), $fname);
         $this->update('logging', array('log_user' => 0), array('log_user' => $conds['user_id']), $fname);
     } elseif ($table == $this->tableName('image')) {
         $this->update('oldimage', array('oi_name' => 0), array('oi_name' => $conds['img_name']), $fname);
     }
     return parent::delete($table, $conds, $fname);
 }
 public function finishWrite()
 {
     if ($this->readOnly) {
         return;
     } elseif (is_null($this->currentLang)) {
         throw new MWException(__CLASS__ . ': must call startWrite() before finishWrite()');
     }
     $this->dbw->begin(__METHOD__);
     try {
         $this->dbw->delete('l10n_cache', array('lc_lang' => $this->currentLang), __METHOD__);
         foreach (array_chunk($this->batch, 500) as $rows) {
             $this->dbw->insert('l10n_cache', $rows, __METHOD__);
         }
         $this->writesDone = true;
     } catch (DBQueryError $e) {
         if ($this->dbw->wasReadOnlyError()) {
             $this->readOnly = true;
             // just avoid site down time
         } else {
             throw $e;
         }
     }
     $this->dbw->commit(__METHOD__);
     $this->currentLang = null;
     $this->batch = array();
 }
Esempio n. 19
0
 /**
  * Deletes all entries to a certain image
  *
  * @param $title Title Title of the file
  */
 public function deleteLinksToFile($title)
 {
     $this->db->delete('globalimagelinks', array('gil_wiki' => $this->interwiki, 'gil_to' => $title->getDBkey()), __METHOD__);
 }
 /**
  * @param DatabaseBase $dbw
  * @return void
  */
 private function delete($dbw)
 {
     $dbw->delete('text', '*', __METHOD__);
 }
 public function remove($name, $wiki)
 {
     $this->db->delete('users_to_rename', array('utr_wiki' => $wiki, 'utr_name' => $name), __METHOD__);
 }
Esempio n. 22
0
 /**
  * Deletes everything from search index.
  */
 private function clearSearchIndex()
 {
     $this->output('Clearing searchindex table...');
     $this->db->delete('searchindex', '*', __METHOD__);
     $this->output("Done\n");
 }
Esempio n. 23
0
 public function eraseSilently(\DatabaseBase $db)
 {
     $counter = 1;
     $db->delete('FlowThread', array('flowthread_id' => $this->id->getBin()));
     // We need to delete attitude as well to free up space
     $db->delete('FlowThreadAttitude', array('flowthread_att_id' => $this->id->getBin()));
     $children = $this->getChildren();
     foreach ($children as $post) {
         $counter += $post->eraseSilently($db);
     }
     return $counter;
 }
 public function startWrite($code)
 {
     if ($this->readOnly) {
         return;
     }
     if (!$code) {
         throw new MWException(__METHOD__ . ": Invalid language \"{$code}\"");
     }
     $this->dbw = wfGetDB(DB_MASTER);
     try {
         $this->dbw->begin(__METHOD__);
         $this->dbw->delete('l10n_cache', array('lc_lang' => $code), __METHOD__);
     } catch (DBQueryError $e) {
         if ($this->dbw->wasReadOnlyError()) {
             $this->readOnly = true;
             $this->dbw->rollback(__METHOD__);
             return;
         } else {
             throw $e;
         }
     }
     $this->currentLang = $code;
     $this->batch = array();
 }
 /**
  * Update the query cache as needed
  *
  * @param DatabaseBase $dbw
  * @param int $days How many days user must be idle before he is considered inactive
  * @param int $window Maximum time range of new data to scan (in seconds)
  * @return int|bool UNIX timestamp the cache is now up-to-date as of (false on error)
  */
 protected static function doQueryCacheUpdate(DatabaseBase $dbw, $days, $window)
 {
     $lockKey = wfWikiID() . '-activeusers';
     if (!$dbw->lock($lockKey, __METHOD__, 1)) {
         return false;
         // exclusive update (avoids duplicate entries)
     }
     $now = time();
     $cTime = $dbw->selectField('querycache_info', 'qci_timestamp', array('qci_type' => 'activeusers'));
     $cTimeUnix = $cTime ? wfTimestamp(TS_UNIX, $cTime) : 1;
     // Pick the date range to fetch from. This is normally from the last
     // update to till the present time, but has a limited window for sanity.
     // If the window is limited, multiple runs are need to fully populate it.
     $sTimestamp = max($cTimeUnix, $now - $days * 86400);
     $eTimestamp = min($sTimestamp + $window, $now);
     // Get all the users active since the last update
     $res = $dbw->select(array('recentchanges'), array('rc_user_text', 'lastedittime' => 'MAX(rc_timestamp)'), array('rc_user > 0', 'rc_type != ' . $dbw->addQuotes(RC_EXTERNAL), 'rc_log_type IS NULL OR rc_log_type != ' . $dbw->addQuotes('newusers'), 'rc_timestamp >= ' . $dbw->addQuotes($dbw->timestamp($sTimestamp)), 'rc_timestamp <= ' . $dbw->addQuotes($dbw->timestamp($eTimestamp))), __METHOD__, array('GROUP BY' => array('rc_user_text'), 'ORDER BY' => 'NULL'));
     $names = array();
     foreach ($res as $row) {
         $names[$row->rc_user_text] = $row->lastedittime;
     }
     // Rotate out users that have not edited in too long (according to old data set)
     $dbw->delete('querycachetwo', array('qcc_type' => 'activeusers', 'qcc_value < ' . $dbw->addQuotes($now - $days * 86400)), __METHOD__);
     // Find which of the recently active users are already accounted for
     if (count($names)) {
         $res = $dbw->select('querycachetwo', array('user_name' => 'qcc_title'), array('qcc_type' => 'activeusers', 'qcc_namespace' => NS_USER, 'qcc_title' => array_keys($names)), __METHOD__);
         foreach ($res as $row) {
             unset($names[$row->user_name]);
         }
     }
     // Insert the users that need to be added to the list (which their last edit time
     if (count($names)) {
         $newRows = array();
         foreach ($names as $name => $lastEditTime) {
             $newRows[] = array('qcc_type' => 'activeusers', 'qcc_namespace' => NS_USER, 'qcc_title' => $name, 'qcc_value' => wfTimestamp(TS_UNIX, $lastEditTime), 'qcc_namespacetwo' => 0, 'qcc_titletwo' => '');
         }
         foreach (array_chunk($newRows, 500) as $rowBatch) {
             $dbw->insert('querycachetwo', $rowBatch, __METHOD__);
             if (!$dbw->trxLevel()) {
                 wfWaitForSlaves();
             }
         }
     }
     // Touch the data freshness timestamp
     $dbw->replace('querycache_info', array('qci_type'), array('qci_type' => 'activeusers', 'qci_timestamp' => $dbw->timestamp($eTimestamp)), __METHOD__);
     $dbw->unlock($lockKey, __METHOD__);
     return $eTimestamp;
 }