diff options
Diffstat (limited to 'includes/api/ApiQueryLinks.php')
-rw-r--r-- | includes/api/ApiQueryLinks.php | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/includes/api/ApiQueryLinks.php b/includes/api/ApiQueryLinks.php index d77e627a..546a599d 100644 --- a/includes/api/ApiQueryLinks.php +++ b/includes/api/ApiQueryLinks.php @@ -30,8 +30,8 @@ if (!defined('MEDIAWIKI')) { /** * A query module to list all wiki links on a given set of pages. - * - * @addtogroup API + * + * @ingroup API */ class ApiQueryLinks extends ApiQueryGeneratorBase { @@ -41,7 +41,7 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { private $table, $prefix, $description; public function __construct($query, $moduleName) { - + switch ($moduleName) { case self::LINKS : $this->table = 'pagelinks'; @@ -84,16 +84,54 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { $this->addTables($this->table); $this->addWhereFld($this->prefix . '_from', array_keys($this->getPageSet()->getGoodTitles())); $this->addWhereFld($this->prefix . '_namespace', $params['namespace']); - $this->addOption('ORDER BY', str_replace('pl_', $this->prefix . '_', 'pl_from, pl_namespace, pl_title')); + + if(!is_null($params['continue'])) { + $cont = explode('|', $params['continue']); + if(count($cont) != 3) + $this->dieUsage("Invalid continue param. You should pass the " . + "original value returned by the previous query", "_badcontinue"); + $plfrom = intval($cont[0]); + $plns = intval($cont[1]); + $pltitle = $this->getDb()->strencode($this->titleToKey($cont[2])); + $this->addWhere("{$this->prefix}_from > $plfrom OR ". + "({$this->prefix}_from = $plfrom AND ". + "({$this->prefix}_namespace > $plns OR ". + "({$this->prefix}_namespace = $plns AND ". + "{$this->prefix}_title >= '$pltitle')))"); + } + + # Here's some MySQL craziness going on: if you use WHERE foo='bar' + # and later ORDER BY foo MySQL doesn't notice the ORDER BY is pointless + # but instead goes and filesorts, because the index for foo was used + # already. To work around this, we drop constant fields in the WHERE + # clause from the ORDER BY clause + $order = array(); + if(count($this->getPageSet()->getGoodTitles()) != 1) + $order[] = "{$this->prefix}_from"; + if(count($params['namespace']) != 1) + $order[] = "{$this->prefix}_namespace"; + $order[] = "{$this->prefix}_title"; + $this->addOption('ORDER BY', implode(", ", $order)); + $this->addOption('USE INDEX', "{$this->prefix}_from"); + $this->addOption('LIMIT', $params['limit'] + 1); $db = $this->getDB(); $res = $this->select(__METHOD__); if (is_null($resultPageSet)) { - + $data = array(); - $lastId = 0; // database has no ID 0 + $lastId = 0; // database has no ID 0 + $count = 0; while ($row = $db->fetchObject($res)) { + if(++$count > $params['limit']) { + // We've reached the one extra which shows that + // there are additional pages to be had. Stop here... + $this->setContinueEnumParameter('continue', + "{$row->pl_from}|{$row->pl_namespace}|" . + $this->keyToTitle($row->pl_title)); + break; + } if ($lastId != $row->pl_from) { if($lastId != 0) { $this->addPageSubItems($lastId, $data); @@ -114,7 +152,16 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { } else { $titles = array(); + $count = 0; while ($row = $db->fetchObject($res)) { + if(++$count > $params['limit']) { + // We've reached the one extra which shows that + // there are additional pages to be had. Stop here... + $this->setContinueEnumParameter('continue', + "{$row->pl_from}|{$row->pl_namespace}|" . + $this->keyToTitle($row->pl_title)); + break; + } $titles[] = Title :: makeTitle($row->pl_namespace, $row->pl_title); } $resultPageSet->populateFromTitles($titles); @@ -129,15 +176,25 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { 'namespace' => array( ApiBase :: PARAM_TYPE => 'namespace', ApiBase :: PARAM_ISMULTI => true - ) + ), + 'limit' => array( + ApiBase :: PARAM_DFLT => 10, + ApiBase :: PARAM_TYPE => 'limit', + ApiBase :: PARAM_MIN => 1, + ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1, + ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2 + ), + 'continue' => null, ); } public function getParamDescription() { return array( - 'namespace' => "Show {$this->description}s in this namespace(s) only" - ); + 'namespace' => "Show {$this->description}s in this namespace(s) only", + 'limit' => "How many {$this->description}s to return", + 'continue' => 'When more results are available, use this to continue', + ); } public function getDescription() { @@ -156,7 +213,6 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { } public function getVersion() { - return __CLASS__ . ': $Id: ApiQueryLinks.php 30222 2008-01-28 19:05:26Z catrope $'; + return __CLASS__ . ': $Id: ApiQueryLinks.php 37909 2008-07-22 13:26:15Z catrope $'; } } - |