From: Yuri Astrakhan Date: Fri, 29 Sep 2006 07:29:13 +0000 (+0000) Subject: * API: revisions module fixes X-Git-Tag: 1.31.0-rc.0~55699 X-Git-Url: http://git.cyclocoop.org/%7B%24admin_url%7Dmes_infos.php?a=commitdiff_plain;h=94517aac14b72e376fbb382a7ae47e488934580b;p=lhc%2Fweb%2Fwiklou.git * API: revisions module fixes --- diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php index 0a32b9a06d..7854e94cd0 100644 --- a/includes/api/ApiPageSet.php +++ b/includes/api/ApiPageSet.php @@ -83,7 +83,7 @@ class ApiPageSet extends ApiQueryBase { * Returns the number of unique pages (not revisions) in the set. */ public function getPageCount() { - return count($this->getGoodTitles()); + return count($this->getGoodTitles()); } /** @@ -176,7 +176,7 @@ class ApiPageSet extends ApiQueryBase { 'pl_from' => array_keys($redirectIds )), __CLASS__ . '::' . __FUNCTION__); $this->profileDBOut(); - + while ($row = $db->fetchObject($res)) { // Bug 7304 workaround @@ -199,9 +199,9 @@ class ApiPageSet extends ApiQueryBase { } $db->freeResult($res); } - $this->profileOut(); + $this->profileOut(); } - + /** * Given an array of title strings, convert them into Title objects. * This method validates access rights for the title, @@ -237,6 +237,10 @@ class ApiPageSet extends ApiQueryBase { return $linkBatch; } + public function populatePageIDs($pageids) { + $this->dieUsage(__FUNCTION__ . " is not implemented", 'notimplemented'); + } + public function execute() { $this->dieDebug("execute() is not supported on this object"); } diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php index 20ec0e8cba..5bddbacf7b 100644 --- a/includes/api/ApiQuery.php +++ b/includes/api/ApiQuery.php @@ -96,44 +96,24 @@ class ApiQuery extends ApiBase { * #5 Execute all requested modules */ public function execute() { - $meta = $prop = $list = $generator = $titles = $pageids = $revids = null; + $meta = $prop = $list = $generator = $titles = $pageids = null; $redirects = null; extract($this->extractRequestParams()); // // Create and initialize PageSet // - // Only one of the titles/pageids/revids is allowed at the same time $dataSource = null; - if (isset ($titles)) - $dataSource = 'titles'; - if (isset ($pageids)) { - if (isset ($dataSource)) - $this->dieUsage("Cannot use 'pageids' at the same time as '$dataSource'", 'multisource'); - $dataSource = 'pageids'; - } - if (isset ($revids)) { - if (isset ($dataSource)) - $this->dieUsage("Cannot use 'revids' at the same time as '$dataSource'", 'multisource'); - $dataSource = 'revids'; - } + if (isset ($titles) && isset($pageids)) + $this->dieUsage("At present you may not use titles= and pageids= at the same time", 'multisource'); $this->mData = new ApiPageSet($this, $redirects); - switch ($dataSource) { - case 'titles' : - $this->mData->populateTitles($titles); - break; - case 'pageids' : - $this->mData->populatePageIDs($pageids); - break; - case 'titles' : - $this->mData->populateRevIDs($revids); - break; - default : - // Do nothing - some queries do not need any of the data sources. - break; - } + if (isset($titles)) + $this->mData->populateTitles($titles); + + if (isset($pageids)) + $this->mData->populatePageIDs($pageids); // // If generator is provided, get a new dataset to work on @@ -159,7 +139,8 @@ class ApiQuery extends ApiBase { foreach ($this->mData->getNormalizedTitles() as $rawTitleStr => $titleStr) { $this->getResult()->addMessage('query', 'normalized', array ( 'from' => $rawTitleStr, - 'to' => $titleStr + 'to' => $titleStr, + '*' => '' ), 'n'); } @@ -168,7 +149,8 @@ class ApiQuery extends ApiBase { foreach ($this->mData->getRedirectTitles() as $titleStrFrom => $titleStrTo) { $this->getResult()->addMessage('query', 'redirects', array ( 'from' => $titleStrFrom, - 'to' => $titleStrTo + 'to' => $titleStrTo, + '*' => '' ), 'r'); } } @@ -224,10 +206,6 @@ class ApiQuery extends ApiBase { // GN_ENUM_TYPE => 'integer', // GN_ENUM_ISMULTI => true // ), - // 'revids' => array ( - // GN_ENUM_TYPE => 'integer', - // GN_ENUM_ISMULTI => true - // ), 'redirects' => false ); } @@ -280,7 +258,6 @@ class ApiQuery extends ApiBase { 'generator' => 'Use the output of a list as the input for other prop/list/meta items', 'titles' => 'A list of titles to work on', 'pageids' => 'A list of page IDs to work on', - 'revids' => 'A list of revision IDs to work on', 'redirects' => 'Automatically resolve redirects' ); } diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php index d3129b0646..4be5d7a85a 100644 --- a/includes/api/ApiQueryRevisions.php +++ b/includes/api/ApiQueryRevisions.php @@ -36,7 +36,7 @@ class ApiQueryRevisions extends ApiQueryBase { } public function execute() { - $rvlimit = $rvstartid = $rvendid = $rvstart = $rvend = $rvdir = $rvprop = null; + $rvrevids = $rvlimit = $rvstartid = $rvendid = $rvstart = $rvend = $rvdir = $rvprop = null; extract($this->extractRequestParams()); // @@ -46,16 +46,30 @@ class ApiQueryRevisions extends ApiQueryBase { // true when ordered by timestamp from older to newer, false otherwise $dirNewer = ($rvdir === 'newer'); - // If any of those parameters are used, we work with single page only - $singePageMode = ($rvlimit !== 0 || $rvstartid !== 0 || $rvendid !== 0 || $dirNewer || isset ($rvstart) || isset ($rvend)); + // If any of those parameters are used, we can only work with a single page + // Enumerating revisions on multiple pages make it extremelly + // difficult to manage continuations and require additional sql indexes + $enumRevMode = ($rvlimit !== 0 || $rvstartid !== 0 || $rvendid !== 0 || $dirNewer || isset ($rvstart) || isset ($rvend)); if ($rvstartid !== 0 || $rvendid !== 0) $this->dieUsage('rvstartid/rvendid not implemented', 'notimplemented'); $data = $this->getData(); $pageCount = $data->getPageCount(); - if ($singePageMode && $pageCount > 1) - $this->dieUsage('You have supplied multiple pages, but the specified revisions parameters may only be used with one page.', 'rv_multpages'); + + if (!empty ($rvrevids)) { + if ($pageCount > 0) + $this->dieUsage('The rvrevids= parameter may not be used with titles, pageids, and generator options.', 'rv_rvrevids'); + + if ($enumRevMode) + $this->dieUsage('The rvrevids= parameter may not be used with the list options (rvlimit, rvstartid, rvendid, dirNewer, rvstart, rvend).', 'rv_rvrevids'); + } else { + if ($pageCount < 1) + $this->dieUsage('No pages were given. Please use titles, pageids or a generator to provide page(s) to work on.', 'rv_no_pages'); + + if ($enumRevMode && $pageCount > 1) + $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the rvlimit, rvstartid, rvendid, dirNewer, rvstart, and rvend parameters may only be used on a single page.', 'rv_multpages'); + } $tables = array ( 'revision' @@ -97,6 +111,7 @@ class ApiQueryRevisions extends ApiQueryBase { $fields[] = 'old_id'; $fields[] = 'old_text'; $fields[] = 'old_flags'; + $showContent = true; break; default : $this->dieDebug("unknown rvprop $prop"); @@ -104,25 +119,43 @@ class ApiQueryRevisions extends ApiQueryBase { } } - if (isset ($rvstart)) - $conds[] = 'rev_timestamp >= ' . $this->prepareTimestamp($rvstart); - if (isset ($rvend)) - $conds[] = 'rev_timestamp <= ' . $this->prepareTimestamp($rvend); + $userMax = ($showContent ? 50 : 500); + $botMax = ($showContent ? 200 : 10000); + + if ($enumRevMode) { - if ($singePageMode) { + if (isset ($rvstart)) + $conds[] = 'rev_timestamp >= ' . $this->prepareTimestamp($rvstart); + if (isset ($rvend)) + $conds[] = 'rev_timestamp <= ' . $this->prepareTimestamp($rvend); + + // must manually initialize unset rvlimit if (!isset ($rvlimit)) $rvlimit = 10; - $options['LIMIT'] = $rvlimit + 1; $options['ORDER BY'] = 'rev_timestamp' . ($dirNewer ? '' : ' DESC'); - - // get the first (and only) pageid => title pair - foreach($data->getGoodTitles() as $pageId => $titleObj) { - $conds['rev_page'] = $pageId; - break; - } + + $this->validateLimit('rvlimit', $rvlimit, 1, $userMax, $botMax); + + // There is only one ID + $conds['rev_page'] = array_keys($data->getGoodTitles()); + + } else { + // When working in multi-page non-enumeration mode, + // limit to the latest revision only + $tables[] = 'page'; + $conds[] = 'page_id=rev_page'; + $conds[] = 'page_latest=rev_id'; + $this->validateLimit('page_count', $pageCount, 1, $userMax, $botMax); + + // Get all page IDs + $conds['page_id'] = array_keys($data->getGoodTitles()); + + $rvlimit = $pageCount; // assumption testing -- we should never get more then $pageCount rows. } + $options['LIMIT'] = $rvlimit +1; + $db = $this->getDB(); $this->profileDBIn(); $res = $db->select($tables, $fields, $conds, __CLASS__ . '::' . __FUNCTION__, $options); @@ -134,31 +167,32 @@ class ApiQueryRevisions extends ApiQueryBase { if (++ $count > $rvlimit) { // We've reached the one extra which shows that there are additional pages to be had. Stop here... + if (!$enumRevMode) + $this->dieDebug('Got more rows then expected'); // bug report + $startStr = 'rvstartid=' . $row->rev_id; - $msg = array ('continue' => $startStr ); + $msg = array ( + 'continue' => $startStr + ); $this->getResult()->addMessage('query-status', 'revisions', $msg); break; } - - $revid = intval($row->rev_id); - $pageid = intval($row->rev_page); - $vals = array ( - 'revid' => $revid, + 'revid' => intval($row->rev_id), 'oldid' => intval($row->rev_text_id )); - if( $row->rev_minor_edit ) { + if ($row->rev_minor_edit) { $vals['minor'] = ''; } - + if ($showTimestamp) $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rev_timestamp); - + if ($showUser) { $vals['user'] = $row->rev_user_text; - if( !$row->rev_user ) + if (!$row->rev_user) $vals['anon'] = ''; } @@ -167,13 +201,13 @@ class ApiQueryRevisions extends ApiQueryBase { if ($showContent) { $vals['xml:space'] = 'preserve'; - $vals['*'] = Revision::getRevisionText( $row ); + $vals['*'] = Revision :: getRevisionText($row); } else { - $vals['*'] = ''; // Force all elements to be attributes + $vals['*'] = ''; // Force all elements to be attributes } - $data[$pageid]['revisions']['_element'] = 'rv'; - $data[$pageid]['revisions'][$revid] = $vals; + $data[$row->rev_page]['revisions']['_element'] = 'rv'; + $data[$row->rev_page]['revisions'][$row->rev_id] = $vals; } $db->freeResult($res); @@ -182,6 +216,10 @@ class ApiQueryRevisions extends ApiQueryBase { protected function getAllowedParams() { return array ( + 'rvrevids' => array ( + GN_ENUM_ISMULTI => true, + GN_ENUM_TYPE => 'integer' + ), 'rvlimit' => array ( GN_ENUM_DFLT => 0, GN_ENUM_TYPE => 'limit',