Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
UpdateForMultipleDevicesSupport
0.00% covered (danger)
0.00%
0 / 58
0.00% covered (danger)
0.00%
0 / 3
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 doDBUpdates
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 1
42
 getUpdateKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * @license GPL-2.0-or-later
4 *
5 * @file
6 */
7
8namespace MediaWiki\Extension\OATHAuth\Maintenance;
9
10use MediaWiki\Extension\OATHAuth\OATHAuthServices;
11use MediaWiki\Json\FormatJson;
12use MediaWiki\Maintenance\LoggedUpdateMaintenance;
13
14// @codeCoverageIgnoreStart
15if ( getenv( 'MW_INSTALL_PATH' ) ) {
16    $IP = getenv( 'MW_INSTALL_PATH' );
17} else {
18    $IP = __DIR__ . '/../../..';
19}
20require_once "$IP/maintenance/Maintenance.php";
21// @codeCoverageIgnoreEnd
22
23/**
24 * @author Taavi Väänänen <hi@taavi.wtf>
25 */
26class UpdateForMultipleDevicesSupport extends LoggedUpdateMaintenance {
27    public function __construct() {
28        parent::__construct();
29        $this->requireExtension( 'OATHAuth' );
30        $this->setBatchSize( 500 );
31    }
32
33    /** @inheritDoc */
34    protected function doDBUpdates() {
35        $services = $this->getServiceContainer();
36        $dbw = $services
37            ->getDBLoadBalancerFactory()
38            ->getPrimaryDatabase( 'virtual-oathauth' );
39
40        $maxId = $dbw->newSelectQueryBuilder()
41            ->select( 'MAX(id)' )
42            ->from( 'oathauth_users' )
43            ->caller( __METHOD__ )
44            ->fetchField();
45
46        $typeIds = OATHAuthServices::getInstance( $services )
47            ->getModuleRegistry()->getModuleIds();
48
49        $updated = 0;
50
51        for ( $min = 0; $min <= $maxId; $min += $this->getBatchSize() ) {
52            $max = $min + $this->getBatchSize();
53            $this->output( "Now processing rows with id between $min and $max... (updated $updated users so far)\n" );
54
55            $res = $dbw->newSelectQueryBuilder()
56                ->select( [
57                    'id',
58                    'module',
59                    'data',
60                ] )
61                ->from( 'oathauth_users' )
62                ->leftJoin(
63                    'oathauth_devices',
64                    null,
65                    'oad_user = id'
66                )
67                ->where( [
68                    $dbw->buildComparison( '>=', [ 'id' => $min ] ),
69                    $dbw->buildComparison( '<', [ 'id' => $max ] ),
70
71                    // Only select rows that haven't been migrated yet, so no matching
72                    // oathauth_devices row.
73                    'oad_id' => null,
74                ] )
75                ->caller( __METHOD__ )
76                ->fetchResultSet();
77
78            $toAdd = [];
79
80            foreach ( $res as $row ) {
81                $decodedData = FormatJson::decode( $row->data, true );
82
83                if ( isset( $decodedData['keys'] ) ) {
84                    $updated++;
85
86                    foreach ( $decodedData['keys'] as $keyData ) {
87                        $toAdd[] = [
88                            'oad_user' => (int)$row->id,
89                            'oad_type' => $typeIds[$row->module],
90                            'oad_data' => FormatJson::encode( $keyData ),
91                        ];
92                    }
93                }
94            }
95
96            if ( $toAdd ) {
97                $dbw->newInsertQueryBuilder()
98                    ->insertInto( 'oathauth_devices' )
99                    ->rows( $toAdd )
100                    ->caller( __METHOD__ )
101                    ->execute();
102            }
103
104            $this->waitForReplication();
105        }
106
107        $this->output( "Done, updated data for $updated users.\n" );
108        return true;
109    }
110
111    /**
112     * @return string
113     */
114    protected function getUpdateKey() {
115        return __CLASS__;
116    }
117}
118
119// @codeCoverageIgnoreStart
120$maintClass = UpdateForMultipleDevicesSupport::class;
121require_once RUN_MAINTENANCE_IF_MAIN;
122// @codeCoverageIgnoreEnd