Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.00% covered (success)
96.00%
24 / 25
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
LoggedUpdateMaintenance
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
4 / 4
7
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
4
 setForce
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updateSkippedMessage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 doDBUpdates
n/a
0 / 0
n/a
0 / 0
0
 getUpdateKey
n/a
0 / 0
n/a
0 / 0
0
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\Maintenance;
22
23/**
24 * Class for scripts that perform database maintenance and want to log the
25 * update in `updatelog` so we can later skip it
26 * @ingroup Maintenance
27 */
28abstract class LoggedUpdateMaintenance extends Maintenance {
29    public function __construct() {
30        parent::__construct();
31        $this->addOption( 'force', 'Run the update even if it was completed already' );
32        $this->setBatchSize( 200 );
33    }
34
35    public function execute() {
36        $db = $this->getPrimaryDB();
37        $key = $this->getUpdateKey();
38        $queryBuilder = $db->newSelectQueryBuilder()
39            ->select( '1' )
40            ->from( 'updatelog' )
41            ->where( [ 'ul_key' => $key ] );
42
43        if ( !$this->hasOption( 'force' )
44            && $queryBuilder->caller( __METHOD__ )->fetchRow()
45        ) {
46            $this->output( "..." . $this->updateSkippedMessage() . "\n" );
47
48            return true;
49        }
50
51        if ( !$this->doDBUpdates() ) {
52            return false;
53        }
54
55        $db->newInsertQueryBuilder()
56            ->insertInto( 'updatelog' )
57            ->ignore()
58            ->row( [ 'ul_key' => $key ] )
59            ->caller( __METHOD__ )->execute();
60
61        return true;
62    }
63
64    /**
65     * Sets whether a run of this maintenance script has the force parameter set
66     * @param bool $forced
67     */
68    public function setForce( $forced = true ) {
69        $this->setOption( 'force', $forced );
70    }
71
72    /**
73     * Message to show that the update was done already and was just skipped
74     * @return string
75     */
76    protected function updateSkippedMessage() {
77        $key = $this->getUpdateKey();
78
79        return "Update '{$key}' already logged as completed. Use --force to run it again.";
80    }
81
82    /**
83     * Do the actual work. All child classes will need to implement this.
84     * Return true to log the update as done or false (usually on failure).
85     * @return bool
86     */
87    abstract protected function doDBUpdates();
88
89    /**
90     * Get the update key name to go in the update log table
91     * @return string
92     */
93    abstract protected function getUpdateKey();
94}
95
96/** @deprecated class alias since 1.43 */
97class_alias( LoggedUpdateMaintenance::class, 'LoggedUpdateMaintenance' );