MediaWiki master
RenameUserTableJob.php
Go to the documentation of this file.
1<?php
2
4
5use InvalidArgumentException;
11
36class RenameUserTableJob extends Job {
38 private $updateRowsPerQuery;
39
41 private $lbFactory;
42
43 public function __construct(
45 $params,
46 Config $config,
47 ILBFactory $lbFactory
48 ) {
49 parent::__construct( 'renameUserTable', $title, $params );
50
51 $this->updateRowsPerQuery = $config->get( MainConfigNames::UpdateRowsPerQuery );
52 $this->lbFactory = $lbFactory;
53 }
54
55 public function run() {
56 $dbw = $this->lbFactory->getPrimaryDatabase();
57 $ticket = $this->lbFactory->getEmptyTransactionTicket( __METHOD__ );
58 $table = $this->params['table'];
59 $column = $this->params['column'];
60
61 $oldname = $this->params['oldname'];
62 $newname = $this->params['newname'];
63 if ( isset( $this->params['userID'] ) ) {
64 $userID = $this->params['userID'];
65 $uidColumn = $this->params['uidColumn'];
66 } else {
67 $userID = null;
68 $uidColumn = null;
69 }
70 if ( isset( $this->params['timestampColumn'] ) ) {
71 $timestampColumn = $this->params['timestampColumn'];
72 $minTimestamp = $this->params['minTimestamp'];
73 $maxTimestamp = $this->params['maxTimestamp'];
74 } else {
75 $timestampColumn = null;
76 $minTimestamp = null;
77 $maxTimestamp = null;
78 }
79 $uniqueKey = $this->params['uniqueKey'] ?? null;
80 $keyId = $this->params['keyId'] ?? null;
81
82 # Conditions like "*_user_text = 'x'
83 $conds = [ $column => $oldname ];
84 # If user ID given, add that to condition to avoid rename collisions
85 if ( $userID !== null ) {
86 $conds[$uidColumn] = $userID;
87 }
88 # Bound by timestamp if given
89 if ( $timestampColumn !== null ) {
90 $conds[] = $dbw->expr( $timestampColumn, '>=', $minTimestamp );
91 $conds[] = $dbw->expr( $timestampColumn, '<=', $maxTimestamp );
92 # Bound by unique key if given (B/C)
93 } elseif ( $uniqueKey !== null && $keyId !== null ) {
94 $conds[$uniqueKey] = $keyId;
95 } else {
96 throw new InvalidArgumentException( 'Expected ID batch or time range' );
97 }
98
99 # Actually update the rows for this job...
100 if ( $uniqueKey !== null ) {
101 // Select the rows to update by PRIMARY KEY
102 $ids = $dbw->newSelectQueryBuilder()
103 ->select( $uniqueKey )
104 ->from( $table )
105 ->where( $conds )
106 ->caller( __METHOD__ )->fetchFieldValues();
107 # Update these rows by PRIMARY KEY to avoid replica lag
108 foreach ( array_chunk( $ids, $this->updateRowsPerQuery ) as $batch ) {
109 $this->lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
110
111 $dbw->newUpdateQueryBuilder()
112 ->update( $table )
113 ->set( [ $column => $newname ] )
114 ->where( [ $column => $oldname, $uniqueKey => $batch ] )
115 ->caller( __METHOD__ )->execute();
116 }
117 } else {
118 # Update the chunk of rows directly
119 $dbw->newUpdateQueryBuilder()
120 ->update( $table )
121 ->set( [ $column => $newname ] )
122 ->where( $conds )
123 ->caller( __METHOD__ )->execute();
124 }
125
126 return true;
127 }
128}
130class_alias( RenameUserTableJob::class, 'RenameUserJob' );
Describe and execute a background job.
Definition Job.php:41
array $params
Array of job parameters.
Definition Job.php:46
A class containing constants representing the names of configuration variables.
const UpdateRowsPerQuery
Name constant for the UpdateRowsPerQuery setting, for use with Config::get()
Custom job to perform updates on tables in busier environments.
__construct(Title $title, $params, Config $config, ILBFactory $lbFactory)
Represents a title within MediaWiki.
Definition Title.php:78
Interface for configuration instances.
Definition Config.php:32
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
Manager of ILoadBalancer objects and, indirectly, IDatabase connections.