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(
bool $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.
report(bool $final=false)
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.
Update the CREDITS list by merging in the list of git commit authors.