mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Linter
synced 2024-09-23 10:21:52 +00:00
Migrate Database.php to use QueryBuilders everywhere
Bug: T350977 Change-Id: I864c1e4880876b329ba0e8102e6c0f335a149491
This commit is contained in:
parent
91ff1af06b
commit
24155905cd
|
@ -173,7 +173,7 @@ class Database {
|
|||
* @param LintError $error
|
||||
* @return array
|
||||
*/
|
||||
private function serializeError( LintError $error ) {
|
||||
private function buildErrorRow( LintError $error ) {
|
||||
$mwServices = MediaWikiServices::getInstance();
|
||||
$config = $mwServices->getMainConfig();
|
||||
|
||||
|
@ -246,11 +246,11 @@ class Database {
|
|||
$toInsert = array_values( $errors );
|
||||
$toDelete = [];
|
||||
} elseif ( $previous && !$errors ) {
|
||||
$dbw->delete(
|
||||
'linter',
|
||||
[ 'linter_page' => $this->pageId ],
|
||||
__METHOD__
|
||||
);
|
||||
$dbw->newDeleteQueryBuilder()
|
||||
->deleteFrom( 'linter' )
|
||||
->where( [ 'linter_page' => $this->pageId ] )
|
||||
->caller( __METHOD__ )
|
||||
->execute();
|
||||
return [ 'deleted' => $this->countByCat( $previous ), 'added' => [] ];
|
||||
} else {
|
||||
$toInsert = [];
|
||||
|
@ -273,22 +273,22 @@ class Database {
|
|||
$ids[] = $lintError->lintId;
|
||||
}
|
||||
}
|
||||
$dbw->delete(
|
||||
'linter',
|
||||
[ 'linter_id' => $ids ],
|
||||
__METHOD__
|
||||
);
|
||||
$dbw->newDeleteQueryBuilder()
|
||||
->deleteFrom( 'linter' )
|
||||
->where( [ 'linter_id' => $ids ] )
|
||||
->caller( __METHOD__ )
|
||||
->execute();
|
||||
}
|
||||
|
||||
if ( $toInsert ) {
|
||||
// Insert into db, ignoring any duplicate key errors
|
||||
// since they're the same lint error
|
||||
$dbw->insert(
|
||||
'linter',
|
||||
array_map( [ $this, 'serializeError' ], $toInsert ),
|
||||
__METHOD__,
|
||||
[ 'IGNORE' ]
|
||||
);
|
||||
$dbw->newInsertQueryBuilder()
|
||||
->insertInto( 'linter' )
|
||||
->ignore()
|
||||
->rows( array_map( [ $this, 'buildErrorRow' ], $toInsert ) )
|
||||
->caller( __METHOD__ )
|
||||
->execute();
|
||||
}
|
||||
|
||||
return [
|
||||
|
@ -297,13 +297,6 @@ class Database {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getTotalsForPage() {
|
||||
return $this->getTotalsAccurate( [ 'linter_page' => $this->pageId ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an estimate of how many rows are there for the
|
||||
* specified category with EXPLAIN SELECT COUNT(*).
|
||||
|
@ -315,20 +308,20 @@ class Database {
|
|||
* @return int
|
||||
*/
|
||||
private function getTotalsEstimate( $catId ) {
|
||||
$dbr = self::getDBConnectionRef( DB_REPLICA );
|
||||
$dbr = self::getReplicaDBConnection();
|
||||
// First see if there are no rows, or a moderate number
|
||||
// within the limit specified by the MAX_ACCURATE_COUNT.
|
||||
// The distinction between 0, a few and a lot is important
|
||||
// to determine first, as estimateRowCount seem to never
|
||||
// return 0 or accurate low error counts.
|
||||
$rows = $dbr->selectRowCount(
|
||||
'linter',
|
||||
'*',
|
||||
[ 'linter_cat' => $catId ],
|
||||
__METHOD__,
|
||||
$rows = $dbr->newSelectQueryBuilder()
|
||||
->select( '*' )
|
||||
->from( 'linter' )
|
||||
->where( [ 'linter_cat' => $catId ] )
|
||||
// Select 1 more so we can see if we're over the max limit
|
||||
[ 'LIMIT' => self::MAX_ACCURATE_COUNT + 1 ]
|
||||
);
|
||||
->limit( self::MAX_ACCURATE_COUNT + 1 )
|
||||
->caller( __METHOD__ )
|
||||
->fetchRowCount();
|
||||
// Return an accurate count if the number of errors is
|
||||
// below the maximum accurate count limit
|
||||
if ( $rows <= self::MAX_ACCURATE_COUNT ) {
|
||||
|
@ -336,27 +329,25 @@ class Database {
|
|||
}
|
||||
// Now we can just estimate if the maximum accurate count limit
|
||||
// was returned, which isn't the actual count but the limit reached
|
||||
return $dbr->estimateRowCount(
|
||||
'linter',
|
||||
'*',
|
||||
[ 'linter_cat' => $catId ],
|
||||
__METHOD__
|
||||
);
|
||||
return $dbr->newSelectQueryBuilder()
|
||||
->select( '*' )
|
||||
->from( 'linter' )
|
||||
->where( [ 'linter_cat' => $catId ] )
|
||||
->caller( __METHOD__ )
|
||||
->estimateRowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This uses COUNT(*), which is accurate, but can be significantly
|
||||
* slower depending upon how many rows are in the database.
|
||||
*
|
||||
* @param array $conds
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
private function getTotalsAccurate( $conds = [] ) {
|
||||
public function getTotalsForPage(): array {
|
||||
$rows = self::getReplicaDBConnection()->newSelectQueryBuilder()
|
||||
->select( [ 'linter_cat', 'COUNT(*) AS count' ] )
|
||||
->from( 'linter' )
|
||||
->where( $conds )
|
||||
->where( [ 'linter_page' => $this->pageId ] )
|
||||
->caller( __METHOD__ )
|
||||
->groupBy( 'linter_cat' )
|
||||
->fetchResultSet();
|
||||
|
@ -482,15 +473,16 @@ class Database {
|
|||
// Gather some unique pageId values in linter table records into an array
|
||||
$linterPages = [];
|
||||
|
||||
$queryLinterTable = new SelectQueryBuilder( $dbw );
|
||||
$queryLinterTable
|
||||
->select( 'DISTINCT linter_page' )
|
||||
$result = $dbw->newSelectQueryBuilder()
|
||||
->select( 'linter_page' )
|
||||
->distinct()
|
||||
->from( 'linter' )
|
||||
->where( [ 'linter_namespace IS NULL', 'linter_page > ' . $lastElement ] )
|
||||
->where( $dbw->expr( 'linter_page', '>', $lastElement ) )
|
||||
->andWhere( [ 'linter_namespace' => null ] )
|
||||
->orderBy( 'linter_page' )
|
||||
->limit( $linterBatchSize )
|
||||
->caller( __METHOD__ );
|
||||
$result = $queryLinterTable->fetchResultSet();
|
||||
->caller( __METHOD__ )
|
||||
->fetchResultSet();
|
||||
|
||||
foreach ( $result as $row ) {
|
||||
$lastElement = intval( $row->linter_page );
|
||||
|
@ -504,14 +496,12 @@ class Database {
|
|||
|
||||
if ( count( $pageIdBatch ) > 0 ) {
|
||||
|
||||
$queryPageTable = new SelectQueryBuilder( $dbread );
|
||||
$queryPageTable
|
||||
->fields( [ 'page_id', 'page_namespace' ] )
|
||||
$pageResults = $dbread->newSelectQueryBuilder()
|
||||
->select( [ 'page_id', 'page_namespace' ] )
|
||||
->from( 'page' )
|
||||
->where( [ 'page_id' => $pageIdBatch ] )
|
||||
->caller( __METHOD__ );
|
||||
|
||||
$pageResults = $queryPageTable->fetchResultSet();
|
||||
->caller( __METHOD__ )
|
||||
->fetchResultSet();
|
||||
|
||||
foreach ( $pageResults as $pageRow ) {
|
||||
$pageId = intval( $pageRow->page_id );
|
||||
|
@ -519,15 +509,16 @@ class Database {
|
|||
|
||||
// If a record about to be updated has been removed by another process,
|
||||
// the update will not error, and continue updating the existing records.
|
||||
$dbw->update(
|
||||
'linter',
|
||||
[
|
||||
'linter_namespace' => $namespaceID
|
||||
],
|
||||
[ 'linter_namespace IS NULL', 'linter_page = ' . $pageId ],
|
||||
__METHOD__
|
||||
);
|
||||
$updated++;
|
||||
$dbw->newUpdateQueryBuilder()
|
||||
->update( 'linter' )
|
||||
->set( [ 'linter_namespace' => $namespaceID ] )
|
||||
->where( [
|
||||
'linter_namespace' => null,
|
||||
'linter_page' => $pageId
|
||||
] )
|
||||
->caller( __METHOD__ )
|
||||
->execute();
|
||||
$updated += $dbw->affectedRows();
|
||||
}
|
||||
|
||||
// Sleep between batches for replication to catch up
|
||||
|
@ -587,16 +578,18 @@ class Database {
|
|||
$updated = 0;
|
||||
$lastElement = 0;
|
||||
do {
|
||||
$queryLinterTable = new SelectQueryBuilder( $dbw );
|
||||
$queryLinterTable
|
||||
->table( 'linter' )
|
||||
->fields( [ 'linter_id', 'linter_params', 'linter_template', 'linter_tag' ] )
|
||||
->where( [ 'linter_params != \'[]\'', 'linter_params IS NOT NULL', 'linter_id > ' . $lastElement ] )
|
||||
$results = $dbw->newSelectQueryBuilder()
|
||||
->select( [ 'linter_id', 'linter_params', 'linter_template', 'linter_tag' ] )
|
||||
->from( 'linter' )
|
||||
->where( [
|
||||
$dbw->expr( "linter_params", '!=', '[]' ),
|
||||
$dbw->expr( "linter_params", '!=', null ),
|
||||
$dbw->expr( "linter_id", '>', $lastElement )
|
||||
] )
|
||||
->orderBy( 'linter_id', selectQueryBuilder::SORT_ASC )
|
||||
->limit( $batchSize )
|
||||
->caller( __METHOD__ );
|
||||
$results = $queryLinterTable->fetchResultSet();
|
||||
|
||||
->caller( __METHOD__ )
|
||||
->fetchResultSet();
|
||||
$linterBatchLength = 0;
|
||||
|
||||
foreach ( $results as $row ) {
|
||||
|
@ -626,15 +619,13 @@ class Database {
|
|||
if ( $templateInfo != $row->linter_template || $tagInfo != $row->linter_tag ) {
|
||||
// If the record about to be updated has been removed by another process,
|
||||
// the update will not do anything and just return with no records updated.
|
||||
$dbw->update(
|
||||
'linter',
|
||||
[
|
||||
'linter_template' => $templateInfo, 'linter_tag' => $tagInfo
|
||||
],
|
||||
[ 'linter_id' => $linter_id ],
|
||||
__METHOD__
|
||||
);
|
||||
$updated++;
|
||||
$dbw->newUpdateQueryBuilder()
|
||||
->update( 'linter' )
|
||||
->set( [ 'linter_template' => $templateInfo, 'linter_tag' => $tagInfo, ] )
|
||||
->where( [ 'linter_id' => $linter_id ] )
|
||||
->caller( __METHOD__ )
|
||||
->execute();
|
||||
$updated += $dbw->affectedRows();
|
||||
}
|
||||
$linterBatchLength++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue