Merge "Revert "Log the reason why revision->getContent() returns null""
[lhc/web/wiklou.git] / includes / Storage / SqlBlobStore.php
index fcdc1b9..0ff7c13 100644 (file)
@@ -35,6 +35,7 @@ use Language;
 use MWException;
 use WANObjectCache;
 use Wikimedia\Assert\Assert;
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
 
@@ -269,7 +270,10 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                        // TODO: change key, since this is not necessarily revision text!
                        $this->cache->makeKey( 'revisiontext', 'textid', $blobAddress ),
                        $this->getCacheTTL(),
-                       function () use ( $blobAddress, $queryFlags ) {
+                       function ( $unused, &$ttl, &$setOpts ) use ( $blobAddress, $queryFlags ) {
+                               list( $index ) = DBAccessObjectUtils::getDBOptions( $queryFlags );
+                               $setOpts += Database::getCacheSetOptions( $this->getDBConnection( $index ) );
+
                                return $this->fetchBlob( $blobAddress, $queryFlags );
                        },
                        [ 'pcGroup' => self::TEXT_CACHE_GROUP, 'pcTTL' => IExpiringStore::TTL_PROC_LONG ]
@@ -295,7 +299,6 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                list( $schema, $id, ) = self::splitBlobAddress( $blobAddress );
 
                //TODO: MCR: also support 'ex' schema with ExternalStore URLs, plus flags encoded in the URL!
-               //TODO: MCR: also support 'ar' schema for content blobs in old style archive rows!
                if ( $schema === 'tt' ) {
                        $textId = intval( $id );
                } else {
@@ -365,6 +368,8 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
         *        May be the blob itself, or the blob compressed, or just the address
         *        of the actual blob, depending on $flags.
         * @param string|string[] $flags Blob flags, such as 'external' or 'gzip'.
+        *   Note that not including 'utf-8' in $flags will cause the data to be decoded
+        *   according to the legacy encoding specified via setLegacyEncoding.
         * @param string|null $cacheKey May be used for caching if given
         *
         * @return false|string The expanded blob or false on failure
@@ -382,7 +387,7 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                                return false;
                        }
 
-                       if ( $cacheKey ) {
+                       if ( $cacheKey && $this->wikiId === false ) {
                                // Make use of the wiki-local revision text cache.
                                // The cached value should be decompressed, so handle that and return here.
                                // NOTE: we rely on $this->cache being the right cache for $this->wikiId!
@@ -427,7 +432,8 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                $blobFlags = [];
 
                // Revisions not marked as UTF-8 will have legacy decoding applied by decompressData().
-               // XXX: if $this->legacyEncoding is not set, we could skip this. May be risky, though.
+               // XXX: if $this->legacyEncoding is not set, we could skip this. That would however be
+               // risky, since $this->legacyEncoding being set in the future would lead to data corruption.
                $blobFlags[] = 'utf-8';
 
                if ( $this->compressBlobs ) {
@@ -456,16 +462,23 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
         * @todo make this private, there should be no need to use this method outside this class.
         *
         * @param mixed $blob Reference to a text
-        * @param array $blobFlags Compression flags
+        * @param array $blobFlags Compression flags, such as 'gzip'.
+        *   Note that not including 'utf-8' in $blobFlags will cause the data to be decoded
+        *   according to the legacy encoding specified via setLegacyEncoding.
         *
         * @return string|bool Decompressed text, or false on failure
         */
-       public function decompressData( $blob, $blobFlags ) {
+       public function decompressData( $blob, array $blobFlags ) {
                if ( $blob === false ) {
                        // Text failed to be fetched; nothing to do
                        return false;
                }
 
+               if ( in_array( 'error', $blobFlags ) ) {
+                       // Error row, return false
+                       return false;
+               }
+
                if ( in_array( 'gzip', $blobFlags ) ) {
                        # Deal with optional compression of archived pages.
                        # This can be done periodically via maintenance/compressOld.php, and
@@ -577,4 +590,11 @@ class SqlBlobStore implements IDBAccessObject, BlobStore {
                return [ $schema, $id, $parameters ];
        }
 
+       public function isReadOnly() {
+               if ( $this->useExternalStore && ExternalStore::defaultStoresAreReadOnly() ) {
+                       return true;
+               }
+
+               return ( $this->getDBLoadBalancer()->getReadOnlyReason() !== false );
+       }
 }