api: Use RevisionStore::newRevisionsFromBatch to fetch revision records
This bundles the slot queries from RevisionRecords into one query for all revisions requested for the module. Before for each revision a query for the slots was needed Change-Id: I2c08d0437a51de252d53a59269e1d701c475d403
This commit is contained in:
parent
489874ef72
commit
704ba8ed5f
5 changed files with 56 additions and 4 deletions
|
|
@ -357,6 +357,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
|
|||
|
||||
if ( $resultPageSet === null ) {
|
||||
$this->executeGenderCacheFromResultWrapper( $res, __METHOD__, 'ar' );
|
||||
$revisions = $this->getRevisionRecords( $res, 'archive' );
|
||||
}
|
||||
|
||||
$pageMap = []; // Maps ns&title to array index
|
||||
|
|
@ -393,7 +394,8 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
|
|||
$generated[] = $row->ar_rev_id;
|
||||
}
|
||||
} else {
|
||||
$revision = $this->revisionStore->newRevisionFromArchiveRow( $row );
|
||||
// @phan-suppress-next-line PhanTypeArraySuspiciousNullable Set when used
|
||||
$revision = $revisions[$row->ar_rev_id];
|
||||
$rev = $this->extractRevisionInfo( $revision, $row );
|
||||
|
||||
if ( !isset( $pageMap[$row->ar_namespace][$row->ar_title] ) ) {
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
|
|||
|
||||
if ( $resultPageSet === null ) {
|
||||
$this->executeGenderCacheFromResultWrapper( $res, __METHOD__ );
|
||||
$revisions = $this->getRevisionRecords( $res );
|
||||
}
|
||||
|
||||
$pageMap = []; // Maps rev_page to array index
|
||||
|
|
@ -249,7 +250,8 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
|
|||
$generated[] = $row->rev_id;
|
||||
}
|
||||
} else {
|
||||
$revision = $this->revisionStore->newRevisionFromRow( $row, 0, Title::newFromRow( $row ) );
|
||||
// @phan-suppress-next-line PhanTypeArraySuspiciousNullable Set when used
|
||||
$revision = $revisions[$row->rev_id];
|
||||
$rev = $this->extractRevisionInfo( $revision, $row );
|
||||
|
||||
if ( !isset( $pageMap[$row->rev_page] ) ) {
|
||||
|
|
|
|||
|
|
@ -239,6 +239,11 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
|
|||
$this->addWhereRange( 'ar_id', $dir, null, null );
|
||||
|
||||
$res = $this->select( __METHOD__ );
|
||||
|
||||
if ( $resultPageSet === null ) {
|
||||
$revisions = $this->getRevisionRecords( $res, 'archive' );
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
$generated = [];
|
||||
foreach ( $res as $row ) {
|
||||
|
|
@ -276,7 +281,8 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
|
|||
|
||||
$fit = $this->addPageSubItem(
|
||||
$pageMap[$row->ar_namespace][$row->ar_title],
|
||||
$this->extractRevisionInfo( $this->revisionStore->newRevisionFromArchiveRow( $row ), $row ),
|
||||
// @phan-suppress-next-line PhanTypeArraySuspiciousNullable Set when used
|
||||
$this->extractRevisionInfo( $revisions[$row->ar_rev_id], $row ),
|
||||
'rev'
|
||||
);
|
||||
if ( !$fit ) {
|
||||
|
|
|
|||
|
|
@ -403,6 +403,10 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
|
|||
$hookData = [];
|
||||
$res = $this->select( __METHOD__, [], $hookData );
|
||||
|
||||
if ( $resultPageSet === null ) {
|
||||
$revisions = $this->getRevisionRecords( $res );
|
||||
}
|
||||
|
||||
foreach ( $res as $row ) {
|
||||
if ( ++$count > $this->limit ) {
|
||||
// We've reached the one extra which shows that there are
|
||||
|
|
@ -422,7 +426,8 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
|
|||
if ( $resultPageSet !== null ) {
|
||||
$generated[] = $row->rev_id;
|
||||
} else {
|
||||
$revision = $this->revisionStore->newRevisionFromRow( $row, 0, Title::newFromRow( $row ) );
|
||||
// @phan-suppress-next-line PhanTypeArraySuspiciousNullable Set when used
|
||||
$revision = $revisions[$row->rev_id];
|
||||
$rev = $this->extractRevisionInfo( $revision, $row );
|
||||
$fit = $this->processRow( $row, $rev, $hookData ) &&
|
||||
$this->addPageSubItem( $row->rev_page, $rev, 'rev' );
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ use MediaWiki\Title\Title;
|
|||
use Wikimedia\ParamValidator\ParamValidator;
|
||||
use Wikimedia\ParamValidator\TypeDef\EnumDef;
|
||||
use Wikimedia\ParamValidator\TypeDef\IntegerDef;
|
||||
use Wikimedia\Rdbms\IResultWrapper;
|
||||
|
||||
/**
|
||||
* A base class for functions common to producing a list of revisions.
|
||||
|
|
@ -297,6 +298,42 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
|
|||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create RevisionRecord objects with the RevisionStore
|
||||
* @param IResultWrapper $res
|
||||
* @param string|null $mode 'archive' or omit
|
||||
* @return RevisionRecord[]
|
||||
*/
|
||||
protected function getRevisionRecords( $res, $mode = null ) {
|
||||
$result = $this->revisionStore->newRevisionsFromBatch( $res, [
|
||||
'slots' => $this->needSlots ? ( $this->slotRoles ?? [ SlotRecord::MAIN ] ) : null,
|
||||
'archive' => $mode === 'archive',
|
||||
// RevisionStore::newRevisionsFromBatch also supports a 'content' option to prefetch the content of
|
||||
// all revisions. This can be problematic for big list of revisions as the content does not fit into
|
||||
// MainConfigNames::APIMaxResultSize and the module produce a continue parameter to get the next content
|
||||
// with the next request, but internally all contents are already fetched, which could be huge blobs.
|
||||
// Also this loads content of revdeleted content, which is not used later
|
||||
// Also failures on loading blobs would make the whole batch invalid and needs extra checking
|
||||
// how to handle that in the module
|
||||
// 'content' => $this->fetchContent,
|
||||
] );
|
||||
|
||||
if ( !$result->isOK() ) {
|
||||
// RevisionStore can set some internalerror_info
|
||||
ApiBase::dieDebug( __METHOD__, Status::wrap( $result )->getWikiText( false, false, 'en' ) );
|
||||
}
|
||||
|
||||
// Assert that all ids are set
|
||||
$revisions = $result->getValue();
|
||||
$idField = $mode !== 'archive' ? 'rev_id' : 'ar_rev_id';
|
||||
foreach ( $res as $row ) {
|
||||
if ( !isset( $revisions[$row->$idField] ) ) {
|
||||
ApiBase::dieDebug( __METHOD__, 'RevisionStore does not return record for ' . $row->$idField );
|
||||
}
|
||||
}
|
||||
return $revisions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract information from the RevisionRecord
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue