Make BackupDumper MCR compatible (main slot only)
[lhc/web/wiklou.git] / maintenance / dumpTextPass.php
index 512910c..0479a91 100644 (file)
@@ -29,6 +29,9 @@ require_once __DIR__ . '/7zip.inc';
 require_once __DIR__ . '/../includes/export/WikiExporter.php';
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Storage\BlobAccessException;
+use MediaWiki\Storage\BlobStore;
+use MediaWiki\Storage\SqlBlobStore;
 use Wikimedia\Rdbms\IMaintainableDatabase;
 
 /**
@@ -139,6 +142,13 @@ TEXT
                }
        }
 
+       /**
+        * @return BlobStore
+        */
+       private function getBlobStore() {
+               return MediaWikiServices::getInstance()->getBlobStore();
+       }
+
        function execute() {
                $this->processOptions();
                $this->dump( true );
@@ -520,17 +530,17 @@ TEXT
        }
 
        /**
-        * Tries to get the revision text for a revision id.
-        * Export transformations are applied if the content model can is given or can be
+        * Tries to load revision text.
+        * Export transformations are applied if the content model is given or can be
         * determined from the database.
         *
         * Upon errors, retries (Up to $this->maxFailures tries each call).
-        * If still no good revision get could be found even after this retrying, "" is returned.
+        * If still no good revision could be found even after this retrying, "" is returned.
         * If no good revision text could be returned for
         * $this->maxConsecutiveFailedTextRetrievals consecutive calls to getText, MWException
         * is thrown.
         *
-        * @param string $id The revision id to get the text for
+        * @param int|string $id Content address, or text row ID.
         * @param string|bool|null $model The content model used to determine
         *  applicable export transformations.
         *  If $model is null, it will be determined from the database.
@@ -558,6 +568,7 @@ TEXT
                $consecutiveFailedTextRetrievals = 0;
 
                if ( $model === null && $wgContentHandlerUseDB ) {
+                       // TODO: MCR: use content table
                        $row = $this->db->selectRow(
                                'revision',
                                [ 'rev_content_model', 'rev_content_format' ],
@@ -700,30 +711,35 @@ TEXT
        }
 
        /**
-        * May throw a database error if, say, the server dies during query.
-        * @param int $id
+        * Loads the serialized content from storage.
+        *
+        * @param int|string $id Content address, or text row ID.
         * @return bool|string
-        * @throws MWException
         */
        private function getTextDb( $id ) {
-               if ( !isset( $this->db ) ) {
-                       throw new MWException( __METHOD__ . "No database available" );
-               }
-               $row = $this->db->selectRow( 'text',
-                       [ 'old_text', 'old_flags' ],
-                       [ 'old_id' => $id ],
-                       __METHOD__ );
-               $text = Revision::getRevisionText( $row );
-               if ( $text === false ) {
+               $store = $this->getBlobStore();
+               $address = ( is_int( $id ) || strpos( $id, ':' ) === false )
+                       ? SqlBlobStore::makeAddressFromTextId( (int)$id )
+                       : $id;
+
+               try {
+                       $text = $store->getBlob( $address );
+
+                       $stripped = str_replace( "\r", "", $text );
+                       $normalized = MediaWikiServices::getInstance()->getContentLanguage()
+                               ->normalize( $stripped );
+
+                       return $normalized;
+               } catch ( BlobAccessException $ex ) {
+                       // XXX: log a warning?
                        return false;
                }
-               $stripped = str_replace( "\r", "", $text );
-               $normalized = MediaWikiServices::getInstance()->getContentLanguage()->
-                       normalize( $stripped );
-
-               return $normalized;
        }
 
+       /**
+        * @param int|string $id Content address, or text row ID.
+        * @return bool|string
+        */
        private function getTextSpawned( $id ) {
                Wikimedia\suppressWarnings();
                if ( !$this->spawnProc ) {
@@ -797,6 +813,10 @@ TEXT
                Wikimedia\restoreWarnings();
        }
 
+       /**
+        * @param int|string $id Content address, or text row ID.
+        * @return bool|string
+        */
        private function getTextSpawnedOnce( $id ) {
                $ok = fwrite( $this->spawnWrite, "$id\n" );
                // $this->progress( ">> $id" );
@@ -812,10 +832,23 @@ TEXT
 
                // check that the text id they are sending is the one we asked for
                // this avoids out of sync revision text errors we have encountered in the past
-               $newId = fgets( $this->spawnRead );
-               if ( $newId === false ) {
+               $newAddress = fgets( $this->spawnRead );
+               if ( $newAddress === false ) {
                        return false;
                }
+               if ( strpos( $newAddress, ':' ) === false ) {
+                       $newId = intval( $newAddress );
+                       if ( $newId === false ) {
+                               return false;
+                       }
+               } else {
+                       try {
+                               $newAddressFields = SqlBlobStore::splitBlobAddress( $newAddress );
+                               $newId = $newAddressFields[ 1 ];
+                       } catch ( InvalidArgumentException $ex ) {
+                               return false;
+                       }
+               }
                if ( $id != intval( $newId ) ) {
                        return false;
                }