17require_once __DIR__ .
'/../Maintenance.php';
18require_once __DIR__ .
'/../../includes/Export/WikiExporter.php';
31use Wikimedia\Timestamp\ConvertibleTimestamp;
32use Wikimedia\Timestamp\TimestampFormat as TS;
132 parent::__construct();
133 $this->stderr = fopen(
"php://stderr",
"wt" );
145 $this->
registerFilter(
'namespace', \DumpNamespaceFilter::class );
148 $this->
addOption(
'plugin',
'Load a dump plugin class. Specify as <class>[:<file>].',
149 false,
true,
false,
true );
150 $this->
addOption(
'output',
'Begin a filtered output stream; Specify as <type>:<file>. ' .
151 '<type>s: file, gzip, bzip2, 7zip, dbzip2, lbzip2',
false,
true,
'o',
true );
152 $this->
addOption(
'filter',
'Add a filter on an output branch. Specify as ' .
153 '<type>[:<options>]. <types>s: latest, notalk, namespace',
false,
true,
false,
true );
154 $this->
addOption(
'report',
'Report position and speed after every n pages processed. ' .
155 'Default: 100.',
false,
true );
156 $this->
addOption(
'7ziplevel',
'7zip compression level for all 7zip outputs. Used for ' .
157 '-mx option to 7za command.',
false,
true );
161 $this->
addOption(
'schema-version',
'Schema version to use for output.',
false,
true );
172 parent::finalSetup( $settingsBuilder );
176 $this->
addOption(
'schema-version',
'Schema version to use for output. ' .
185 $this->outputTypes[$name] = $class;
193 $this->filterTypes[$name] = $class;
207 $register = [ $class,
'register' ];
218 $this->schemaVersion = WikiExporter::schemaVersion();
221 foreach ( $options as [ $opt, $param ] ) {
224 $val = explode(
':', $param, 2 );
226 if ( count( $val ) === 1 ) {
228 } elseif ( count( $val ) === 2 ) {
234 $split = explode(
':', $param, 2 );
235 if ( count( $split ) !== 2 ) {
236 $this->
fatalError(
'Invalid output parameter' );
238 [ $type, $file ] = $split;
239 if (
$sink !==
null ) {
242 if ( !isset( $this->outputTypes[$type] ) ) {
243 $this->
fatalError(
"Unrecognized output sink type '$type'" );
245 $class = $this->outputTypes[$type];
246 if ( $type ===
"7zip" ) {
247 $sink =
new $class( $file, intval( $this->
getOption(
'7ziplevel' ) ) );
249 $sink =
new $class( $file );
256 $split = explode(
':', $param, 2 );
259 if ( !isset( $this->filterTypes[$key] ) ) {
260 $this->
fatalError(
"Unrecognized filter type '$key'" );
263 $type = $this->filterTypes[$key];
265 if ( count( $split ) === 2 ) {
266 $filter =
new $type(
$sink, $split[1] );
268 $filter =
new $type(
$sink );
276 case 'schema-version':
277 if ( !in_array( $param, XmlDumpWriter::$supportedSchemas ) ) {
279 "Unsupported schema version $param. Supported versions: " .
280 implode(
', ', XmlDumpWriter::$supportedSchemas )
283 $this->schemaVersion = $param;
289 $this->reportingInterval = intval( $this->
getOption(
'report' ) );
295 if ( count( $sinks ) > 1 ) {
306 public function dump( $history, $text = WikiExporter::TEXT ) {
307 # Notice messages will foul up your XML output even if they're
308 # relatively harmless.
309 if ( ini_get(
'display_errors' ) ) {
310 ini_set(
'display_errors',
'stderr' );
316 $exporter = $services->getWikiExporterFactory()->getWikiExporter(
320 $this->limitNamespaces
322 $exporter->setSchemaVersion( $this->schemaVersion );
327 $exporter->setOutputSink( $wrapper );
329 if ( !$this->skipHeader ) {
330 $exporter->openStream();
332 # Log item dumps: all or by range
333 if ( $history & WikiExporter::LOGS ) {
334 if ( $this->startId || $this->endId ) {
335 $exporter->logsByRange( $this->startId, $this->endId );
337 $exporter->allLogs();
339 } elseif ( $this->pages ===
null ) {
340 # Page dumps: all or by page ID range
341 if ( $this->startId || $this->endId ) {
342 $exporter->pagesByRange( $this->startId, $this->endId, $this->orderRevs );
343 } elseif ( $this->revStartId || $this->revEndId ) {
344 $exporter->revsByRange( $this->revStartId, $this->revEndId );
346 $exporter->allPages();
349 # Dump of specific pages
350 $exporter->pagesByName( $this->pages );
353 if ( !$this->skipFooter ) {
354 $exporter->closeStream();
367 $table = ( $history == WikiExporter::CURRENT ) ?
'page' :
'revision';
368 $field = ( $history == WikiExporter::CURRENT ) ?
'page_id' :
'rev_id';
371 if ( $this->forcedDb ===
null ) {
374 $this->maxCount = $dbr->newSelectQueryBuilder()
375 ->select(
"MAX($field)" )
377 ->caller( __METHOD__ )->fetchField();
378 $this->startTime = microtime(
true );
380 $this->ID = getmypid();
387 if ( $this->forcedDb !==
null ) {
392 ->getDBLoadBalancerFactory()
410 parent::setDB( $db );
411 $this->forcedDb = $db;
423 public function report(
bool $final =
false ) {
424 if ( $final xor ( $this->
revCount % $this->reportingInterval == 0 ) ) {
430 if ( $this->reporting ) {
431 $now = ConvertibleTimestamp::now( TS::DB );
432 $nowts = microtime(
true );
440 $eta = $this->startTime + $deltaAll / $portion;
442 $pageRate = $this->pageCount / $deltaAll;
443 $revRate = $this->
revCount / $deltaAll;
450 $pageRatePart = $this->pageCountPart / $deltaPart;
451 $revRatePart = $this->revCountPart / $deltaPart;
457 $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
459 "%s: %s (ID %d) %d pages (%0.1f|%0.1f/sec all|curr), "
460 .
"%d revs (%0.1f|%0.1f/sec all|curr), ETA %s [max %d]",
461 $now, $dbDomain, $this->ID, $this->pageCount, $pageRate,
462 $pageRatePart, $this->
revCount, $revRate, $revRatePart, $etats,
465 $this->lastTime = $nowts;
471 if ( $this->reporting ) {
472 fwrite( $this->stderr, $string .
"\n" );
478class_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.