summaryrefslogtreecommitdiff
path: root/includes/LinksUpdate.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/LinksUpdate.php')
-rw-r--r--includes/LinksUpdate.php154
1 files changed, 75 insertions, 79 deletions
diff --git a/includes/LinksUpdate.php b/includes/LinksUpdate.php
index d99ae22d..fdd0e3c1 100644
--- a/includes/LinksUpdate.php
+++ b/includes/LinksUpdate.php
@@ -27,7 +27,7 @@
*/
class LinksUpdate extends SqlDataUpdate {
- // @todo: make members protected, but make sure extensions don't break
+ // @todo make members protected, but make sure extensions don't break
public $mId, //!< Page ID of the article linked from
$mTitle, //!< Title object of the article linked from
@@ -44,6 +44,16 @@ class LinksUpdate extends SqlDataUpdate {
$mRecursive; //!< Whether to queue jobs for recursive updates
/**
+ * @var null|array Added links if calculated.
+ */
+ private $linkInsertions = null;
+
+ /**
+ * @var null|array Deleted links if calculated.
+ */
+ private $linkDeletions = null;
+
+ /**
* Constructor
*
* @param $title Title of the page we're updating
@@ -112,14 +122,8 @@ class LinksUpdate extends SqlDataUpdate {
* Update link tables with outgoing links from an updated article
*/
public function doUpdate() {
- global $wgUseDumbLinkUpdate;
-
wfRunHooks( 'LinksUpdate', array( &$this ) );
- if ( $wgUseDumbLinkUpdate ) {
- $this->doDumbUpdate();
- } else {
- $this->doIncrementalUpdate();
- }
+ $this->doIncrementalUpdate();
wfRunHooks( 'LinksUpdateComplete', array( &$this ) );
}
@@ -128,8 +132,9 @@ class LinksUpdate extends SqlDataUpdate {
# Page links
$existing = $this->getExistingLinks();
- $this->incrTableUpdate( 'pagelinks', 'pl', $this->getLinkDeletions( $existing ),
- $this->getLinkInsertions( $existing ) );
+ $this->linkDeletions = $this->getLinkDeletions( $existing );
+ $this->linkInsertions = $this->getLinkInsertions( $existing );
+ $this->incrTableUpdate( 'pagelinks', 'pl', $this->linkDeletions, $this->linkInsertions );
# Image links
$existing = $this->getExistingImages();
@@ -198,61 +203,35 @@ class LinksUpdate extends SqlDataUpdate {
}
/**
- * Link update which clears the previous entries and inserts new ones
- * May be slower or faster depending on level of lock contention and write speed of DB
- * Also useful where link table corruption needs to be repaired, e.g. in refreshLinks.php
+ * Queue recursive jobs for this page
+ *
+ * Which means do LinksUpdate on all templates
+ * that include the current page, using the job queue.
*/
- protected function doDumbUpdate() {
- wfProfileIn( __METHOD__ );
-
- # Refresh category pages and image description pages
- $existing = $this->getExistingCategories();
- $categoryInserts = array_diff_assoc( $this->mCategories, $existing );
- $categoryDeletes = array_diff_assoc( $existing, $this->mCategories );
- $categoryUpdates = $categoryInserts + $categoryDeletes;
- $existing = $this->getExistingImages();
- $imageUpdates = array_diff_key( $existing, $this->mImages ) + array_diff_key( $this->mImages, $existing );
-
- $this->dumbTableUpdate( 'pagelinks', $this->getLinkInsertions(), 'pl_from' );
- $this->dumbTableUpdate( 'imagelinks', $this->getImageInsertions(), 'il_from' );
- $this->dumbTableUpdate( 'categorylinks', $this->getCategoryInsertions(), 'cl_from' );
- $this->dumbTableUpdate( 'templatelinks', $this->getTemplateInsertions(), 'tl_from' );
- $this->dumbTableUpdate( 'externallinks', $this->getExternalInsertions(), 'el_from' );
- $this->dumbTableUpdate( 'langlinks', $this->getInterlangInsertions(), 'll_from' );
- $this->dumbTableUpdate( 'iwlinks', $this->getInterwikiInsertions(), 'iwl_from' );
- $this->dumbTableUpdate( 'page_props', $this->getPropertyInsertions(), 'pp_page' );
-
- # Update the cache of all the category pages and image description
- # pages which were changed, and fix the category table count
- $this->invalidateCategories( $categoryUpdates );
- $this->updateCategoryCounts( $categoryInserts, $categoryDeletes );
- $this->invalidateImageDescriptions( $imageUpdates );
-
- # Refresh links of all pages including this page
- # This will be in a separate transaction
- if ( $this->mRecursive ) {
- $this->queueRecursiveJobs();
- }
-
- wfProfileOut( __METHOD__ );
+ function queueRecursiveJobs() {
+ self::queueRecursiveJobsForTable( $this->mTitle, 'templatelinks' );
}
- function queueRecursiveJobs() {
+ /**
+ * Queue a RefreshLinks job for any table.
+ *
+ * @param Title $title Title to do job for
+ * @param String $table Table to use (e.g. 'templatelinks')
+ */
+ public static function queueRecursiveJobsForTable( Title $title, $table ) {
wfProfileIn( __METHOD__ );
-
- if ( $this->mTitle->getBacklinkCache()->hasLinks( 'templatelinks' ) ) {
+ if ( $title->getBacklinkCache()->hasLinks( $table ) ) {
$job = new RefreshLinksJob2(
- $this->mTitle,
+ $title,
array(
- 'table' => 'templatelinks',
+ 'table' => $table,
) + Job::newRootJobParams( // "overall" refresh links job info
- "refreshlinks:templatelinks:{$this->mTitle->getPrefixedText()}"
+ "refreshlinks:{$table}:{$title->getPrefixedText()}"
)
);
JobQueueGroup::singleton()->push( $job );
JobQueueGroup::singleton()->deduplicateRootJob( $job );
}
-
wfProfileOut( __METHOD__ );
}
@@ -283,21 +262,6 @@ class LinksUpdate extends SqlDataUpdate {
}
/**
- * @param $table
- * @param $insertions
- * @param $fromField
- */
- private function dumbTableUpdate( $table, $insertions, $fromField ) {
- $this->mDb->delete( $table, array( $fromField => $this->mId ), __METHOD__ );
- if ( count( $insertions ) ) {
- # The link array was constructed without FOR UPDATE, so there may
- # be collisions. This may cause minor link table inconsistencies,
- # which is better than crippling the site with lock contention.
- $this->mDb->insert( $table, $insertions, __METHOD__, array( 'IGNORE' ) );
- }
- }
-
- /**
* Update a table by doing a delete query then an insert query
* @param $table
* @param $prefix
@@ -354,7 +318,7 @@ class LinksUpdate extends SqlDataUpdate {
*/
private function getLinkInsertions( $existing = array() ) {
$arr = array();
- foreach( $this->mLinks as $ns => $dbkeys ) {
+ foreach ( $this->mLinks as $ns => $dbkeys ) {
$diffs = isset( $existing[$ns] )
? array_diff_key( $dbkeys, $existing[$ns] )
: $dbkeys;
@@ -376,7 +340,7 @@ class LinksUpdate extends SqlDataUpdate {
*/
private function getTemplateInsertions( $existing = array() ) {
$arr = array();
- foreach( $this->mTemplates as $ns => $dbkeys ) {
+ foreach ( $this->mTemplates as $ns => $dbkeys ) {
$diffs = isset( $existing[$ns] ) ? array_diff_key( $dbkeys, $existing[$ns] ) : $dbkeys;
foreach ( $diffs as $dbk => $id ) {
$arr[] = array(
@@ -398,7 +362,7 @@ class LinksUpdate extends SqlDataUpdate {
private function getImageInsertions( $existing = array() ) {
$arr = array();
$diffs = array_diff_key( $this->mImages, $existing );
- foreach( $diffs as $iname => $dummy ) {
+ foreach ( $diffs as $iname => $dummy ) {
$arr[] = array(
'il_from' => $this->mId,
'il_to' => $iname
@@ -415,8 +379,8 @@ class LinksUpdate extends SqlDataUpdate {
private function getExternalInsertions( $existing = array() ) {
$arr = array();
$diffs = array_diff_key( $this->mExternals, $existing );
- foreach( $diffs as $url => $dummy ) {
- foreach( wfMakeUrlIndexes( $url ) as $index ) {
+ foreach ( $diffs as $url => $dummy ) {
+ foreach ( wfMakeUrlIndexes( $url ) as $index ) {
$arr[] = array(
'el_from' => $this->mId,
'el_to' => $url,
@@ -481,7 +445,7 @@ class LinksUpdate extends SqlDataUpdate {
private function getInterlangInsertions( $existing = array() ) {
$diffs = array_diff_assoc( $this->mInterlangs, $existing );
$arr = array();
- foreach( $diffs as $lang => $title ) {
+ foreach ( $diffs as $lang => $title ) {
$arr[] = array(
'll_from' => $this->mId,
'll_lang' => $lang,
@@ -517,7 +481,7 @@ class LinksUpdate extends SqlDataUpdate {
*/
private function getInterwikiInsertions( $existing = array() ) {
$arr = array();
- foreach( $this->mInterwikis as $prefix => $dbkeys ) {
+ foreach ( $this->mInterwikis as $prefix => $dbkeys ) {
$diffs = isset( $existing[$prefix] ) ? array_diff_key( $dbkeys, $existing[$prefix] ) : $dbkeys;
foreach ( $diffs as $dbk => $id ) {
$arr[] = array(
@@ -807,6 +771,40 @@ class LinksUpdate extends SqlDataUpdate {
}
}
}
+
+ /**
+ * Fetch page links added by this LinksUpdate. Only available after the update is complete.
+ * @since 1.22
+ * @return null|array of Titles
+ */
+ public function getAddedLinks() {
+ if ( $this->linkInsertions === null ) {
+ return null;
+ }
+ $result = array();
+ foreach ( $this->linkInsertions as $insertion ) {
+ $result[] = Title::makeTitle( $insertion[ 'pl_namespace' ], $insertion[ 'pl_title' ] );
+ }
+ return $result;
+ }
+
+ /**
+ * Fetch page links removed by this LinksUpdate. Only available after the update is complete.
+ * @since 1.22
+ * @return null|array of Titles
+ */
+ public function getRemovedLinks() {
+ if ( $this->linkDeletions === null ) {
+ return null;
+ }
+ $result = array();
+ foreach ( $this->linkDeletions as $ns => $titles ) {
+ foreach ( $titles as $title => $unused ) {
+ $result[] = Title::makeTitle( $ns, $title );
+ }
+ }
+ return $result;
+ }
}
/**
@@ -840,22 +838,20 @@ class LinksDeletionUpdate extends SqlDataUpdate {
$id = $this->mPage->getId();
# Delete restrictions for it
- $this->mDb->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
+ $this->mDb->delete( 'page_restrictions', array( 'pr_page' => $id ), __METHOD__ );
# Fix category table counts
$cats = array();
$res = $this->mDb->select( 'categorylinks', 'cl_to', array( 'cl_from' => $id ), __METHOD__ );
foreach ( $res as $row ) {
- $cats [] = $row->cl_to;
+ $cats[] = $row->cl_to;
}
$this->mPage->updateCategoryCounts( array(), $cats );
# If using cascading deletes, we can skip some explicit deletes
if ( !$this->mDb->cascadingDeletes() ) {
- $this->mDb->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
-
# Delete outgoing links
$this->mDb->delete( 'pagelinks', array( 'pl_from' => $id ), __METHOD__ );
$this->mDb->delete( 'imagelinks', array( 'il_from' => $id ), __METHOD__ );