Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 68
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
MigrateRevisionActorTemp
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 3
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 11
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 / 53
0.00% covered (danger)
0.00%
0 / 1
110
1<?php
2
3require_once __DIR__ . '/Maintenance.php';
4
5/**
6 * Maintenance script that merges the revision_actor_temp table into the
7 * revision table.
8 *
9 * @ingroup Maintenance
10 * @since 1.37
11 */
12class MigrateRevisionActorTemp extends LoggedUpdateMaintenance {
13    public function __construct() {
14        parent::__construct();
15        $this->addDescription(
16            'Copy the data from the revision_actor_temp into the revision table'
17        );
18        $this->addOption(
19            'sleep',
20            'Sleep time (in seconds) between every batch. Default: 0',
21            false,
22            true
23        );
24        $this->addOption( 'start', 'Start after this rev_id', false, true );
25    }
26
27    protected function getUpdateKey() {
28        return __CLASS__;
29    }
30
31    protected function doDBUpdates() {
32        $batchSize = $this->getBatchSize();
33
34        $dbw = $this->getDB( DB_PRIMARY );
35        if ( !$dbw->fieldExists( 'revision', 'rev_actor', __METHOD__ ) ) {
36            $this->output( "Run update.php to create rev_actor.\n" );
37            return false;
38        }
39        if ( !$dbw->tableExists( 'revision_actor_temp', __METHOD__ ) ) {
40            $this->output( "revision_actor_temp does not exist, so nothing to do.\n" );
41            return true;
42        }
43
44        $this->output( "Merging the revision_actor_temp table into the revision table...\n" );
45        $conds = [];
46        $updated = 0;
47        $start = (int)$this->getOption( 'start', 0 );
48        if ( $start > 0 ) {
49            $conds[] = $dbw->expr( 'rev_id', '>=', $start );
50        }
51        while ( true ) {
52            $res = $dbw->newSelectQueryBuilder()
53                ->select( [ 'rev_id', 'rev_actor', 'revactor_actor' ] )
54                ->from( 'revision' )
55                ->join( 'revision_actor_temp', null, 'rev_id=revactor_rev' )
56                ->where( $conds )
57                ->limit( $batchSize )
58                ->orderBy( 'rev_id' )
59                ->caller( __METHOD__ )
60                ->fetchResultSet();
61
62            $numRows = $res->numRows();
63
64            $last = null;
65            foreach ( $res as $row ) {
66                $last = $row->rev_id;
67                if ( !$row->rev_actor ) {
68                    $dbw->newUpdateQueryBuilder()
69                        ->update( 'revision' )
70                        ->set( [ 'rev_actor' => $row->revactor_actor ] )
71                        ->where( [ 'rev_id' => $row->rev_id ] )
72                        ->caller( __METHOD__ )->execute();
73                    $updated += $dbw->affectedRows();
74                } elseif ( $row->rev_actor !== $row->revactor_actor ) {
75                    $this->error(
76                        "Revision ID $row->rev_id has rev_actor = $row->rev_actor and "
77                        . "revactor_actor = $row->revactor_actor. Ignoring the latter."
78                    );
79                }
80            }
81
82            if ( $numRows < $batchSize ) {
83                // We must have reached the end
84                break;
85            }
86
87            // @phan-suppress-next-line PhanTypeSuspiciousStringExpression last is not-null when used
88            $this->output( "... rev_id=$last, updated $updated\n" );
89            $conds = [ $dbw->expr( 'rev_id', '>', $last ) ];
90
91            // Sleep between batches for replication to catch up
92            $this->waitForReplication();
93            $sleep = (int)$this->getOption( 'sleep', 0 );
94            if ( $sleep > 0 ) {
95                sleep( $sleep );
96            }
97        }
98
99        $this->output(
100            "Completed merge of revision_actor into the revision table, "
101            . "$updated rows updated.\n"
102        );
103
104        return true;
105    }
106
107}
108
109$maintClass = MigrateRevisionActorTemp::class;
110require_once RUN_MAINTENANCE_IF_MAIN;