31require_once __DIR__ .
'/../Maintenance.php';
32require_once __DIR__ .
'/../../includes/export/WikiExporter.php';
143 parent::__construct();
144 $this->stderr = fopen(
"php://stderr",
"wt" );
156 $this->
registerFilter(
'namespace', \DumpNamespaceFilter::class );
159 $this->
addOption(
'plugin',
'Load a dump plugin class. Specify as <class>[:<file>].',
160 false,
true,
false,
true );
161 $this->
addOption(
'output',
'Begin a filtered output stream; Specify as <type>:<file>. ' .
162 '<type>s: file, gzip, bzip2, 7zip, dbzip2, lbzip2',
false,
true,
'o',
true );
163 $this->
addOption(
'filter',
'Add a filter on an output branch. Specify as ' .
164 '<type>[:<options>]. <types>s: latest, notalk, namespace',
false,
true,
false,
true );
165 $this->
addOption(
'report',
'Report position and speed after every n pages processed. ' .
166 'Default: 100.',
false,
true );
167 $this->
addOption(
'7ziplevel',
'7zip compression level for all 7zip outputs. Used for ' .
168 '-mx option to 7za command.',
false,
true );
172 $this->
addOption(
'schema-version',
'Schema version to use for output.',
false,
true );
183 parent::finalSetup( $settingsBuilder );
187 $this->
addOption(
'schema-version',
'Schema version to use for output. ' .
196 $this->outputTypes[$name] = $class;
204 $this->filterTypes[$name] = $class;
218 $register = [ $class,
'register' ];
229 $this->schemaVersion = WikiExporter::schemaVersion();
232 foreach ( $options as [ $opt, $param ] ) {
235 $val = explode(
':', $param, 2 );
237 if ( count( $val ) === 1 ) {
239 } elseif ( count( $val ) === 2 ) {
245 $split = explode(
':', $param, 2 );
246 if ( count( $split ) !== 2 ) {
247 $this->
fatalError(
'Invalid output parameter' );
249 [ $type, $file ] = $split;
250 if (
$sink !==
null ) {
253 if ( !isset( $this->outputTypes[$type] ) ) {
254 $this->
fatalError(
"Unrecognized output sink type '$type'" );
256 $class = $this->outputTypes[$type];
257 if ( $type ===
"7zip" ) {
258 $sink =
new $class( $file, intval( $this->
getOption(
'7ziplevel' ) ) );
260 $sink =
new $class( $file );
267 $split = explode(
':', $param, 2 );
270 if ( !isset( $this->filterTypes[$key] ) ) {
271 $this->
fatalError(
"Unrecognized filter type '$key'" );
274 $type = $this->filterTypes[$key];
276 if ( count( $split ) === 2 ) {
277 $filter =
new $type(
$sink, $split[1] );
279 $filter =
new $type(
$sink );
287 case 'schema-version':
288 if ( !in_array( $param, XmlDumpWriter::$supportedSchemas ) ) {
290 "Unsupported schema version $param. Supported versions: " .
291 implode(
', ', XmlDumpWriter::$supportedSchemas )
294 $this->schemaVersion = $param;
300 $this->reportingInterval = intval( $this->
getOption(
'report' ) );
306 if ( count( $sinks ) > 1 ) {
313 public function dump( $history, $text = WikiExporter::TEXT ) {
314 # Notice messages will foul up your XML output even if they're
315 # relatively harmless.
316 if ( ini_get(
'display_errors' ) ) {
317 ini_set(
'display_errors',
'stderr' );
323 $exporter = $services->getWikiExporterFactory()->getWikiExporter(
327 $this->limitNamespaces
329 $exporter->setSchemaVersion( $this->schemaVersion );
334 $exporter->setOutputSink( $wrapper );
336 if ( !$this->skipHeader ) {
337 $exporter->openStream();
339 # Log item dumps: all or by range
340 if ( $history & WikiExporter::LOGS ) {
341 if ( $this->startId || $this->endId ) {
342 $exporter->logsByRange( $this->startId, $this->endId );
344 $exporter->allLogs();
346 } elseif ( $this->pages ===
null ) {
347 # Page dumps: all or by page ID range
348 if ( $this->startId || $this->endId ) {
349 $exporter->pagesByRange( $this->startId, $this->endId, $this->orderRevs );
350 } elseif ( $this->revStartId || $this->revEndId ) {
351 $exporter->revsByRange( $this->revStartId, $this->revEndId );
353 $exporter->allPages();
356 # Dump of specific pages
357 $exporter->pagesByName( $this->pages );
360 if ( !$this->skipFooter ) {
361 $exporter->closeStream();
374 $table = ( $history == WikiExporter::CURRENT ) ?
'page' :
'revision';
375 $field = ( $history == WikiExporter::CURRENT ) ?
'page_id' :
'rev_id';
378 if ( $this->forcedDb ===
null ) {
381 $this->maxCount = $dbr->newSelectQueryBuilder()
382 ->select(
"MAX($field)" )
384 ->caller( __METHOD__ )->fetchField();
385 $this->startTime = microtime(
true );
387 $this->ID = getmypid();
394 if ( $this->forcedDb !==
null ) {
399 ->getDBLoadBalancerFactory()
417 parent::setDB( $db );
418 $this->forcedDb = $db;
430 public function report( $final =
false ) {
431 if ( $final xor ( $this->
revCount % $this->reportingInterval == 0 ) ) {
437 if ( $this->reporting ) {
439 $nowts = microtime(
true );
447 $eta = $this->startTime + $deltaAll / $portion;
449 $pageRate = $this->pageCount / $deltaAll;
450 $revRate = $this->
revCount / $deltaAll;
457 $pageRatePart = $this->pageCountPart / $deltaPart;
458 $revRatePart = $this->revCountPart / $deltaPart;
464 $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
466 "%s: %s (ID %d) %d pages (%0.1f|%0.1f/sec all|curr), "
467 .
"%d revs (%0.1f|%0.1f/sec all|curr), ETA %s [max %d]",
468 $now, $dbDomain, $this->ID, $this->pageCount, $pageRate,
469 $pageRatePart, $this->
revCount, $revRate, $revRatePart, $etats,
472 $this->lastTime = $nowts;
478 if ( $this->reporting ) {
479 fwrite( $this->stderr, $string .
"\n" );
485class_alias( BackupDumper::class,
'BackupDumper' );
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
A class containing constants representing the names of configuration variables.
const XmlDumpSchemaVersion
Name constant for the XmlDumpSchemaVersion setting, for use with Config::get()
bool $skipHeader
don't output <mediawiki> and <siteinfo>
IMaintainableDatabase null $forcedDb
The dependency-injected database to use.
finalSetup(SettingsBuilder $settingsBuilder)
Handle some last-minute setup here.
bool $dumpUploadFileContents
dump( $history, $text=WikiExporter::TEXT)
string null $schemaVersion
null means use default
string[] null $pages
null means all pages
processOptions()
Processes arguments and sets $this->$sink accordingly.
string null $thisRevFormat
array null $limitNamespaces
bool $skipFooter
don't output </mediawiki>
setDB(IMaintainableDatabase $db)
Force the dump to use the provided database connection for database operations, wherever possible.
string null $thisRevModel
registerFilter( $name, $class)
ExportProgressFilter $egress
registerOutput( $name, $class)
DumpMultiWriter DumpOutput null $sink
Output filters.
initProgress( $history=WikiExporter::FULL)
Initialise starting time and maximum revision count.
loadPlugin( $class, $file)
Load a plugin and register it.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
array $orderedOptions
Used to read the options in the order they were passed.
loadWithArgv( $argv)
Load params and arguments from a given array of command-line arguments.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getDB( $db, $groups=[], $dbDomain=false)
Returns a database to be used by current maintenance script.
hasOption( $name)
Checks to see if a particular option was set.
getOption( $name, $default=null)
Get an option, or return the default.
getServiceContainer()
Returns the main service container.
Advanced database interface for IDatabase handles that include maintenance methods.