*/
use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Shell\Shell;
if ( !defined( 'MEDIAWIKI' ) ) {
class CheckStorage {
const CONCAT_HEADER = 'O:27:"concatenatedgziphistoryblob"';
public $oldIdMap, $errors;
+ /** @var ExternalStoreDB */
public $dbStore = null;
public $errorDescriptions = [
];
function check( $fix = false, $xml = '' ) {
+ global $wgMultiContentRevisionSchemaMigrationStage;
+
$dbr = wfGetDB( DB_REPLICA );
if ( $fix ) {
print "Checking, will fix errors if possible...\n";
$chunkEnd = $chunkStart + $chunkSize - 1;
// print "$chunkStart of $maxRevId\n";
- // Fetch revision rows
$this->oldIdMap = [];
$dbr->ping();
- $res = $dbr->select( 'revision', [ 'rev_id', 'rev_text_id' ],
- [ "rev_id BETWEEN $chunkStart AND $chunkEnd" ], __METHOD__ );
- foreach ( $res as $row ) {
- $this->oldIdMap[$row->rev_id] = $row->rev_text_id;
+
+ // Fetch revision rows
+ if ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_OLD ) {
+ $res = $dbr->select( 'revision', [ 'rev_id', 'rev_text_id' ],
+ [ "rev_id BETWEEN $chunkStart AND $chunkEnd" ], __METHOD__ );
+ foreach ( $res as $row ) {
+ if ( !isset( $this->oldIdMap[ $row->rev_text_id ] ) ) {
+ $this->oldIdMap[ $row->rev_text_id ] = [ $row->rev_id ];
+ } elseif ( !in_array( $row->rev_id, $this->oldIdMap[ $row->rev_text_id ] ) ) {
+ $this->oldIdMap[ $row->rev_text_id ][] = $row->rev_id;
+ }
+ }
+ } else {
+ $res = $dbr->select(
+ [ 'slots', 'content' ],
+ [ 'slot_revision_id', 'content_address' ],
+ [ "slot_revision_id BETWEEN $chunkStart AND $chunkEnd" ],
+ __METHOD__,
+ [],
+ [ 'content' => [ 'INNER JOIN', [ 'content_id = slot_content_id' ] ] ]
+ );
+ $blobStore = MediaWikiServices::getInstance()->getBlobStore();
+ foreach ( $res as $row ) {
+ $textId = $blobStore->getTextIdFromAddress( $row->content_address );
+ if ( $textId ) {
+ if ( !isset( $this->oldIdMap[$textId] ) ) {
+ $this->oldIdMap[ $textId ] = [ $row->slot_revision_id ];
+ } elseif ( !in_array( $row->slot_revision_id, $this->oldIdMap[$textId] ) ) {
+ $this->oldIdMap[ $textId ][] = $row->slot_revision_id;
+ }
+ }
+ }
}
if ( !count( $this->oldIdMap ) ) {
}
// Fetch old_flags
- $missingTextRows = array_flip( $this->oldIdMap );
+ $missingTextRows = $this->oldIdMap;
$externalRevs = [];
$objectRevs = [];
$res = $dbr->select(
'text',
[ 'old_id', 'old_flags' ],
- [ 'old_id' => $this->oldIdMap ],
+ [ 'old_id' => array_keys( $this->oldIdMap ) ],
__METHOD__
);
foreach ( $res as $row ) {
/**
- * @var $flags int
+ * @var int $flags
*/
$flags = $row->old_flags;
$id = $row->old_id;
}
// Output errors for any missing text rows
- foreach ( $missingTextRows as $oldId => $revId ) {
+ foreach ( $missingTextRows as $oldId => $revIds ) {
$this->addError( 'restore revision', "Error: missing text row", $oldId );
}
// Check external normal blobs for existence
if ( count( $externalNormalBlobs ) ) {
if ( is_null( $this->dbStore ) ) {
- $this->dbStore = new ExternalStoreDB;
+ $esFactory = MediaWikiServices::getInstance()->getExternalStoreFactory();
+ $this->dbStore = $esFactory->getStore( 'DB' );
}
foreach ( $externalConcatBlobs as $cluster => $xBlobIds ) {
$blobIds = array_keys( $xBlobIds );
if ( is_array( $ids ) ) {
$revIds = [];
foreach ( $ids as $id ) {
- $revIds = array_merge( $revIds, array_keys( $this->oldIdMap, $id ) );
+ $revIds = array_unique( array_merge( $revIds, $this->oldIdMap[$id] ) );
}
print "$msg in text rows " . implode( ', ', $ids ) .
", revisions " . implode( ', ', $revIds ) . "\n";
} else {
$id = $ids;
- $revIds = array_keys( $this->oldIdMap, $id );
+ $revIds = $this->oldIdMap[$id];
if ( count( $revIds ) == 1 ) {
print "$msg in old_id $id, rev_id {$revIds[0]}\n";
} else {
}
if ( is_null( $this->dbStore ) ) {
- $this->dbStore = new ExternalStoreDB;
+ $esFactory = MediaWikiServices::getInstance()->getExternalStoreFactory();
+ $this->dbStore = $esFactory->getStore( 'DB' );
}
foreach ( $externalConcatBlobs as $cluster => $oldIds ) {
function importRevision( &$revision, &$importer ) {
$id = $revision->getID();
- $content = $revision->getContent( Revision::RAW );
+ $content = $revision->getContent( RevisionRecord::RAW );
$id = $id ?: '';
if ( $content === null ) {