From 4b279acd46437f7e01e6e876c777dbb32a6908dc Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Sun, 24 Apr 2005 04:16:50 +0000 Subject: [PATCH] New updateSpecialPages.php script, to update the QueryPage cache. Disabled recache parameter, using HTTP for long queries is a bad idea because of retries. Fixed broken QueryPage subclasses: Special:BrokenRedirects Special:Disambiguations and Special:DoubleRedirects. --- includes/QueryPage.php | 45 ++++++++++++++++++--- includes/SpecialAncientpages.php | 2 +- includes/SpecialBrokenRedirects.php | 33 +++++++++++---- includes/SpecialDisambiguations.php | 23 ++++++----- includes/SpecialDoubleRedirects.php | 62 ++++++++++++++++++++++------- includes/SpecialPage.php | 9 +++-- maintenance/updateSpecialPages.php | 51 ++++++++++++++++++++++++ 7 files changed, 183 insertions(+), 42 deletions(-) create mode 100644 maintenance/updateSpecialPages.php diff --git a/includes/QueryPage.php b/includes/QueryPage.php index 8838d99327..925083e0d0 100644 --- a/includes/QueryPage.php +++ b/includes/QueryPage.php @@ -9,6 +9,31 @@ */ require_once ( 'Feed.php' ); +/** + * List of query page classes and their associated special pages, for periodic update purposes + */ +$wgQueryPages = array( +// QueryPage subclass Special page name +//------------------------------------------------------------ + array( 'AncientPagesPage', 'Ancientpages' ), + array( 'BrokenRedirectsPage', 'BrokenRedirects' ), + array( 'DeadendPagesPage', 'Deadendpages' ), + array( 'DisambiguationsPage', 'Disambiguations' ), + array( 'DoubleRedirectsPage', 'DoubleRedirects' ), + array( 'ListUsersPage', 'Listusers' ), + array( 'LonelyPagesPage', 'Lonelypages' ), + array( 'LongPagesPage', 'Longpages' ), + array( 'NewPagesPage', 'Newpages' ), + array( 'PopularPagesPage', 'Popularpages' ), + array( 'ShortPagesPage', 'Shortpages' ), + array( 'UncategorizedCategoriesPage','Uncategorizedcategories'), + array( 'UncategorizedPagesPage', 'Uncategorizedpages'), + array( 'UnusedimagesPage', 'Unusedimages' ), + array( 'WantedPagesPage', 'Wantedpages' ), +); + + + /** * This is a class for doing query pages; since they're almost all the same, * we factor out some of the functionality into a superclass, and let @@ -109,7 +134,7 @@ class QueryPage { * @param $offset database query offset * @param $limit database query limit */ - function doQuery( $offset, $limit ) { + function doQuery( $offset, $limit, $recache = false ) { global $wgUser, $wgOut, $wgLang, $wgRequest, $wgContLang; global $wgMiserMode; @@ -124,7 +149,9 @@ class QueryPage { $res = false; if ( $this->isExpensive() ) { - $recache = $wgRequest->getBool( 'recache' ); + // Disabled recache parameter due to retry problems -- TS + // $recache = $wgRequest->getBool( 'recache' ); + if( $recache ) { # Clear out any old cached data $dbw->delete( 'querycache', array( 'qc_type' => $sname ), $fname ); @@ -143,15 +170,23 @@ class QueryPage { } else { $insertSql .= ','; } + if ( isset( $row->value ) ) { + $value = $row->value; + } else { + $value = ''; + } + $insertSql .= '(' . $dbw->addQuotes( $row->type ) . ',' . $dbw->addQuotes( $row->namespace ) . ',' . $dbw->addQuotes( $row->title ) . ',' . - $dbw->addQuotes( $row->value ) . ')'; + $dbw->addQuotes( $value ) . ')'; } # Save results into the querycache table on the master - $dbw->query( $insertSql, $fname ); + if ( !$first ) { + $dbw->query( $insertSql, $fname ); + } # Set result pointer to allow reading for display $numRows = $dbr->numRows( $res ); @@ -178,7 +213,6 @@ class QueryPage { $num = $dbr->numRows($res); } - $sk = $wgUser->getSkin( ); $wgOut->addHTML( $this->getPageHeader() ); @@ -221,6 +255,7 @@ class QueryPage { $wgOut->addHTML( $s ); } $wgOut->addHTML( "

{$sl}

\n" ); + return $num; } /** diff --git a/includes/SpecialAncientpages.php b/includes/SpecialAncientpages.php index 253c917487..991fed3a28 100644 --- a/includes/SpecialAncientpages.php +++ b/includes/SpecialAncientpages.php @@ -36,7 +36,7 @@ class AncientPagesPage extends QueryPage { "SELECT 'Ancientpages' as type, page_namespace as namespace, page_title as title, - rev_timestamp as value + UNIX_TIMESTAMP(rev_timestamp) as value FROM $page, $revision WHERE page_namespace=".NS_MAIN." AND page_is_redirect=0 AND page_latest=rev_id"; diff --git a/includes/SpecialBrokenRedirects.php b/includes/SpecialBrokenRedirects.php index 743e450feb..8ae92c01ce 100644 --- a/includes/SpecialBrokenRedirects.php +++ b/includes/SpecialBrokenRedirects.php @@ -16,6 +16,7 @@ require_once('QueryPage.php'); * @subpackage SpecialPage */ class BrokenRedirectsPage extends PageQueryPage { + var $targets = array(); function getName() { return 'BrokenRedirects'; @@ -25,7 +26,6 @@ class BrokenRedirectsPage extends PageQueryPage { function isSyndicated() { return false; } function getPageHeader( ) { - #FIXME : probably need to add a backlink to the maintenance page. return '

'.wfMsg('brokenredirectstext')."


\n"; } @@ -33,22 +33,39 @@ class BrokenRedirectsPage extends PageQueryPage { $dbr =& wfGetDB( DB_SLAVE ); extract( $dbr->tableNames( 'page', 'brokenlinks' ) ); - $sql = "SELECT bl_to,page_title FROM $brokenlinks,$page " . - 'WHERE page_is_redirect=1 AND page_namespace='.NS_MAIN.' AND bl_from=page_id '; + $sql = "SELECT 'BrokenRedirects' as type, page_namespace as namespace," . + "page_title as title, bl_to FROM $brokenlinks,$page " . + 'WHERE page_is_redirect=1 AND bl_from=page_id '; return $sql; } function getOrder() { return ''; } - + function formatResult( $skin, $result ) { global $wgContLang ; - $ns = $wgContLang->getNamespaces() ; /* not used, why bother? */ - $from = $skin->makeKnownLink( $result->page_title ,'', 'redirect=no' ); - $edit = $skin->makeBrokenLink( $result->page_title , "(".wfMsg("qbedit").")" , 'redirect=no'); - $to = $skin->makeBrokenLink( $result->bl_to ); + $fromObj = Title::makeTitle( $result->namespace, $result->title ); + if ( isset( $result->bl_to ) ) { + $toObj = Title::newFromText( $result->bl_to ); + } else { + $blinks = $fromObj->getBrokenLinksFrom(); + if ( $blinks ) { + $toObj = $blinks[0]; + } else { + $toObj = false; + } + } + + // $toObj may very easily be false if the $result list is cached + if ( !is_object( $toObj ) || !is_object( $fromObj ) ) { + return ''; + } + + $from = $skin->makeKnownLinkObj( $fromObj ,'', 'redirect=no' ); + $edit = $skin->makeBrokenLinkObj( $fromObj , "(".wfMsg("qbedit").")" , 'redirect=no'); + $to = $skin->makeBrokenLinkObj( $toObj ); return "$from $edit => $to"; } diff --git a/includes/SpecialDisambiguations.php b/includes/SpecialDisambiguations.php index e2b5301013..2522e6668a 100644 --- a/includes/SpecialDisambiguations.php +++ b/includes/SpecialDisambiguations.php @@ -37,15 +37,17 @@ class DisambiguationsPage extends PageQueryPage { extract( $dbr->tableNames( 'page', 'links' ) ); $dp = Title::newFromText(wfMsgForContent("disambiguationspage")); - $dpid = $dp->getArticleID(); - - $sql = "SELECT pa.page_namespace AS ns_art, pa.page_title AS title_art," - . " pb.page_namespace AS ns_dis, pb.page_title AS title_dis" + $dns = $dp->getNamespace(); + $dtitle = $dbr->addQuotes( $dp->getDBkey() ); + + $sql = "SELECT 'Disambiguations' as type," + . " pa.page_namespace AS namespace, pa.page_title AS title" . " FROM {$links} as la, {$links} as lb, {$page} as pa, {$page} as pb" - . " WHERE la.l_to = '{$dpid}'" + . " WHERE pb.page_namespace = $dns" + . " AND pb.page_title = $dtitle" . " AND la.l_from = lb.l_to" . " AND pa.page_id = lb.l_from" - . " AND pb.page_id = lb.l_to"; + . " AND pb.page_id = lb.l_to" ; return $sql; } @@ -56,11 +58,12 @@ class DisambiguationsPage extends PageQueryPage { function formatResult( $skin, $result ) { global $wgContLang ; - $ns = $wgContLang->getNamespaces() ; + $dp = Title::newFromText(wfMsgForContent("disambiguationspage")); + $title = Title::makeTitle( $result->namespace, $result->title ); - $from = $skin->makeKnownLink( $ns[$result->ns_art].':'.$result->title_art ,''); - $edit = $skin->makeBrokenLink( $ns[$result->ns_art].':'.$result->title_art , "(".wfMsg("qbedit").")" , 'redirect=no'); - $to = $skin->makeKnownLink( $ns[$result->ns_dis].':'.$result->title_dis ,''); + $from = $skin->makeKnownLinkObj( $title,''); + $edit = $skin->makeBrokenLinkObj( $title, "(".wfMsg("qbedit").")" , 'redirect=no'); + $to = $skin->makeKnownLinkObj( $dp,''); return "$from $edit => $to"; } diff --git a/includes/SpecialDoubleRedirects.php b/includes/SpecialDoubleRedirects.php index cc044f12c7..9c0563e5ab 100644 --- a/includes/SpecialDoubleRedirects.php +++ b/includes/SpecialDoubleRedirects.php @@ -31,15 +31,18 @@ class DoubleRedirectsPage extends PageQueryPage { function getSQL() { $dbr =& wfGetDB( DB_SLAVE ); - extract( $dbr->tableNames( 'page', 'links', 'text' ) ); + extract( $dbr->tableNames( 'page', 'links' ) ); - $sql = "SELECT pa.page_namespace as ns_a, pa.page_title as title_a, - pb.page_namespace as ns_b, pb.page_title as title_b, - old_text AS rt - FROM $text AS t, $links,$page AS pa,$page AS pb - WHERE pa.page_is_redirect=1 AND pb.page_is_redirect=1 AND l_to=pb.page_id - AND l_from=pa.page_id - AND pb.page_latest=t.old_id" ; + $sql = "SELECT 'DoubleRedirects' as type," . + " pa.page_namespace as namespace, pa.page_title as title," . + " pb.page_namespace as nsb, pb.page_title as tb," . + " pc.page_namespace as nsc, pc.page_title as tc" . + " FROM $links AS la, $links AS lb, $page AS pa, $page AS pb, $page AS pc" . + " WHERE pa.page_is_redirect=1 AND pb.page_is_redirect=1" . + " AND la.l_from=pa.page_id" . + " AND la.l_to=pb.page_id" . + " AND lb.l_from=pb.page_id" . + " AND lb.l_to=pc.page_id"; return $sql; } @@ -48,14 +51,43 @@ class DoubleRedirectsPage extends PageQueryPage { } function formatResult( $skin, $result ) { - global $wgContLang ; - $ns = $wgContLang->getNamespaces() ; - $from = $skin->makeKnownLink( $ns[$result->ns_a].':'.$result->title_a ,'', 'redirect=no' ); - $edit = $skin->makeBrokenLink( $ns[$result->ns_a].':'.$result->title_a , "(".wfMsg("qbedit").")" , 'redirect=no'); - $to = $skin->makeKnownLink( $ns[$result->ns_b].':'.$result->title_b ,''); - $content = $result->rt; + $fname = 'DoubleRedirectsPage::formatResult'; + $titleA = Title::makeTitle( $result->namespace, $result->title ); + + if ( $result && !isset( $result->nsb ) ) { + $dbr =& wfGetDB( DB_SLAVE ); + extract( $dbr->tableNames( 'page', 'links' ) ); + $encTitle = $dbr->addQuotes( $result->title ); + + $sql = "SELECT pa.page_namespace as namespace, pa.page_title as title," . + " pb.page_namespace as nsb, pb.page_title as tb," . + " pc.page_namespace as nsc, pc.page_title as tc" . + " FROM $links AS la, $links AS lb, $page AS pa, $page AS pb, $page AS pc" . + " WHERE pa.page_is_redirect=1 AND pb.page_is_redirect=1" . + " AND la.l_from=pa.page_id" . + " AND la.l_to=pb.page_id" . + " AND lb.l_from=pb.page_id" . + " AND lb.l_to=pc.page_id" . + " AND pa.page_namespace={$result->namespace}" . + " AND pa.page_title=$encTitle"; + $res = $dbr->query( $sql, $fname ); + if ( $res ) { + $result = $dbr->fetchObject( $res ); + } + } + if ( !$result ) { + return ''; + } + + $titleB = Title::makeTitle( $result->nsb, $result->tb ); + $titleC = Title::makeTitle( $result->nsc, $result->tc ); + + $linkA = $skin->makeKnownLinkObj( $titleA,'', 'redirect=no' ); + $edit = $skin->makeBrokenLinkObj( $titleA, "(".wfMsg("qbedit").")" , 'redirect=no'); + $linkB = $skin->makeKnownLinkObj( $titleB, '', 'redirect=no' ); + $linkC = $skin->makeKnownLinkObj( $titleC ); - return "$from $edit => $to ($content)"; + return "$linkA $edit → $linkB → $linkC"; } } diff --git a/includes/SpecialPage.php b/includes/SpecialPage.php index 5cc1e84231..31d4f17a34 100644 --- a/includes/SpecialPage.php +++ b/includes/SpecialPage.php @@ -15,6 +15,7 @@ * @subpackage SpecialPage */ + /** * */ @@ -24,9 +25,9 @@ global $wgSpecialPages; * @access private */ $wgSpecialPages = array( - 'DoubleRedirects' => new UnlistedSpecialPage ( 'DoubleRedirects' ), - 'BrokenRedirects' => new UnlistedSpecialPage ( 'BrokenRedirects' ), - 'Disambiguations' => new UnlistedSpecialPage ( 'Disambiguations' ), + 'DoubleRedirects' => new SpecialPage ( 'DoubleRedirects' ), + 'BrokenRedirects' => new SpecialPage ( 'BrokenRedirects' ), + 'Disambiguations' => new SpecialPage ( 'Disambiguations' ), 'Userlogin' => new SpecialPage( 'Userlogin' ), 'Userlogout' => new UnlistedSpecialPage( 'Userlogout' ), @@ -257,6 +258,7 @@ class SpecialPage function getName() { return $this->mName; } function getRestriction() { return $this->mRestriction; } function isListed() { return $this->mListed; } + function getFile() { return $this->mFile; } /** * Checks if the given user (identified by an object) can execute this @@ -350,3 +352,4 @@ class UnlistedSpecialPage extends SpecialPage SpecialPage::SpecialPage( $name, $restriction, false, $function, $file ); } } +?> diff --git a/maintenance/updateSpecialPages.php b/maintenance/updateSpecialPages.php new file mode 100644 index 0000000000..61f319e4ab --- /dev/null +++ b/maintenance/updateSpecialPages.php @@ -0,0 +1,51 @@ +disable(); + +foreach ( $wgQueryPages as $page ) { + list( $class, $special ) = $page; + + $specialObj = SpecialPage::getPage( $special ); + if ( !$specialObj ) { + print "No such special page: $special\n"; + exit; + } + $file = $specialObj->getFile(); + if ( $file ) { + require_once( $file ); + } + $queryPage = new $class; + + printf( '%-30s', $special ); + + if ( $queryPage->isExpensive() ) { + $t1 = explode( ' ', microtime() ); + $num = $queryPage->doQuery( 0, 0, true ); + $t2 = explode( ' ', microtime() ); + + print "got $num rows in "; + + $elapsed = ($t2[0] - $t1[0]) + ($t2[1] - $t1[1]); + $hours = intval( $elapsed / 3600 ); + $minutes = intval( $elapsed % 3600 / 60 ); + $seconds = $elapsed - $hours * 3600 - $minutes * 60; + if ( $hours ) { + print $hours . 'h '; + } + if ( $minutes ) { + print $minutes . 'm '; + } + printf( "%.2f s\n", $seconds ); + } else { + print "cheap, skipped\n"; + } +} + +?> -- 2.20.1