17require_once __DIR__ .
'/../Maintenance.php';
18require_once __DIR__ .
'/../../includes/Export/WikiExporter.php';
41use Wikimedia\Timestamp\ConvertibleTimestamp;
42use Wikimedia\Timestamp\TimestampFormat as TS;
141 parent::__construct();
142 $this->stderr = fopen(
"php://stderr",
"wt" );
157 $this->
addOption(
'plugin',
'Load a dump plugin class. Specify as <class>[:<file>].',
158 false,
true,
false,
true );
159 $this->
addOption(
'output',
'Begin a filtered output stream; Specify as <type>:<file>. ' .
160 '<type>s: file, gzip, bzip2, 7zip, dbzip2, lbzip2',
false,
true,
'o',
true );
161 $this->
addOption(
'filter',
'Add a filter on an output branch. Specify as ' .
162 '<type>[:<options>]. <types>s: latest, notalk, namespace',
false,
true,
false,
true );
163 $this->
addOption(
'report',
'Report position and speed after every n pages processed. ' .
164 'Default: 100.',
false,
true );
165 $this->
addOption(
'7ziplevel',
'7zip compression level for all 7zip outputs. Used for ' .
166 '-mx option to 7za command.',
false,
true );
170 $this->
addOption(
'schema-version',
'Schema version to use for output.',
false,
true );
181 parent::finalSetup( $settingsBuilder );
185 $this->
addOption(
'schema-version',
'Schema version to use for output. ' .
194 $this->outputTypes[$name] = $class;
202 $this->filterTypes[$name] = $class;
216 $register = [ $class,
'register' ];
227 $this->schemaVersion = WikiExporter::schemaVersion();
230 foreach ( $options as [ $opt, $param ] ) {
233 $val = explode(
':', $param, 2 );
235 if ( count( $val ) === 1 ) {
237 } elseif ( count( $val ) === 2 ) {
243 $split = explode(
':', $param, 2 );
244 if ( count( $split ) !== 2 ) {
245 $this->
fatalError(
'Invalid output parameter' );
247 [ $type, $file ] = $split;
248 if (
$sink !==
null ) {
251 if ( !isset( $this->outputTypes[$type] ) ) {
252 $this->
fatalError(
"Unrecognized output sink type '$type'" );
254 $class = $this->outputTypes[$type];
255 if ( $type ===
"7zip" ) {
256 $sink =
new $class( $file, intval( $this->
getOption(
'7ziplevel' ) ) );
258 $sink =
new $class( $file );
265 $split = explode(
':', $param, 2 );
268 if ( !isset( $this->filterTypes[$key] ) ) {
269 $this->
fatalError(
"Unrecognized filter type '$key'" );
272 $type = $this->filterTypes[$key];
274 if ( count( $split ) === 2 ) {
275 $filter =
new $type(
$sink, $split[1] );
277 $filter =
new $type(
$sink );
285 case 'schema-version':
286 if ( !in_array( $param, XmlDumpWriter::$supportedSchemas ) ) {
288 "Unsupported schema version $param. Supported versions: " .
289 implode(
', ', XmlDumpWriter::$supportedSchemas )
292 $this->schemaVersion = $param;
298 $this->reportingInterval = intval( $this->
getOption(
'report' ) );
304 if ( count( $sinks ) > 1 ) {
315 public function dump( $history, $text = WikiExporter::TEXT ) {
316 # Notice messages will foul up your XML output even if they're
317 # relatively harmless.
318 if ( ini_get(
'display_errors' ) ) {
319 ini_set(
'display_errors',
'stderr' );
325 $exporter = $services->getWikiExporterFactory()->getWikiExporter(
329 $this->limitNamespaces
331 $exporter->setSchemaVersion( $this->schemaVersion );
336 $exporter->setOutputSink( $wrapper );
338 if ( !$this->skipHeader ) {
339 $exporter->openStream();
341 # Log item dumps: all or by range
342 if ( $history & WikiExporter::LOGS ) {
343 if ( $this->startId || $this->endId ) {
344 $exporter->logsByRange( $this->startId, $this->endId );
346 $exporter->allLogs();
348 } elseif ( $this->pages ===
null ) {
349 # Page dumps: all or by page ID range
350 if ( $this->startId || $this->endId ) {
351 $exporter->pagesByRange( $this->startId, $this->endId, $this->orderRevs );
352 } elseif ( $this->revStartId || $this->revEndId ) {
353 $exporter->revsByRange( $this->revStartId, $this->revEndId );
355 $exporter->allPages();
358 # Dump of specific pages
359 $exporter->pagesByName( $this->pages );
362 if ( !$this->skipFooter ) {
363 $exporter->closeStream();
376 $table = ( $history == WikiExporter::CURRENT ) ?
'page' :
'revision';
377 $field = ( $history == WikiExporter::CURRENT ) ?
'page_id' :
'rev_id';
380 if ( $this->forcedDb ===
null ) {
383 $this->maxCount = $dbr->newSelectQueryBuilder()
384 ->select(
"MAX($field)" )
386 ->caller( __METHOD__ )->fetchField();
387 $this->startTime = microtime(
true );
389 $this->ID = getmypid();
396 if ( $this->forcedDb !==
null ) {
401 ->getDBLoadBalancerFactory()
419 parent::setDB( $db );
420 $this->forcedDb = $db;
432 public function report(
bool $final =
false ) {
433 if ( $final xor ( $this->
revCount % $this->reportingInterval == 0 ) ) {
439 if ( $this->reporting ) {
440 $now = ConvertibleTimestamp::now( TS::DB );
441 $nowts = microtime(
true );
449 $eta = $this->startTime + $deltaAll / $portion;
451 $pageRate = $this->pageCount / $deltaAll;
452 $revRate = $this->
revCount / $deltaAll;
459 $pageRatePart = $this->pageCountPart / $deltaPart;
460 $revRatePart = $this->revCountPart / $deltaPart;
466 $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
468 "%s: %s (ID %d) %d pages (%0.1f|%0.1f/sec all|curr), "
469 .
"%d revs (%0.1f|%0.1f/sec all|curr), ETA %s [max %d]",
470 $now, $dbDomain, $this->ID, $this->pageCount, $pageRate,
471 $pageRatePart, $this->
revCount, $revRate, $revRatePart, $etats,
474 $this->lastTime = $nowts;
480 if ( $this->reporting ) {
481 fwrite( $this->stderr, $string .
"\n" );
487class_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)
array< string, class-string< DumpOutput > > $outputTypes
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
array< string, class-string< DumpFilter > > $filterTypes
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.