diff options
Diffstat (limited to 'includes/LinksUpdate.php')
-rw-r--r-- | includes/LinksUpdate.php | 154 |
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__ ); |