/** * 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]); }
/** * 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__); }
/** * 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__); } } } }
/** * 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; }
/** * 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__); } } }
/** * 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" ); }
/** * 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); } }
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); } }
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; }
/** * 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__); } }
/** * 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; }
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(); }
/** * 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__); }
/** * Deletes everything from search index. */ private function clearSearchIndex() { $this->output('Clearing searchindex table...'); $this->db->delete('searchindex', '*', __METHOD__); $this->output("Done\n"); }
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; }