$fld_patrolled = false, $fld_tags = false, $fld_size = false, $fld_sizediff = false;
public function execute() {
- global $wgActorTableSchemaMigrationStage;
-
// Parse some parameters
$this->params = $this->extractRequestParams();
// a wiki with users "Test00000001" to "Test99999999"), use a
// generator with batched lookup and continuation.
$userIter = call_user_func( function () use ( $dbSecondary, $sort, $op, $fname ) {
- global $wgActorTableSchemaMigrationStage;
-
$fromName = false;
if ( !is_null( $this->params['continue'] ) ) {
$continue = explode( '|', $this->params['continue'] );
do {
$from = $fromName ? "$op= " . $dbSecondary->addQuotes( $fromName ) : false;
-
- // For the new schema, pull from the actor table. For the
- // old, pull from rev_user.
- if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
- $res = $dbSecondary->select(
- 'actor',
- [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
- array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
- $fname,
- [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
- );
- } else {
- $res = $dbSecondary->select(
- 'revision',
- [ 'actor_id' => 'NULL', 'user_id' => 'rev_user', 'user_name' => 'rev_user_text' ],
- array_merge( [ "rev_user_text$like" ], $from ? [ "rev_user_text $from" ] : [] ),
- $fname,
- [ 'DISTINCT', 'ORDER BY' => [ "rev_user_text $sort" ], 'LIMIT' => $limit ]
- );
- }
+ $res = $dbSecondary->select(
+ 'actor',
+ [ 'actor_id', 'user_id' => 'COALESCE(actor_user,0)', 'user_name' => 'actor_name' ],
+ array_merge( [ "actor_name$like" ], $from ? [ "actor_name $from" ] : [] ),
+ $fname,
+ [ 'ORDER BY' => [ "user_name $sort" ], 'LIMIT' => $limit ]
+ );
$count = 0;
$fromName = false;
$from = "$op= $fromId";
}
- // For the new schema, just select from the actor table. For the
- // old, select from user.
- if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
- $res = $dbSecondary->select(
- 'actor',
- [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
- array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
- __METHOD__,
- [ 'ORDER BY' => "user_id $sort" ]
- );
- } else {
- $res = $dbSecondary->select(
- 'user',
- [ 'actor_id' => 'NULL', 'user_id' => 'user_id', 'user_name' => 'user_name' ],
- array_merge( [ 'user_id' => $ids ], $from ? [ "user_id $from" ] : [] ),
- __METHOD__,
- [ 'ORDER BY' => "user_id $sort" ]
- );
- }
+ $res = $dbSecondary->select(
+ 'actor',
+ [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+ array_merge( [ 'actor_user' => $ids ], $from ? [ "actor_id $from" ] : [] ),
+ __METHOD__,
+ [ 'ORDER BY' => "user_id $sort" ]
+ );
$userIter = UserArray::newFromResult( $res );
$batchSize = count( $ids );
} else {
$from = "$op= " . $dbSecondary->addQuotes( $fromName );
}
- // For the new schema, just select from the actor table. For the
- // old, select from user then merge in any unknown users (IPs and imports).
- if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
- $res = $dbSecondary->select(
- 'actor',
- [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
- array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
- __METHOD__,
- [ 'ORDER BY' => "actor_name $sort" ]
- );
- $userIter = UserArray::newFromResult( $res );
- } else {
- $res = $dbSecondary->select(
- 'user',
- [ 'actor_id' => 'NULL', 'user_id', 'user_name' ],
- array_merge( [ 'user_name' => array_keys( $names ) ], $from ? [ "user_name $from" ] : [] ),
- __METHOD__
- );
- foreach ( $res as $row ) {
- $names[$row->user_name] = $row;
- }
- if ( $this->params['dir'] == 'newer' ) {
- ksort( $names, SORT_STRING );
- } else {
- krsort( $names, SORT_STRING );
- }
- $neg = $op === '>' ? -1 : 1;
- $userIter = call_user_func( function () use ( $names, $fromName, $neg ) {
- foreach ( $names as $name => $row ) {
- if ( $fromName === false || $neg * strcmp( $name, $fromName ) <= 0 ) {
- $user = $row ? User::newFromRow( $row ) : User::newFromName( $name, false );
- yield $user;
- }
- }
- } );
- }
+ $res = $dbSecondary->select(
+ 'actor',
+ [ 'actor_id', 'user_id' => 'actor_user', 'user_name' => 'actor_name' ],
+ array_merge( [ 'actor_name' => array_keys( $names ) ], $from ? [ "actor_id $from" ] : [] ),
+ __METHOD__,
+ [ 'ORDER BY' => "actor_name $sort" ]
+ );
+ $userIter = UserArray::newFromResult( $res );
$batchSize = count( $names );
}
- // With the new schema, the DB query will order by actor so update $this->orderBy to match.
- if ( $batchSize > 1 && ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) ) {
+ // The DB query will order by actor so update $this->orderBy to match.
+ if ( $batchSize > 1 ) {
$this->orderBy = 'actor';
}
- // Use the 'contributions' replica, but only if we're querying by user ID (T216656).
- if ( $this->orderBy === 'id' &&
- !( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW )
- ) {
- $this->selectNamedDB( 'contributions', DB_REPLICA, 'contributions' );
- }
-
$count = 0;
$limit = $this->params['limit'];
$userIter->rewind();
* @param int $limit
*/
private function prepareQuery( array $users, $limit ) {
- global $wgActorTableSchemaMigrationStage;
-
$this->resetQueryParams();
$db = $this->getDB();
$revQuery = MediaWikiServices::getInstance()->getRevisionStore()->getQueryInfo( [ 'page' ] );
- if ( $wgActorTableSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) {
- $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
- $orderUserField = 'rev_actor';
- $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
- $tsField = 'revactor_timestamp';
- $idField = 'revactor_rev';
-
- // T221511: MySQL/MariaDB (10.1.37) can sometimes irrationally decide that querying `actor`
- // before `revision_actor_temp` and filesorting is somehow better than querying $limit+1 rows
- // from `revision_actor_temp`. Tell it not to reorder the query (and also reorder it ourselves
- // because as generated by RevisionStore it'll have `revision` first rather than
- // `revision_actor_temp`). But not when uctag is used, as it seems as likely to be harmed as
- // helped in that case, and not when there's only one User because in that case it fetches
- // the one `actor` row as a constant and doesn't filesort.
- if ( count( $users ) > 1 && !isset( $this->params['tag'] ) ) {
- $revQuery['joins']['revision'] = $revQuery['joins']['temp_rev_user'];
- unset( $revQuery['joins']['temp_rev_user'] );
- $this->addOption( 'STRAIGHT_JOIN' );
- // It isn't actually necesssary to reorder $revQuery['tables'] as Database does the right thing
- // when join conditions are given for all joins, but Gergő is wary of relying on that so pull
- // `revision_actor_temp` to the start.
- $revQuery['tables'] =
- [ 'temp_rev_user' => $revQuery['tables']['temp_rev_user'] ] + $revQuery['tables'];
- }
- } else {
- // If we're dealing with user names (rather than IDs) in read-old mode,
- // pass false for ActorMigration::getWhere()'s $useId parameter so
- // $revWhere['conds'] isn't an OR.
- $revWhere = ActorMigration::newMigration()
- ->getWhere( $db, 'rev_user', $users, $this->orderBy === 'id' );
- $orderUserField = $this->orderBy === 'id' ? 'rev_user' : 'rev_user_text';
- $userField = $revQuery['fields'][$orderUserField];
- $tsField = 'rev_timestamp';
- $idField = 'rev_id';
+ $revWhere = ActorMigration::newMigration()->getWhere( $db, 'rev_user', $users );
+ $orderUserField = 'rev_actor';
+ $userField = $this->orderBy === 'actor' ? 'revactor_actor' : 'actor_name';
+ $tsField = 'revactor_timestamp';
+ $idField = 'revactor_rev';
+
+ // T221511: MySQL/MariaDB (10.1.37) can sometimes irrationally decide that querying `actor`
+ // before `revision_actor_temp` and filesorting is somehow better than querying $limit+1 rows
+ // from `revision_actor_temp`. Tell it not to reorder the query (and also reorder it ourselves
+ // because as generated by RevisionStore it'll have `revision` first rather than
+ // `revision_actor_temp`). But not when uctag is used, as it seems as likely to be harmed as
+ // helped in that case, and not when there's only one User because in that case it fetches
+ // the one `actor` row as a constant and doesn't filesort.
+ if ( count( $users ) > 1 && !isset( $this->params['tag'] ) ) {
+ $revQuery['joins']['revision'] = $revQuery['joins']['temp_rev_user'];
+ unset( $revQuery['joins']['temp_rev_user'] );
+ $this->addOption( 'STRAIGHT_JOIN' );
+ // It isn't actually necesssary to reorder $revQuery['tables'] as Database does the right thing
+ // when join conditions are given for all joins, but Gergő is wary of relying on that so pull
+ // `revision_actor_temp` to the start.
+ $revQuery['tables'] =
+ [ 'temp_rev_user' => $revQuery['tables']['temp_rev_user'] ] + $revQuery['tables'];
}
$this->addTables( $revQuery['tables'] );
$user = $this->getUser();
if ( !$this->getPermissionManager()->userHasRight( $user, 'deletedhistory' ) ) {
$bitmask = RevisionRecord::DELETED_USER;
- } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+ } elseif ( !$this->getPermissionManager()
+ ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' )
+ ) {
$bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
} else {
$bitmask = 0;