rdbms: make implement IResultWrapper directly instead of via inheritence
authorAaron Schulz <aschulz@wikimedia.org>
Thu, 20 Jun 2019 22:17:22 +0000 (23:17 +0100)
committerKrinkle <krinklemail@gmail.com>
Thu, 4 Jul 2019 13:42:53 +0000 (13:42 +0000)
Change-Id: If1b15c0c21d0ee336025fb99f47fc19ddf1d5435

includes/db/DatabaseOracle.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php
includes/libs/rdbms/database/resultwrapper/ResultWrapper.php
includes/specials/pagers/AllMessagesTablePager.php
tests/phpunit/includes/libs/rdbms/database/DBConnRefTest.php

index c716e4d..a123d00 100644 (file)
@@ -253,11 +253,7 @@ class DatabaseOracle extends Database {
         * @param IResultWrapper|ORAResult $res
         */
        function freeResult( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               $res->free();
+               ResultWrapper::unwrap( $res )->free();
        }
 
        /**
@@ -265,11 +261,7 @@ class DatabaseOracle extends Database {
         * @return stdClass|bool
         */
        function fetchObject( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $res->fetchObject();
+               return ResultWrapper::unwrap( $res )->fetchObject();
        }
 
        /**
@@ -277,11 +269,7 @@ class DatabaseOracle extends Database {
         * @return stdClass|bool
         */
        function fetchRow( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $res->fetchRow();
+               return ResultWrapper::unwrap( $res )->fetchRow();
        }
 
        /**
@@ -289,11 +277,7 @@ class DatabaseOracle extends Database {
         * @return int
         */
        function numRows( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $res->numRows();
+               return ResultWrapper::unwrap( $res )->numRows();
        }
 
        /**
@@ -301,11 +285,7 @@ class DatabaseOracle extends Database {
         * @return int
         */
        function numFields( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $res->numFields();
+               return ResultWrapper::unwrap( $res )->numFields();
        }
 
        function fieldName( $stmt, $n ) {
@@ -326,7 +306,7 @@ class DatabaseOracle extends Database {
                if ( $res instanceof ORAResult ) {
                        $res->seek( $row );
                } else {
-                       $res->result->seek( $row );
+                       ResultWrapper::unwrap( $res )->seek( $row );
                }
        }
 
index dfad922..9233e13 100644 (file)
@@ -994,8 +994,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         * For SELECT queries, this returns either:
         *   - a) A driver-specific value/resource, only on success. This can be iterated
         *        over by calling fetchObject()/fetchRow() until there are no more rows.
-        *        Alternatively, the result can be passed to resultObject() to obtain a
-        *        ResultWrapper instance which can then be iterated over via "foreach".
+        *        Alternatively, the result can be passed to resultObject() to obtain an
+        *        IResultWrapper instance which can then be iterated over via "foreach".
         *   - b) False, on any query failure
         *
         * For non-SELECT queries, this returns either:
@@ -4185,9 +4185,8 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        abstract protected function fetchAffectedRowCount();
 
        /**
-        * Take the result from a query, and wrap it in a ResultWrapper if
-        * necessary. Boolean values are passed through as is, to indicate success
-        * of write queries or failure.
+        * Take a query result and wrap it in an iterable result wrapper if necessary.
+        * Booleans are passed through as-is to indicate success/failure of write queries.
         *
         * Once upon a time, Database::query() returned a bare MySQL result
         * resource, and it was necessary to call this function to convert it to
@@ -4199,12 +4198,11 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        protected function resultObject( $result ) {
                if ( !$result ) {
-                       return false;
-               } elseif ( $result instanceof ResultWrapper ) {
+                       return false; // failed query
+               } elseif ( $result instanceof IResultWrapper ) {
                        return $result;
                } elseif ( $result === true ) {
-                       // Successful write query
-                       return $result;
+                       return $result; // succesful write query
                } else {
                        return new ResultWrapper( $this, $result );
                }
index 50aaff2..69174f9 100644 (file)
@@ -229,11 +229,7 @@ class DatabaseMssql extends Database {
        }
 
        public function freeResult( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               sqlsrv_free_stmt( $res );
+               sqlsrv_free_stmt( ResultWrapper::unwrap( $res ) );
        }
 
        /**
@@ -258,12 +254,9 @@ class DatabaseMssql extends Database {
         * @return int
         */
        public function numRows( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
+               $res = ResultWrapper::unwrap( $res );
 
                $ret = sqlsrv_num_rows( $res );
-
                if ( $ret === false ) {
                        // we cannot get an amount of rows from this cursor type
                        // has_rows returns bool true/false if the result has rows
@@ -278,11 +271,7 @@ class DatabaseMssql extends Database {
         * @return int
         */
        public function numFields( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return sqlsrv_num_fields( $res );
+               return sqlsrv_num_fields( ResultWrapper::unwrap( $res ) );
        }
 
        /**
@@ -291,11 +280,7 @@ class DatabaseMssql extends Database {
         * @return int
         */
        public function fieldName( $res, $n ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return sqlsrv_field_metadata( $res )[$n]['Name'];
+               return sqlsrv_field_metadata( ResultWrapper::unwrap( $res ) )[$n]['Name'];
        }
 
        /**
@@ -730,7 +715,7 @@ class DatabaseMssql extends Database {
                        }
                        $this->scrollableCursor = true;
 
-                       if ( $ret instanceof ResultWrapper && !is_null( $identity ) ) {
+                       if ( $ret instanceof IResultWrapper && !is_null( $identity ) ) {
                                // Then we want to get the identity column value we were assigned and save it off
                                $row = $ret->fetchObject();
                                if ( is_object( $row ) ) {
index b3af8ad..417b464 100644 (file)
@@ -241,11 +241,8 @@ abstract class DatabaseMysqlBase extends Database {
         * @throws DBUnexpectedError
         */
        public function freeResult( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
                Wikimedia\suppressWarnings();
-               $ok = $this->mysqlFreeResult( $res );
+               $ok = $this->mysqlFreeResult( ResultWrapper::unwrap( $res ) );
                Wikimedia\restoreWarnings();
                if ( !$ok ) {
                        throw new DBUnexpectedError( $this, "Unable to free MySQL result" );
@@ -266,11 +263,8 @@ abstract class DatabaseMysqlBase extends Database {
         * @throws DBUnexpectedError
         */
        public function fetchObject( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
                Wikimedia\suppressWarnings();
-               $row = $this->mysqlFetchObject( $res );
+               $row = $this->mysqlFetchObject( ResultWrapper::unwrap( $res ) );
                Wikimedia\restoreWarnings();
 
                $errno = $this->lastErrno();
@@ -302,11 +296,8 @@ abstract class DatabaseMysqlBase extends Database {
         * @throws DBUnexpectedError
         */
        public function fetchRow( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
                Wikimedia\suppressWarnings();
-               $row = $this->mysqlFetchArray( $res );
+               $row = $this->mysqlFetchArray( ResultWrapper::unwrap( $res ) );
                Wikimedia\restoreWarnings();
 
                $errno = $this->lastErrno();
@@ -338,12 +329,13 @@ abstract class DatabaseMysqlBase extends Database {
         * @return int
         */
        function numRows( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
+               if ( is_bool( $res ) ) {
+                       $n = 0;
+               } else {
+                       Wikimedia\suppressWarnings();
+                       $n = $this->mysqlNumRows( ResultWrapper::unwrap( $res ) );
+                       Wikimedia\restoreWarnings();
                }
-               Wikimedia\suppressWarnings();
-               $n = !is_bool( $res ) ? $this->mysqlNumRows( $res ) : 0;
-               Wikimedia\restoreWarnings();
 
                // Unfortunately, mysql_num_rows does not reset the last errno.
                // We are not checking for any errors here, since
@@ -366,11 +358,7 @@ abstract class DatabaseMysqlBase extends Database {
         * @return int
         */
        public function numFields( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $this->mysqlNumFields( $res );
+               return $this->mysqlNumFields( ResultWrapper::unwrap( $res ) );
        }
 
        /**
@@ -387,11 +375,7 @@ abstract class DatabaseMysqlBase extends Database {
         * @return string
         */
        public function fieldName( $res, $n ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $this->mysqlFieldName( $res, $n );
+               return $this->mysqlFieldName( ResultWrapper::unwrap( $res ), $n );
        }
 
        /**
@@ -410,11 +394,7 @@ abstract class DatabaseMysqlBase extends Database {
         * @return string
         */
        public function fieldType( $res, $n ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $this->mysqlFieldType( $res, $n );
+               return $this->mysqlFieldType( ResultWrapper::unwrap( $res ), $n );
        }
 
        /**
@@ -432,11 +412,7 @@ abstract class DatabaseMysqlBase extends Database {
         * @return bool
         */
        public function dataSeek( $res, $row ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return $this->mysqlDataSeek( $res, $row );
+               return $this->mysqlDataSeek( ResultWrapper::unwrap( $res ), $row );
        }
 
        /**
@@ -606,9 +582,9 @@ abstract class DatabaseMysqlBase extends Database {
                if ( !$res ) {
                        return false;
                }
-               $n = $this->mysqlNumFields( $res->result );
+               $n = $this->mysqlNumFields( ResultWrapper::unwrap( $res ) );
                for ( $i = 0; $i < $n; $i++ ) {
-                       $meta = $this->mysqlFetchField( $res->result, $i );
+                       $meta = $this->mysqlFetchField( ResultWrapper::unwrap( $res ), $i );
                        if ( $field == $meta->name ) {
                                return new MySQLField( $meta );
                        }
index 92eac90..08987d9 100644 (file)
@@ -274,11 +274,8 @@ class DatabasePostgres extends Database {
        }
 
        public function freeResult( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
                Wikimedia\suppressWarnings();
-               $ok = pg_free_result( $res );
+               $ok = pg_free_result( ResultWrapper::unwrap( $res ) );
                Wikimedia\restoreWarnings();
                if ( !$ok ) {
                        throw new DBUnexpectedError( $this, "Unable to free Postgres result\n" );
@@ -286,11 +283,8 @@ class DatabasePostgres extends Database {
        }
 
        public function fetchObject( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
                Wikimedia\suppressWarnings();
-               $row = pg_fetch_object( $res );
+               $row = pg_fetch_object( ResultWrapper::unwrap( $res ) );
                Wikimedia\restoreWarnings();
                # @todo FIXME: HACK HACK HACK HACK debug
 
@@ -308,11 +302,8 @@ class DatabasePostgres extends Database {
        }
 
        public function fetchRow( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
                Wikimedia\suppressWarnings();
-               $row = pg_fetch_array( $res );
+               $row = pg_fetch_array( ResultWrapper::unwrap( $res ) );
                Wikimedia\restoreWarnings();
 
                $conn = $this->getBindingHandle();
@@ -331,11 +322,8 @@ class DatabasePostgres extends Database {
                        return 0;
                }
 
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
                Wikimedia\suppressWarnings();
-               $n = pg_num_rows( $res );
+               $n = pg_num_rows( ResultWrapper::unwrap( $res ) );
                Wikimedia\restoreWarnings();
 
                $conn = $this->getBindingHandle();
@@ -350,19 +338,11 @@ class DatabasePostgres extends Database {
        }
 
        public function numFields( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return pg_num_fields( $res );
+               return pg_num_fields( ResultWrapper::unwrap( $res ) );
        }
 
        public function fieldName( $res, $n ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return pg_field_name( $res, $n );
+               return pg_field_name( ResultWrapper::unwrap( $res ), $n );
        }
 
        public function insertId() {
@@ -372,11 +352,7 @@ class DatabasePostgres extends Database {
        }
 
        public function dataSeek( $res, $row ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return pg_result_seek( $res, $row );
+               return pg_result_seek( ResultWrapper::unwrap( $res ), $row );
        }
 
        public function lastError() {
@@ -1307,11 +1283,7 @@ SQL;
         * @return string
         */
        public function fieldType( $res, $index ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return pg_field_type( $res, $index );
+               return pg_field_type( ResultWrapper::unwrap( $res ), $index );
        }
 
        public function encodeBlob( $b ) {
index c1a3ab5..c875e56 100644 (file)
@@ -355,9 +355,9 @@ class DatabaseSqlite extends Database {
                        return false;
                }
 
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
-               $this->lastAffectedRowCount = $r->rowCount();
-               $res = new ResultWrapper( $this, $r->fetchAll() );
+               $resource = ResultWrapper::unwrap( $res );
+               $this->lastAffectedRowCount = $resource->rowCount();
+               $res = new ResultWrapper( $this, $resource->fetchAll() );
 
                return $res;
        }
@@ -367,9 +367,7 @@ class DatabaseSqlite extends Database {
         */
        function freeResult( $res ) {
                if ( $res instanceof ResultWrapper ) {
-                       $res->result = null;
-               } else {
-                       $res = null;
+                       $res->free();
                }
        }
 
@@ -378,15 +376,11 @@ class DatabaseSqlite extends Database {
         * @return stdClass|bool
         */
        function fetchObject( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $r =& $res->result;
-               } else {
-                       $r =& $res;
-               }
+               $resource =& ResultWrapper::unwrap( $res );
 
-               $cur = current( $r );
+               $cur = current( $resource );
                if ( is_array( $cur ) ) {
-                       next( $r );
+                       next( $resource );
                        $obj = new stdClass;
                        foreach ( $cur as $k => $v ) {
                                if ( !is_numeric( $k ) ) {
@@ -405,14 +399,10 @@ class DatabaseSqlite extends Database {
         * @return array|bool
         */
        function fetchRow( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $r =& $res->result;
-               } else {
-                       $r =& $res;
-               }
-               $cur = current( $r );
+               $resource =& ResultWrapper::unwrap( $res );
+               $cur = current( $resource );
                if ( is_array( $cur ) ) {
-                       next( $r );
+                       next( $resource );
 
                        return $cur;
                }
@@ -428,9 +418,9 @@ class DatabaseSqlite extends Database {
         */
        function numRows( $res ) {
                // false does not implement Countable
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
+               $resource = ResultWrapper::unwrap( $res );
 
-               return is_array( $r ) ? count( $r ) : 0;
+               return is_array( $resource ) ? count( $resource ) : 0;
        }
 
        /**
@@ -438,10 +428,10 @@ class DatabaseSqlite extends Database {
         * @return int
         */
        function numFields( $res ) {
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
-               if ( is_array( $r ) && count( $r ) > 0 ) {
+               $resource = ResultWrapper::unwrap( $res );
+               if ( is_array( $resource ) && count( $resource ) > 0 ) {
                        // The size of the result array is twice the number of fields. (T67578)
-                       return count( $r[0] ) / 2;
+                       return count( $resource[0] ) / 2;
                } else {
                        // If the result is empty return 0
                        return 0;
@@ -454,9 +444,9 @@ class DatabaseSqlite extends Database {
         * @return bool
         */
        function fieldName( $res, $n ) {
-               $r = $res instanceof ResultWrapper ? $res->result : $res;
-               if ( is_array( $r ) ) {
-                       $keys = array_keys( $r[0] );
+               $resource = ResultWrapper::unwrap( $res );
+               if ( is_array( $resource ) ) {
+                       $keys = array_keys( $resource[0] );
 
                        return $keys[$n];
                }
@@ -495,15 +485,11 @@ class DatabaseSqlite extends Database {
         * @param int $row
         */
        function dataSeek( $res, $row ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $r =& $res->result;
-               } else {
-                       $r =& $res;
-               }
-               reset( $r );
+               $resource =& ResultWrapper::unwrap( $res );
+               reset( $resource );
                if ( $row > 0 ) {
                        for ( $i = 0; $i < $row; $i++ ) {
-                               next( $r );
+                               next( $resource );
                        }
                }
        }
index 2ca3d7d..1094faf 100644 (file)
@@ -8,21 +8,29 @@ use stdClass;
  * Overloads the relevant methods of the real ResultsWrapper so it
  * doesn't go anywhere near an actual database.
  */
-class FakeResultWrapper extends ResultWrapper {
-       /** @var stdClass[]|array[] $result */
+class FakeResultWrapper implements IResultWrapper {
+       /** @var stdClass[]|array[] */
+       protected $result;
+
+       /** @var int */
+       protected $pos = 0;
 
        /**
-        * @param stdClass[]|array[] $rows
+        * @param stdClass[]|array[]|FakeResultWrapper $result
         */
-       function __construct( array $rows ) {
-               parent::__construct( null, $rows );
+       public function __construct( $result ) {
+               if ( $result instanceof self ) {
+                       $this->result = $result->result;
+               } else {
+                       $this->result = $result;
+               }
        }
 
-       function numRows() {
+       public function numRows() {
                return count( $this->result );
        }
 
-       function fetchObject() {
+       public function fetchObject() {
                $current = $this->current();
 
                $this->next();
@@ -30,7 +38,7 @@ class FakeResultWrapper extends ResultWrapper {
                return $current;
        }
 
-       function fetchRow() {
+       public function fetchRow() {
                $row = $this->valid() ? $this->result[$this->pos] : false;
 
                $this->next();
@@ -38,35 +46,35 @@ class FakeResultWrapper extends ResultWrapper {
                return is_object( $row ) ? get_object_vars( $row ) : $row;
        }
 
-       function seek( $pos ) {
+       public function seek( $pos ) {
                $this->pos = $pos;
        }
 
-       function free() {
+       public function free() {
                $this->result = null;
        }
 
-       function rewind() {
+       public function rewind() {
                $this->pos = 0;
        }
 
-       function current() {
+       public function current() {
                $row = $this->valid() ? $this->result[$this->pos] : false;
 
                return is_array( $row ) ? (object)$row : $row;
        }
 
-       function key() {
+       public function key() {
                return $this->pos;
        }
 
-       function next() {
+       public function next() {
                $this->pos++;
 
                return $this->current();
        }
 
-       function valid() {
+       public function valid() {
                return array_key_exists( $this->pos, $this->result );
        }
 }
index b7938ad..3e50967 100644 (file)
@@ -4,29 +4,27 @@ namespace Wikimedia\Rdbms;
 
 use stdClass;
 use RuntimeException;
+use InvalidArgumentException;
 
 /**
  * Result wrapper for grabbing data queried from an IDatabase object
  *
+ * Only IDatabase-related classes should construct these. Other code may
+ * use the FakeResultWrapper class for convenience or compatibility shims.
+ *
  * Note that using the Iterator methods in combination with the non-Iterator
- * DB result iteration functions may cause rows to be skipped or repeated.
+ * IDatabase result iteration functions may cause rows to be skipped or repeated.
  *
  * By default, this will use the iteration methods of the IDatabase handle if provided.
  * Subclasses can override methods to make it solely work on the result resource instead.
- * If no database is provided, and the subclass does not override the DB iteration methods,
- * then a RuntimeException will be thrown when iteration is attempted.
- *
- * The result resource field should not be accessed from non-Database related classes.
- * It is database class specific and is stored here to associate iterators with queries.
  *
  * @ingroup Database
  */
 class ResultWrapper implements IResultWrapper {
-       /** @var resource|array|null Optional underlying result handle for subclass usage */
-       public $result;
-
-       /** @var IDatabase|null */
+       /** @var IDatabase */
        protected $db;
+       /** @var mixed|null RDBMS driver-specific result resource */
+       protected $result;
 
        /** @var int */
        protected $pos = 0;
@@ -34,20 +32,39 @@ class ResultWrapper implements IResultWrapper {
        protected $currentRow;
 
        /**
-        * Create a row iterator from a result resource and an optional Database object
-        *
-        * Only Database-related classes should construct ResultWrapper. Other code may
-        * use the FakeResultWrapper subclass for convenience or compatibility shims, however.
-        *
-        * @param IDatabase|null $db Optional database handle
-        * @param ResultWrapper|array|resource $result Optional underlying result handle
+        * @param IDatabase $db Database handle that the result comes from
+        * @param self|mixed $result RDBMS driver-specific result resource
         */
-       public function __construct( IDatabase $db = null, $result ) {
+       public function __construct( IDatabase $db, $result ) {
                $this->db = $db;
-               if ( $result instanceof ResultWrapper ) {
+               if ( $result instanceof self ) {
                        $this->result = $result->result;
-               } else {
+               } elseif ( $result !== null ) {
                        $this->result = $result;
+               } else {
+                       throw new InvalidArgumentException( "Null result resource provided" );
+               }
+       }
+
+       /**
+        * Get the underlying RDBMS driver-specific result resource
+        *
+        * The result resource field should not be accessed from non-Database related classes.
+        * It is database class specific and is stored here to associate iterators with queries.
+        *
+        * @param self|mixed &$res
+        * @return mixed
+        * @since 1.34
+        */
+       public static function &unwrap( &$res ) {
+               if ( $res instanceof self ) {
+                       if ( $res->result === null ) {
+                               throw new RuntimeException( "The result resource was already freed" );
+                       }
+
+                       return $res->result;
+               } else {
+                       return $res;
                }
        }
 
@@ -110,7 +127,7 @@ class ResultWrapper implements IResultWrapper {
         */
        private function getDB() {
                if ( !$this->db ) {
-                       throw new RuntimeException( static::class . ' needs a DB handle for iteration.' );
+                       throw new RuntimeException( "Database handle was already freed" );
                }
 
                return $this->db;
index 6facda1..76e2ab7 100644 (file)
@@ -176,11 +176,11 @@ class AllMessagesTablePager extends TablePager {
         */
        function reallyDoQuery( $offset, $limit, $order ) {
                $asc = ( $order === self::QUERY_ASCENDING );
-               $result = new FakeResultWrapper( [] );
 
                $messageNames = $this->getAllMessages( $order );
                $statuses = self::getCustomisedStatuses( $messageNames, $this->langcode, $this->foreign );
 
+               $rows = [];
                $count = 0;
                foreach ( $messageNames as $key ) {
                        $customised = isset( $statuses['pages'][$key] );
@@ -190,7 +190,7 @@ class AllMessagesTablePager extends TablePager {
                        ) {
                                $actual = $this->msg( $key )->inLanguage( $this->lang )->plain();
                                $default = $this->msg( $key )->inLanguage( $this->lang )->useDatabase( false )->plain();
-                               $result->result[] = [
+                               $rows[] = [
                                        'am_title' => $key,
                                        'am_actual' => $actual,
                                        'am_default' => $default,
@@ -205,7 +205,7 @@ class AllMessagesTablePager extends TablePager {
                        }
                }
 
-               return $result;
+               return new FakeResultWrapper( $rows );
        }
 
        protected function getStartBody() {
index 833ac2c..fafeb4e 100644 (file)
@@ -4,7 +4,7 @@ use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\DBConnRef;
 use Wikimedia\Rdbms\FakeResultWrapper;
 use Wikimedia\Rdbms\ILoadBalancer;
-use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\IResultWrapper;
 
 /**
  * @covers Wikimedia\Rdbms\DBConnRef
@@ -75,7 +75,7 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
                $lb = $this->getLoadBalancerMock();
                $ref = new DBConnRef( $lb, $this->getDatabaseMock(), DB_MASTER );
 
-               $this->assertInstanceOf( ResultWrapper::class, $ref->select( 'whatever', '*' ) );
+               $this->assertInstanceOf( IResultWrapper::class, $ref->select( 'whatever', '*' ) );
        }
 
        public function testConstruct_params() {
@@ -96,7 +96,7 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
                        DB_MASTER
                );
 
-               $this->assertInstanceOf( ResultWrapper::class, $ref->select( 'whatever', '*' ) );
+               $this->assertInstanceOf( IResultWrapper::class, $ref->select( 'whatever', '*' ) );
                $this->assertEquals( DB_MASTER, $ref->getReferenceRole() );
 
                $ref2 = new DBConnRef(
@@ -119,7 +119,7 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
        private function innerMethodForTestDestruct( ILoadBalancer $lb ) {
                $ref = $lb->getConnectionRef( DB_REPLICA );
 
-               $this->assertInstanceOf( ResultWrapper::class, $ref->select( 'whatever', '*' ) );
+               $this->assertInstanceOf( IResultWrapper::class, $ref->select( 'whatever', '*' ) );
        }
 
        public function testConstruct_failure() {
@@ -150,7 +150,7 @@ class DBConnRefTest extends PHPUnit\Framework\TestCase {
        public function testSelect() {
                // select should get passed through normally
                $ref = $this->getDBConnRef();
-               $this->assertInstanceOf( ResultWrapper::class, $ref->select( 'whatever', '*' ) );
+               $this->assertInstanceOf( IResultWrapper::class, $ref->select( 'whatever', '*' ) );
        }
 
        public function testToString() {