MediaWiki REL1_34
populateLogSearch.php
Go to the documentation of this file.
1<?php
25require_once __DIR__ . '/Maintenance.php';
26
34 private static $tableMap = [
35 'rev' => 'revision',
36 'fa' => 'filearchive',
37 'oi' => 'oldimage',
38 'ar' => 'archive'
39 ];
40
41 public function __construct() {
42 parent::__construct();
43 $this->addDescription( 'Migrate log params to new table and index for searching' );
44 $this->setBatchSize( 100 );
45 }
46
47 protected function getUpdateKey() {
48 return 'populate log_search';
49 }
50
51 protected function updateSkippedMessage() {
52 return 'log_search table already populated.';
53 }
54
55 protected function doDBUpdates() {
56 $batchSize = $this->getBatchSize();
57 $db = $this->getDB( DB_MASTER );
58 if ( !$db->tableExists( 'log_search' ) ) {
59 $this->error( "log_search does not exist" );
60
61 return false;
62 }
63 $start = $db->selectField( 'logging', 'MIN(log_id)', '', __FUNCTION__ );
64 if ( !$start ) {
65 $this->output( "Nothing to do.\n" );
66
67 return true;
68 }
69 $end = $db->selectField( 'logging', 'MAX(log_id)', '', __FUNCTION__ );
70
71 // This maintenance script is for updating pre-1.16 to 1.16. The target_author_id and
72 // target_author_ip relations it adds will later be migrated to target_author_actor by
73 // migrateActors.php. If the schema is already 1.34, we should have nothing to do.
74 if ( !$db->fieldExists( 'logging', 'log_user' ) ) {
75 $this->output(
76 "This does not appear to be an upgrade from MediaWiki pre-1.16 "
77 . "(logging.log_user does not exist).\n"
78 );
79 $this->output( "Nothing to do.\n" );
80
81 return true;
82 }
83
84 # Do remaining chunk
85 $end += $batchSize - 1;
86 $blockStart = $start;
87 $blockEnd = $start + $batchSize - 1;
88
89 $delTypes = [ 'delete', 'suppress' ]; // revisiondelete types
90 while ( $blockEnd <= $end ) {
91 $this->output( "...doing log_id from $blockStart to $blockEnd\n" );
92 $cond = "log_id BETWEEN " . (int)$blockStart . " AND " . (int)$blockEnd;
93 $res = $db->select(
94 'logging', [ 'log_id', 'log_type', 'log_action', 'log_params' ], $cond, __FUNCTION__
95 );
96 foreach ( $res as $row ) {
97 // RevisionDelete logs - revisions
98 if ( LogEventsList::typeAction( $row, $delTypes, 'revision' ) ) {
99 $params = LogPage::extractParams( $row->log_params );
100 // Param format: <urlparam> <item CSV> [<ofield> <nfield>]
101 if ( count( $params ) < 2 ) {
102 continue; // bad row?
103 }
104 $field = RevisionDeleter::getRelationType( $params[0] );
105 // B/C, the params may start with a title key (<title> <urlparam> <CSV>)
106 if ( $field == null ) {
107 array_shift( $params ); // remove title param
108 $field = RevisionDeleter::getRelationType( $params[0] );
109 if ( $field == null ) {
110 $this->output( "Invalid param type for {$row->log_id}\n" );
111 continue; // skip this row
112 } else {
113 // Clean up the row...
114 $db->update( 'logging',
115 [ 'log_params' => implode( ',', $params ) ],
116 [ 'log_id' => $row->log_id ] );
117 }
118 }
119 $items = explode( ',', $params[1] );
120 $log = new LogPage( $row->log_type );
121 // Add item relations...
122 $log->addRelations( $field, $items, $row->log_id );
123 // Determine what table to query...
124 $prefix = substr( $field, 0, strpos( $field, '_' ) ); // db prefix
125 if ( !isset( self::$tableMap[$prefix] ) ) {
126 continue; // bad row?
127 }
128 $table = self::$tableMap[$prefix];
129 $userField = $prefix . '_user';
130 $userTextField = $prefix . '_user_text';
131 // Add item author relations...
132 $userIds = $userIPs = [];
133 $sres = $db->select( $table,
134 [ $userField, $userTextField ],
135 [ $field => $items ]
136 );
137 foreach ( $sres as $srow ) {
138 if ( $srow->$userField > 0 ) {
139 $userIds[] = intval( $srow->$userField );
140 } elseif ( $srow->$userTextField != '' ) {
141 $userIPs[] = $srow->$userTextField;
142 }
143 }
144 // Add item author relations...
145 $log->addRelations( 'target_author_id', $userIds, $row->log_id );
146 $log->addRelations( 'target_author_ip', $userIPs, $row->log_id );
147 } elseif ( LogEventsList::typeAction( $row, $delTypes, 'event' ) ) {
148 // RevisionDelete logs - log events
149 $params = LogPage::extractParams( $row->log_params );
150 // Param format: <item CSV> [<ofield> <nfield>]
151 if ( count( $params ) < 1 ) {
152 continue; // bad row
153 }
154 $items = explode( ',', $params[0] );
155 $log = new LogPage( $row->log_type );
156 // Add item relations...
157 $log->addRelations( 'log_id', $items, $row->log_id );
158 // Add item author relations...
159 $userIds = $userIPs = [];
160 $sres = $db->select( 'logging',
161 [ 'log_user', 'log_user_text' ],
162 [ 'log_id' => $items ]
163 );
164 foreach ( $sres as $srow ) {
165 if ( $srow->log_user > 0 ) {
166 $userIds[] = intval( $srow->log_user );
167 } elseif ( IP::isIPAddress( $srow->log_user_text ) ) {
168 $userIPs[] = $srow->log_user_text;
169 }
170 }
171 $log->addRelations( 'target_author_id', $userIds, $row->log_id );
172 $log->addRelations( 'target_author_ip', $userIPs, $row->log_id );
173 }
174 }
175 $blockStart += $batchSize;
176 $blockEnd += $batchSize;
178 }
179 $this->output( "Done populating log_search table.\n" );
180
181 return true;
182 }
183}
184
185$maintClass = PopulateLogSearch::class;
186require_once RUN_MAINTENANCE_IF_MAIN;
getDB()
wfWaitForSlaves( $ifWritesSince=null, $wiki=false, $cluster=false, $timeout=null)
Waits for the replica DBs to catch up to the master position.
const RUN_MAINTENANCE_IF_MAIN
static typeAction( $row, $type, $action, $right='')
Class to simplify the use of log pages.
Definition LogPage.php:33
static extractParams( $blob)
Extract a parameter array from a blob.
Definition LogPage.php:427
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.
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...
const DB_MASTER
Definition defines.php:26