MediaWiki REL1_35
populateLogSearch.php
Go to the documentation of this file.
1<?php
25require_once __DIR__ . '/Maintenance.php';
26
28
36 private static $tableMap = [
37 'rev' => 'revision',
38 'fa' => 'filearchive',
39 'oi' => 'oldimage',
40 'ar' => 'archive'
41 ];
42
43 public function __construct() {
44 parent::__construct();
45 $this->addDescription( 'Migrate log params to new table and index for searching' );
46 $this->setBatchSize( 100 );
47 }
48
49 protected function getUpdateKey() {
50 return 'populate log_search';
51 }
52
53 protected function updateSkippedMessage() {
54 return 'log_search table already populated.';
55 }
56
57 protected function doDBUpdates() {
58 $batchSize = $this->getBatchSize();
59 $db = $this->getDB( DB_MASTER );
60 if ( !$db->tableExists( 'log_search', __METHOD__ ) ) {
61 $this->error( "log_search does not exist" );
62
63 return false;
64 }
65 $start = $db->selectField( 'logging', 'MIN(log_id)', '', __FUNCTION__ );
66 if ( !$start ) {
67 $this->output( "Nothing to do.\n" );
68
69 return true;
70 }
71 $end = $db->selectField( 'logging', 'MAX(log_id)', '', __FUNCTION__ );
72
73 // This maintenance script is for updating pre-1.16 to 1.16. The target_author_id and
74 // target_author_ip relations it adds will later be migrated to target_author_actor by
75 // migrateActors.php. If the schema is already 1.34, we should have nothing to do.
76 if ( !$db->fieldExists( 'logging', 'log_user', __METHOD__ ) ) {
77 $this->output(
78 "This does not appear to be an upgrade from MediaWiki pre-1.16 "
79 . "(logging.log_user does not exist).\n"
80 );
81 $this->output( "Nothing to do.\n" );
82
83 return true;
84 }
85
86 # Do remaining chunk
87 $end += $batchSize - 1;
88 $blockStart = $start;
89 $blockEnd = $start + $batchSize - 1;
90 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
91
92 $delTypes = [ 'delete', 'suppress' ]; // revisiondelete types
93 while ( $blockEnd <= $end ) {
94 $this->output( "...doing log_id from $blockStart to $blockEnd\n" );
95 $cond = "log_id BETWEEN " . (int)$blockStart . " AND " . (int)$blockEnd;
96 $res = $db->select(
97 'logging', [ 'log_id', 'log_type', 'log_action', 'log_params' ], $cond, __FUNCTION__
98 );
99 foreach ( $res as $row ) {
100 // RevisionDelete logs - revisions
101 if ( LogEventsList::typeAction( $row, $delTypes, 'revision' ) ) {
102 $params = LogPage::extractParams( $row->log_params );
103 // Param format: <urlparam> <item CSV> [<ofield> <nfield>]
104 if ( count( $params ) < 2 ) {
105 continue; // bad row?
106 }
107 $field = RevisionDeleter::getRelationType( $params[0] );
108 // B/C, the params may start with a title key (<title> <urlparam> <CSV>)
109 if ( $field == null ) {
110 array_shift( $params ); // remove title param
111 $field = RevisionDeleter::getRelationType( $params[0] );
112 if ( $field == null ) {
113 $this->output( "Invalid param type for {$row->log_id}\n" );
114 continue; // skip this row
115 } else {
116 // Clean up the row...
117 $db->update( 'logging',
118 [ 'log_params' => implode( ',', $params ) ],
119 [ 'log_id' => $row->log_id ],
120 __METHOD__
121 );
122 }
123 }
124 $items = explode( ',', $params[1] );
125 $log = new LogPage( $row->log_type );
126 // Add item relations...
127 $log->addRelations( $field, $items, $row->log_id );
128 // Determine what table to query...
129 $prefix = substr( $field, 0, strpos( $field, '_' ) ); // db prefix
130 if ( !isset( self::$tableMap[$prefix] ) ) {
131 continue; // bad row?
132 }
133 $table = self::$tableMap[$prefix];
134 $userField = $prefix . '_user';
135 $userTextField = $prefix . '_user_text';
136 // Add item author relations...
137 $userIds = $userIPs = [];
138 $sres = $db->select( $table,
139 [ $userField, $userTextField ],
140 [ $field => $items ],
141 __METHOD__
142 );
143 foreach ( $sres as $srow ) {
144 if ( $srow->$userField > 0 ) {
145 $userIds[] = intval( $srow->$userField );
146 } elseif ( $srow->$userTextField != '' ) {
147 $userIPs[] = $srow->$userTextField;
148 }
149 }
150 // Add item author relations...
151 $log->addRelations( 'target_author_id', $userIds, $row->log_id );
152 $log->addRelations( 'target_author_ip', $userIPs, $row->log_id );
153 } elseif ( LogEventsList::typeAction( $row, $delTypes, 'event' ) ) {
154 // RevisionDelete logs - log events
155 $params = LogPage::extractParams( $row->log_params );
156 // Param format: <item CSV> [<ofield> <nfield>]
157 if ( count( $params ) < 1 ) {
158 continue; // bad row
159 }
160 $items = explode( ',', $params[0] );
161 $log = new LogPage( $row->log_type );
162 // Add item relations...
163 $log->addRelations( 'log_id', $items, $row->log_id );
164 // Add item author relations...
165 $userIds = $userIPs = [];
166 $sres = $db->select( 'logging',
167 [ 'log_user', 'log_user_text' ],
168 [ 'log_id' => $items ],
169 __METHOD__
170 );
171 foreach ( $sres as $srow ) {
172 if ( $srow->log_user > 0 ) {
173 $userIds[] = intval( $srow->log_user );
174 } elseif ( Wikimedia\IPUtils::isIPAddress( $srow->log_user_text ) ) {
175 $userIPs[] = $srow->log_user_text;
176 }
177 }
178 $log->addRelations( 'target_author_id', $userIds, $row->log_id );
179 $log->addRelations( 'target_author_ip', $userIPs, $row->log_id );
180 }
181 }
182 $blockStart += $batchSize;
183 $blockEnd += $batchSize;
184 $lbFactory->waitForReplication();
185 }
186 $this->output( "Done populating log_search table.\n" );
187
188 return true;
189 }
190}
191
192$maintClass = PopulateLogSearch::class;
193require_once RUN_MAINTENANCE_IF_MAIN;
getDB()
const RUN_MAINTENANCE_IF_MAIN
Class to simplify the use of log pages.
Definition LogPage.php:37
static extractParams( $blob)
Extract a parameter array from a blob.
Definition LogPage.php:426
Class for scripts that perform database maintenance and want to log the update in updatelog so we can...
error( $err, $die=0)
Throw an error to the user.
output( $out, $channel=null)
Throw some output to the user.
getBatchSize()
Returns batch size.
addDescription( $text)
Set the description text.
setBatchSize( $s=0)
Set the batch size.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Maintenance script that makes the required database updates for populating the log_search table retro...
doDBUpdates()
Do the actual work.
updateSkippedMessage()
Message to show that the update was done already and was just skipped.
getUpdateKey()
Get the update key name to go in the update log table.
__construct()
Default constructor.
static getRelationType( $typeName)
Get DB field name for URL param... Future code for other things may also track other types of revisio...
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...
const DB_MASTER
Definition defines.php:29