Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
48 / 48
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
DeleteOldRevisions
100.00% covered (success)
100.00%
48 / 48
100.00% covered (success)
100.00%
3 / 3
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 doDelete
100.00% covered (success)
100.00%
42 / 42
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2/**
3 * Delete old (non-current) revisions from the database
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 * @ingroup Maintenance
8 * @author Rob Church <robchur@gmail.com>
9 */
10
11use MediaWiki\Maintenance\Maintenance;
12
13// @codeCoverageIgnoreStart
14require_once __DIR__ . '/Maintenance.php';
15// @codeCoverageIgnoreEnd
16
17/**
18 * Maintenance script that deletes old (non-current) revisions from the database.
19 *
20 * @ingroup Maintenance
21 */
22class DeleteOldRevisions extends Maintenance {
23    public function __construct() {
24        parent::__construct();
25        $this->addDescription( 'Delete old (non-current) revisions from the database' );
26        $this->addOption( 'delete', 'Actually perform the deletion' );
27        $this->addArg( 'page_id', 'List of page ids to work on', false, true );
28    }
29
30    public function execute() {
31        $this->output( "Delete old revisions\n\n" );
32        $this->doDelete( $this->hasOption( 'delete' ), $this->getArgs( 'page_id' ) );
33    }
34
35    private function doDelete( bool $delete = false, array $pageIds = [] ) {
36        # Data should come off the master, wrapped in a transaction
37        $dbw = $this->getPrimaryDB();
38        $this->beginTransactionRound( __METHOD__ );
39
40        $pageConds = [];
41        $revConds = [];
42
43        # If a list of page_ids was provided, limit results to that set of page_ids
44        if ( count( $pageIds ) > 0 ) {
45            $pageConds['page_id'] = $pageIds;
46            $revConds['rev_page'] = $pageIds;
47            $this->output( "Limiting to page IDs " . implode( ',', $pageIds ) . "\n" );
48        }
49
50        # Get "active" revisions from the page table
51        $this->output( "Searching for active revisions..." );
52        $latestRevs = $dbw->newSelectQueryBuilder()
53            ->select( 'page_latest' )
54            ->from( 'page' )
55            ->where( $pageConds )
56            ->caller( __METHOD__ )
57            ->fetchFieldValues();
58        $this->output( "done.\n" );
59
60        # Get all revisions that aren't in this set
61        $this->output( "Searching for inactive revisions..." );
62        if ( count( $latestRevs ) > 0 ) {
63            $revConds[] = $dbw->expr( 'rev_id', '!=', $latestRevs );
64        }
65        $oldRevs = $dbw->newSelectQueryBuilder()
66            ->select( 'rev_id' )
67            ->from( 'revision' )
68            ->where( $revConds )
69            ->caller( __METHOD__ )
70            ->fetchFieldValues();
71        $this->output( "done.\n" );
72
73        # Inform the user of what we're going to do
74        $count = count( $oldRevs );
75        $this->output( "$count old revisions found.\n" );
76
77        # Delete as appropriate
78        if ( $delete && $count ) {
79            $this->output( "Deleting..." );
80            $dbw->newDeleteQueryBuilder()
81                ->deleteFrom( 'revision' )
82                ->where( [ 'rev_id' => $oldRevs ] )
83                ->caller( __METHOD__ )->execute();
84            $dbw->newDeleteQueryBuilder()
85                ->deleteFrom( 'ip_changes' )
86                ->where( [ 'ipc_rev_id' => $oldRevs ] )
87                ->caller( __METHOD__ )->execute();
88            $this->output( "done.\n" );
89        }
90
91        # Purge redundant text records
92        $this->commitTransactionRound( __METHOD__ );
93        if ( $delete ) {
94            $this->purgeRedundantText( true );
95        }
96    }
97}
98
99// @codeCoverageIgnoreStart
100$maintClass = DeleteOldRevisions::class;
101require_once RUN_MAINTENANCE_IF_MAIN;
102// @codeCoverageIgnoreEnd