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.
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.
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
19 use MediaWiki\Maintenance\Maintenance
;
21 // @codeCoverageIgnoreStart
22 require_once __DIR__
. '/Maintenance.php';
23 // @codeCoverageIgnoreEnd
26 * Remove autopatrol logs in the logging table.
28 * @ingroup Maintenance
30 class DeleteAutoPatrolLogs
extends Maintenance
{
32 public function __construct() {
33 parent
::__construct();
34 $this->addDescription( 'Remove autopatrol logs in the logging table' );
35 $this->addOption( 'dry-run', 'Print debug info instead of actually deleting' );
38 'Check old patrol logs (for deleting old format autopatrols).'
42 'Timestamp to delete only before that time, all MediaWiki timestamp formats are accepted',
48 'First row (log id) to start updating from',
54 'Sleep time (in seconds) between every batch',
58 $this->setBatchSize( 1000 );
61 public function execute() {
62 $this->setBatchSize( $this->getOption( 'batch-size', $this->getBatchSize() ) );
64 $sleep = (int)$this->getOption( 'sleep', 10 );
65 $fromId = $this->getOption( 'from-id', null );
66 $this->countDown( 5 );
68 if ( $this->hasOption( 'check-old' ) ) {
69 $rowsData = $this->getRowsOld( $fromId );
70 // We reached end of the table
74 $rows = $rowsData['rows'];
75 $fromId = $rowsData['lastId'];
77 // There is nothing to delete in this batch
82 $rows = $this->getRows( $fromId );
86 $fromId = end( $rows );
89 if ( $this->hasOption( 'dry-run' ) ) {
90 $this->output( 'These rows will get deleted: ' . implode( ', ', $rows ) . "\n" );
92 $this->deleteRows( $rows );
93 $this->output( 'Processed up to row id ' . end( $rows ) . "\n" );
102 private function getRows( $fromId ) {
103 $dbr = $this->getReplicaDB();
104 $before = $this->getOption( 'before', false );
107 'log_type' => 'patrol',
108 'log_action' => 'autopatrol',
112 $conds[] = $dbr->expr( 'log_id', '>', $fromId );
116 $conds[] = $dbr->expr( 'log_timestamp', '<', $dbr->timestamp( $before ) );
119 return $dbr->newSelectQueryBuilder()
123 ->orderBy( 'log_id' )
124 ->limit( $this->getBatchSize() )
125 ->caller( __METHOD__
)
126 ->fetchFieldValues();
129 private function getRowsOld( $fromId ) {
130 $dbr = $this->getReplicaDB();
131 $batchSize = $this->getBatchSize();
132 $before = $this->getOption( 'before', false );
135 'log_type' => 'patrol',
136 'log_action' => 'patrol',
140 $conds[] = $dbr->expr( 'log_id', '>', $fromId );
144 $conds[] = $dbr->expr( 'log_timestamp', '<', $dbr->timestamp( $before ) );
147 $result = $dbr->newSelectQueryBuilder()
148 ->select( [ 'log_id', 'log_params' ] )
151 ->orderBy( 'log_id' )
152 ->limit( $batchSize )
153 ->caller( __METHOD__
)
158 foreach ( $result as $row ) {
159 $last = $row->log_id
;
160 $logEntry = DatabaseLogEntry
::newFromRow( $row );
161 $params = $logEntry->getParameters();
162 if ( !is_array( $params ) ) {
166 // This logic belongs to PatrolLogFormatter::getMessageKey
167 // and LogFormatter::extractParameters the 'auto' value is logically presented as key [5].
168 // For legacy case the logical key is index + 3, meaning [2].
169 // For the modern case, the logical key is index - 1 meaning [6].
170 if ( array_key_exists( '6::auto', $params ) ) {
171 // Between 2011-2016 autopatrol logs
172 $auto = $params['6::auto'] === true;
173 } elseif ( $logEntry->isLegacy() === true && array_key_exists( 2, $params ) ) {
174 // Pre-2011 autopatrol logs
175 $auto = $params[2] === '1';
181 $autopatrols[] = $row->log_id
;
185 if ( $last === null ) {
189 return [ 'rows' => $autopatrols, 'lastId' => $last ];
192 private function deleteRows( array $rows ) {
193 $dbw = $this->getPrimaryDB();
195 $dbw->newDeleteQueryBuilder()
196 ->deleteFrom( 'logging' )
197 ->where( [ 'log_id' => $rows ] )
198 ->caller( __METHOD__
)->execute();
200 $this->waitForReplication();
205 // @codeCoverageIgnoreStart
206 $maintClass = DeleteAutoPatrolLogs
::class;
207 require_once RUN_MAINTENANCE_IF_MAIN
;
208 // @codeCoverageIgnoreEnd