Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
PopulateCulActor
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 3
56
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 getUpdateKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doDBUpdates
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\CheckUser\Maintenance;
22
23use LoggedUpdateMaintenance;
24use MediaWiki\MediaWikiServices;
25
26$IP = getenv( 'MW_INSTALL_PATH' );
27if ( $IP === false ) {
28    $IP = __DIR__ . '/../../..';
29}
30require_once "$IP/maintenance/Maintenance.php";
31
32/**
33 * Maintenance script for filling up cul_actor.
34 *
35 * @author Zabe
36 */
37class PopulateCulActor extends LoggedUpdateMaintenance {
38
39    public function __construct() {
40        parent::__construct();
41        $this->requireExtension( 'CheckUser' );
42        $this->addDescription( 'Populate the cul_actor column.' );
43        $this->addOption(
44            'sleep',
45            'Sleep time (in seconds) between every batch. Default: 0',
46            false,
47            true
48        );
49    }
50
51    /**
52     * @inheritDoc
53     */
54    protected function getUpdateKey() {
55        return 'PopulateCulActor-2';
56    }
57
58    /**
59     * @inheritDoc
60     */
61    protected function doDBUpdates() {
62        $services = MediaWikiServices::getInstance();
63        $actorStore = $services->getActorStore();
64        $dbr = $services->getDBLoadBalancerFactory()->getReplicaDatabase( false, 'vslow' );
65        $dbw = $services->getDBLoadBalancerFactory()->getPrimaryDatabase();
66        $batchSize = $this->getBatchSize();
67
68        $prevId = 0;
69        $curId = $prevId + $batchSize;
70        $maxId = (int)$dbr->newSelectQueryBuilder()
71            ->field( 'MAX(cul_id)' )
72            ->table( 'cu_log' )
73            ->caller( __METHOD__ )
74            ->fetchField();
75
76        if ( !$maxId ) {
77            $this->output( "The cu_log table seems to be empty.\n" );
78            return true;
79        }
80
81        $diff = $maxId - $prevId;
82        $failed = 0;
83        $sleep = (int)$this->getOption( 'sleep', 0 );
84
85        do {
86            $res = $dbr->newSelectQueryBuilder()
87                ->fields( [ 'cul_id', 'cul_user' ] )
88                ->table( 'cu_log' )
89                ->conds( [
90                    'cul_actor' => 0,
91                    $dbr->expr( 'cul_id', '>=', $prevId ),
92                    $dbr->expr( 'cul_id', '<=', $curId ),
93                ] )
94                ->caller( __METHOD__ )
95                ->fetchResultSet();
96
97            foreach ( $res as $row ) {
98                $name = $actorStore->getUserIdentityByUserId( $row->cul_user )->getName();
99                $actor = $actorStore->findActorIdByName( $name, $dbr );
100
101                if ( !$actor ) {
102                    $failed++;
103                    continue;
104                }
105
106                $dbw->newUpdateQueryBuilder()
107                    ->update( 'cu_log' )
108                    ->set( [ 'cul_actor' => $actor ] )
109                    ->where( [ 'cul_id' => $row->cul_id ] )
110                    ->caller( __METHOD__ )
111                    ->execute();
112            }
113
114            $this->waitForReplication();
115
116            if ( $sleep > 0 ) {
117                sleep( $sleep );
118            }
119
120            $this->output( "Processed $batchSize rows out of $diff.\n" );
121
122            $prevId = $curId;
123            $curId += $batchSize;
124        } while ( $prevId <= $maxId );
125
126        $this->output( "Done. Migration failed for $failed row(s).\n" );
127        return true;
128    }
129}
130
131$maintClass = PopulateCulActor::class;
132require_once RUN_MAINTENANCE_IF_MAIN;