Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
FetchText
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
3 / 3
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getBlobStore
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2/**
3 * Communications protocol.
4 * This is used by dumpTextPass.php when the --spawn option is present.
5 *
6 * @license GPL-2.0-or-later
7 * @file
8 * @ingroup Maintenance
9 */
10
11// @codeCoverageIgnoreStart
12require_once __DIR__ . '/Maintenance.php';
13// @codeCoverageIgnoreEnd
14
15use MediaWiki\Maintenance\Maintenance;
16use MediaWiki\MediaWikiServices;
17use MediaWiki\Storage\BlobAccessException;
18use MediaWiki\Storage\BlobStore;
19use MediaWiki\Storage\SqlBlobStore;
20
21/**
22 * Maintenance script used to fetch page text in a subprocess.
23 *
24 * @ingroup Maintenance
25 */
26class FetchText extends Maintenance {
27
28    public function __construct() {
29        parent::__construct();
30        $this->addDescription( "Fetch the raw revision blob from a blob address.\n" .
31            "Integer IDs are interpreted as referring to text.old_id for backwards compatibility.\n" .
32            "NOTE: Export transformations are NOT applied. " .
33            "This is left to dumpTextPass.php"
34        );
35    }
36
37    /**
38     * @return BlobStore
39     */
40    private function getBlobStore() {
41        return $this->getServiceContainer()->getBlobStore();
42    }
43
44    /**
45     * returns a string containing the following in order:
46     *   textid
47     *   \n
48     *   length of text (-1 on error = failure to retrieve/unserialize/gunzip/etc)
49     *   \n
50     *   text  (may be empty)
51     *
52     * note that the text string itself is *not* followed by newline
53     */
54    public function execute() {
55        MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->setDefaultGroupName( 'dump' );
56        $stdin = $this->getStdin();
57        while ( !feof( $stdin ) ) {
58            $line = fgets( $stdin );
59            if ( $line === false ) {
60                // We appear to have lost contact...
61                break;
62            }
63            $blobAddress = trim( $line );
64
65            // Plain integers are supported for backwards compatibility with pre-MCR dumps.
66            if ( !str_contains( $blobAddress, ':' ) && is_numeric( $blobAddress ) ) {
67                $blobAddress = SqlBlobStore::makeAddressFromTextId( intval( $blobAddress ) );
68            }
69
70            try {
71                $text = $this->getBlobStore()->getBlob( $blobAddress );
72                $textLen = strlen( $text );
73            } catch ( BlobAccessException | InvalidArgumentException ) {
74                // XXX: log $ex to stderr?
75                $textLen = '-1';
76                $text = '';
77            }
78
79            $this->output( $blobAddress . "\n" . $textLen . "\n" . $text );
80        }
81    }
82
83}
84
85// @codeCoverageIgnoreStart
86$maintClass = FetchText::class;
87require_once RUN_MAINTENANCE_IF_MAIN;
88// @codeCoverageIgnoreEnd