maintenance: Use SelectQueryBuilder to construct queries

Part 2 of migrating files in `maintenance/` from IDatabase::select()
to SelectQueryBuilder.

Change-Id: I73eda0e4429016588bcfc6b3b490cb3fc0f5b711
This commit is contained in:
Derick Alangi 2022-07-21 10:36:56 +01:00
parent e69fbb0e51
commit 7ad8fae44e
No known key found for this signature in database
GPG key ID: 13EC8B5BEEE105FF
10 changed files with 140 additions and 108 deletions

View file

@ -43,7 +43,11 @@ class DeleteArchivedRevisions extends Maintenance {
$dbw = $this->getDB( DB_PRIMARY );
if ( !$this->hasOption( 'delete' ) ) {
$count = $dbw->selectField( 'archive', 'COUNT(*)', '', __METHOD__ );
$count = $dbw->newSelectQueryBuilder()
->select( 'COUNT(*)' )
->from( 'archive' )
->caller( __METHOD__ )
->fetchField();
$this->output( "Found $count revisions to delete.\n" );
$this->output( "Please run the script again with the --delete option "
. "to really delete the revisions.\n" );

View file

@ -113,13 +113,14 @@ class DeleteAutoPatrolLogs extends Maintenance {
$conds[] = 'log_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( $before ) );
}
return $dbr->selectFieldValues(
'logging',
'log_id',
$conds,
__METHOD__,
[ 'LIMIT' => $this->getBatchSize(), 'ORDER BY' => 'log_id' ]
);
return $dbr->newSelectQueryBuilder()
->select( 'log_id' )
->from( 'logging' )
->where( $conds )
->orderBy( 'log_id' )
->limit( $this->getBatchSize() )
->caller( __METHOD__ )
->fetchFieldValues();
}
private function getRowsOld( $fromId ) {
@ -141,13 +142,14 @@ class DeleteAutoPatrolLogs extends Maintenance {
$conds[] = 'log_timestamp < ' . $dbr->addQuotes( $dbr->timestamp( $before ) );
}
$result = $dbr->select(
'logging',
[ 'log_id', 'log_params' ],
$conds,
__METHOD__,
[ 'LIMIT' => $batchSize, 'ORDER BY' => 'log_id' ]
);
$result = $dbr->newSelectQueryBuilder()
->select( [ 'log_id', 'log_params' ] )
->from( 'logging' )
->where( $conds )
->orderBy( 'log_id' )
->limit( $batchSize )
->caller( __METHOD__ )
->fetchResultSet();
$last = null;
$autopatrols = [];

View file

@ -49,17 +49,17 @@ class DeleteDefaultMessages extends Maintenance {
$userFactory = $services->getUserFactory();
$actorQuery = ActorMigration::newMigration()
->getWhere( $dbr, 'rev_user', $userFactory->newFromName( 'MediaWiki default' ) );
$res = $dbr->select(
[ 'page', 'revision' ] + $actorQuery['tables'],
[ 'page_namespace', 'page_title' ],
[
$res = $dbr->newSelectQueryBuilder()
->select( [ 'page_namespace', 'page_title' ] )
->tables( [ 'page', 'revision' ] + $actorQuery['tables'] )
->where( [
'page_namespace' => NS_MEDIAWIKI,
$actorQuery['conds'],
],
__METHOD__,
[],
[ 'revision' => [ 'JOIN', 'page_latest=rev_id' ] ] + $actorQuery['joins']
);
] )
->joinConds( [ 'revision' => [ 'JOIN', 'page_latest=rev_id' ] ] + $actorQuery['joins'] )
->caller( __METHOD__ )
->fetchResultSet();
if ( $res->numRows() == 0 ) {
// No more messages left

View file

@ -59,7 +59,12 @@ class DeleteOldRevisions extends Maintenance {
# Get "active" revisions from the page table
$this->output( "Searching for active revisions..." );
$res = $dbw->select( 'page', 'page_latest', $pageConds, __METHOD__ );
$res = $dbw->newSelectQueryBuilder()
->select( 'page_latest' )
->from( 'page' )
->where( $pageConds )
->caller( __METHOD__ )
->fetchResultSet();
$latestRevs = [];
foreach ( $res as $row ) {
$latestRevs[] = $row->page_latest;
@ -71,7 +76,12 @@ class DeleteOldRevisions extends Maintenance {
if ( count( $latestRevs ) > 0 ) {
$revConds[] = 'rev_id NOT IN (' . $dbw->makeList( $latestRevs ) . ')';
}
$res = $dbw->select( 'revision', 'rev_id', $revConds, __METHOD__ );
$res = $dbw->newSelectQueryBuilder()
->select( 'rev_id' )
->from( 'revision' )
->where( $revConds )
->caller( __METHOD__ )
->fetchResultSet();
$oldRevs = [];
foreach ( $res as $row ) {
$oldRevs[] = $row->rev_id;

View file

@ -48,13 +48,16 @@ class DeleteOrphanedRevisions extends Maintenance {
$dbw = $this->getDB( DB_PRIMARY );
$this->beginTransaction( $dbw, __METHOD__ );
list( $page, $revision ) = $dbw->tableNamesN( 'page', 'revision' );
# Find all the orphaned revisions
$this->output( "Checking for orphaned revisions..." );
$sql = "SELECT rev_id FROM {$revision} LEFT JOIN {$page} ON rev_page = page_id "
. "WHERE page_namespace IS NULL";
$res = $dbw->query( $sql, 'deleteOrphanedRevisions' );
$res = $dbw->newSelectQueryBuilder()
->select( 'rev_id' )
->from( 'revision' )
->leftJoin( 'page', null, 'rev_page = page_id' )
->where( [ 'page_namespace' => null ] )
->caller( 'deleteOrphanedRevisions' )
->fetchResultSet();
# Stash 'em all up for deletion (if needed)
$revisions = [];

View file

@ -56,13 +56,13 @@ class DeleteTag extends Maintenance {
// Iterate over change_tag, deleting rows in batches
$count = 0;
do {
$ids = $dbw->selectFieldValues(
'change_tag',
'ct_id',
[ 'ct_tag_id' => $tagId ],
__METHOD__,
[ 'LIMIT' => $this->getBatchSize() ]
);
$ids = $dbw->newSelectQueryBuilder()
->select( 'ct_id' )
->from( 'change_tag' )
->where( [ 'ct_tag_id' => $tagId ] )
->limit( $this->getBatchSize() )
->caller( __METHOD__ )
->fetchFieldValues();
if ( !$ids ) {
break;

View file

@ -45,16 +45,20 @@ class DumpLinks extends Maintenance {
public function execute() {
$dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select( [ 'pagelinks', 'page' ],
[
$result = $dbr->newSelectQueryBuilder()
->select( [
'page_id',
'page_namespace',
'page_title',
'pl_namespace',
'pl_title' ],
[ 'page_id=pl_from' ],
__METHOD__,
[ 'ORDER BY' => 'page_id' ] );
'pl_title'
] )
->from( 'page' )
->join( 'pagelinks', null, [ 'page_id=pl_from' ] )
->orderBy( 'page_id' )
->caller( __METHOD__ )
->fetchResultSet();
$lastPage = null;
foreach ( $result as $row ) {

View file

@ -81,14 +81,14 @@ By default, outputs relative paths against the parent directory of $wgUploadDire
*/
private function fetchUsed( $shared ) {
$dbr = $this->getDB( DB_REPLICA );
$image = $dbr->tableName( 'image' );
$imagelinks = $dbr->tableName( 'imagelinks' );
$sql = "SELECT DISTINCT il_to, img_name
FROM $imagelinks
LEFT JOIN $image
ON il_to=img_name";
$result = $dbr->query( $sql, __METHOD__ );
$result = $dbr->newSelectQueryBuilder()
->select( [ 'il_to', 'img_name' ] )
->distinct()
->from( 'imagelinks' )
->leftJoin( 'image', null, 'il_to=img_name' )
->caller( __METHOD__ )
->fetchResultSet();
foreach ( $result as $row ) {
$this->outputItem( $row->il_to, $shared );
@ -102,10 +102,11 @@ By default, outputs relative paths against the parent directory of $wgUploadDire
*/
private function fetchLocal( $shared ) {
$dbr = $this->getDB( DB_REPLICA );
$result = $dbr->select( 'image',
[ 'img_name' ],
'',
__METHOD__ );
$result = $dbr->newSelectQueryBuilder()
->select( 'img_name' )
->from( 'image' )
->caller( __METHOD__ )
->fetchResultSet();
foreach ( $result as $row ) {
$this->outputItem( $row->img_name, $shared );

View file

@ -60,9 +60,17 @@ class EraseArchivedFile extends Maintenance {
// specified version
$dbw = $this->getDB( DB_PRIMARY );
$fileQuery = ArchivedFile::getQueryInfo();
$row = $dbw->selectRow( $fileQuery['tables'], $fileQuery['fields'],
[ 'fa_storage_group' => 'deleted', 'fa_storage_key' => $filekey ],
__METHOD__, [], $fileQuery['joins'] );
$row = $dbw->newSelectQueryBuilder()
->select( $fileQuery['fields'] )
->tables( $fileQuery['tables'] )
->where( [
'fa_storage_group' => 'deleted',
'fa_storage_key' => $filekey
] )
->joinConds( $fileQuery['joins'] )
->caller( __METHOD__ )
->fetchRow();
if ( !$row ) {
$this->fatalError( "No deleted file exists with key '$filekey'." );
}
@ -91,9 +99,16 @@ class EraseArchivedFile extends Maintenance {
protected function scrubAllVersions( $name ) {
$dbw = $this->getDB( DB_PRIMARY );
$fileQuery = ArchivedFile::getQueryInfo();
$res = $dbw->select( $fileQuery['tables'], $fileQuery['fields'],
[ 'fa_name' => $name, 'fa_storage_group' => 'deleted' ],
__METHOD__, [], $fileQuery['joins'] );
$res = $dbw->newSelectQueryBuilder()
->select( $fileQuery['fields'] )
->tables( $fileQuery['tables'] )
->where( [
'fa_name' => $name,
'fa_storage_group' => 'deleted'
] )
->joinConds( $fileQuery['joins'] )
->caller( __METHOD__ )
->fetchResultSet();
foreach ( $res as $row ) {
$this->scrubVersion( ArchivedFile::newFromRow( $row ) );
}

View file

@ -262,19 +262,17 @@ class FindBadBlobs extends Maintenance {
$db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
$queryInfo = $this->revisionStore->getQueryInfo();
$quotedTimestamp = $db->addQuotes( $fromTimestamp );
$rows = $db->select(
$queryInfo['tables'],
$queryInfo['fields'],
"rev_timestamp > $quotedTimestamp OR "
. "(rev_timestamp = $quotedTimestamp AND rev_id > $afterId )",
__METHOD__,
[
'USE INDEX' => [ 'revision' => 'rev_timestamp' ],
'ORDER BY' => 'rev_timestamp, rev_id',
'LIMIT' => $batchSize,
],
$queryInfo['joins']
);
$rows = $db->newSelectQueryBuilder()
->select( $queryInfo['fields'] )
->tables( $queryInfo['tables'] )
->where( "rev_timestamp > $quotedTimestamp OR "
. "(rev_timestamp = $quotedTimestamp AND rev_id > $afterId )" )
->joinConds( $queryInfo['joins'] )
->useIndex( [ 'revision' => 'rev_timestamp' ] )
->orderBy( [ 'rev_timestamp', 'rev_id' ] )
->limit( $batchSize )
->caller( __METHOD__ )
->fetchResultSet();
$result = $this->revisionStore->newRevisionsFromBatch( $rows, [ 'slots' => true ] );
$this->handleStatus( $result );
@ -294,14 +292,15 @@ class FindBadBlobs extends Maintenance {
private function loadArchiveByRevisionId( int $afterId, int $uptoId, $batchSize ) {
$db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
$queryInfo = $this->revisionStore->getArchiveQueryInfo();
$rows = $db->select(
$queryInfo['tables'],
$queryInfo['fields'],
[ "ar_rev_id > $afterId", "ar_rev_id <= $uptoId" ],
__METHOD__,
[ 'LIMIT' => $batchSize, 'ORDER BY' => 'ar_rev_id' ],
$queryInfo['joins']
);
$rows = $db->newSelectQueryBuilder()
->select( $queryInfo['fields'] )
->tables( $queryInfo['tables'] )
->where( [ "ar_rev_id > $afterId", "ar_rev_id <= $uptoId" ] )
->joinConds( $queryInfo['joins'] )
->orderBy( 'ar_rev_id' )
->limit( $batchSize )
->caller( __METHOD__ )
->fetchResultSet();
$result = $this->revisionStore->newRevisionsFromBatch(
$rows,
[ 'archive' => true, 'slots' => true ]
@ -325,13 +324,13 @@ class FindBadBlobs extends Maintenance {
*/
private function getNextRevision( int $revId, string $comp, string $dir ) {
$db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
$next = $db->selectField(
'revision',
'rev_id',
"rev_id $comp $revId",
__METHOD__,
[ 'ORDER BY' => "rev_id $dir" ]
);
$next = $db->newSelectQueryBuilder()
->select( 'rev_id' )
->from( 'revision' )
->where( "rev_id $comp $revId" )
->orderBy( [ "rev_id" ], $dir )
->caller( __METHOD__ )
->fetchField();
return (int)$next;
}
@ -374,16 +373,13 @@ class FindBadBlobs extends Maintenance {
$db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
$queryInfo = $this->revisionStore->getQueryInfo();
$rows = $db->select(
$queryInfo['tables'],
$queryInfo['fields'],
[
'rev_id ' => $ids,
],
__METHOD__,
[],
$queryInfo['joins']
);
$rows = $db->newSelectQueryBuilder()
->select( $queryInfo['fields'] )
->tables( $queryInfo['tables'] )
->where( [ 'rev_id' => $ids ] )
->joinConds( $queryInfo['joins'] )
->caller( __METHOD__ )
->fetchResultSet();
$result = $this->revisionStore->newRevisionsFromBatch( $rows, [ 'slots' => true ] );
@ -397,16 +393,13 @@ class FindBadBlobs extends Maintenance {
$archiveQueryInfo = $this->revisionStore->getArchiveQueryInfo();
$remainingIds = array_diff( $ids, array_keys( $revisions ) );
$rows = $db->select(
$archiveQueryInfo['tables'],
$archiveQueryInfo['fields'],
[
'ar_rev_id ' => $remainingIds,
],
__METHOD__,
[],
$archiveQueryInfo['joins']
);
$rows = $db->newSelectQueryBuilder()
->select( $archiveQueryInfo['fields'] )
->tables( $archiveQueryInfo['tables'] )
->where( [ 'ar_rev_id' => $remainingIds ] )
->joinConds( $archiveQueryInfo['joins'] )
->caller( __METHOD__ )
->fetchResultSet();
$archiveResult = $this->revisionStore->newRevisionsFromBatch(
$rows,