diff --git a/RELEASE-NOTES-1.41 b/RELEASE-NOTES-1.41 index d4a89f9edeb..c475bbe13b7 100644 --- a/RELEASE-NOTES-1.41 +++ b/RELEASE-NOTES-1.41 @@ -229,6 +229,9 @@ because of Phabricator reports. * Public access to the DifferenceEngine properties mOldid, mNewid, mOldRev, mNewRev, mOldPage, mNewPage, mOldContent, mNewContent, mRevisionsLoaded, mTextLoaded and mCacheHit, deprecated in 1.32, was removed. +* SearchDatabase::db, deprecated since 1.38, has been removed. +* SearchDatabase::lb has been removed without deprecation, use ::dbProvider + instead. * Title::newFromTitleValue(), deprecated since 1.34, has been removed. * SpecialPageAction has been removed without deprecation. There were no known uses outside of core. diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 799b0144539..127b654f061 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -1857,7 +1857,7 @@ return [ return new SearchEngineFactory( $services->getSearchEngineConfig(), $services->getHookContainer(), - $services->getDBLoadBalancer() + $services->getDBLoadBalancerFactory() ); }, diff --git a/includes/search/SearchDatabase.php b/includes/search/SearchDatabase.php index 80659665f58..f6d06616eaa 100644 --- a/includes/search/SearchDatabase.php +++ b/includes/search/SearchDatabase.php @@ -21,8 +21,7 @@ * @ingroup Search */ -use Wikimedia\Rdbms\IDatabase; -use Wikimedia\Rdbms\ILoadBalancer; +use Wikimedia\Rdbms\IConnectionProvider; /** * Base search engine base class for database-backed searches @@ -31,23 +30,17 @@ use Wikimedia\Rdbms\ILoadBalancer; * @since 1.23 */ abstract class SearchDatabase extends SearchEngine { - /** @var ILoadBalancer */ - protected $lb; - /** @var IDatabase (backwards compatibility) */ - protected $db; - /** * @var string[] search terms */ protected $searchTerms = []; + protected IConnectionProvider $dbProvider; /** - * @param ILoadBalancer $lb The load balancer for the DB cluster to search on + * @param IConnectionProvider $dbProvider */ - public function __construct( ILoadBalancer $lb ) { - $this->lb = $lb; - // @TODO: remove this deprecated field in 1.35 - $this->db = $lb->getConnectionRef( DB_REPLICA ); // b/c + public function __construct( IConnectionProvider $dbProvider ) { + $this->dbProvider = $dbProvider; } /** diff --git a/includes/search/SearchEngineFactory.php b/includes/search/SearchEngineFactory.php index 7c3e7231d86..06b7f2e13f8 100644 --- a/includes/search/SearchEngineFactory.php +++ b/includes/search/SearchEngineFactory.php @@ -2,8 +2,7 @@ use MediaWiki\HookContainer\HookContainer; use Wikimedia\ObjectFactory\ObjectFactory; -use Wikimedia\Rdbms\IDatabase; -use Wikimedia\Rdbms\ILoadBalancer; +use Wikimedia\Rdbms\IConnectionProvider; /** * Factory class for SearchEngine. @@ -19,22 +18,21 @@ class SearchEngineFactory { /** @var HookContainer */ private $hookContainer; - /** @var ILoadBalancer */ - private $loadBalancer; + private IConnectionProvider $dbProvider; /** * @param SearchEngineConfig $config * @param HookContainer $hookContainer - * @param ILoadBalancer $loadBalancer + * @param IConnectionProvider $dbProvider */ public function __construct( SearchEngineConfig $config, HookContainer $hookContainer, - ILoadBalancer $loadBalancer + IConnectionProvider $dbProvider ) { $this->config = $config; $this->hookContainer = $hookContainer; - $this->loadBalancer = $loadBalancer; + $this->dbProvider = $dbProvider; } /** @@ -52,7 +50,7 @@ class SearchEngineFactory { } elseif ( $configuredClass !== null ) { $class = $configuredClass; } else { - $class = self::getSearchEngineClass( $this->loadBalancer ); + $class = self::getSearchEngineClass( $this->dbProvider ); } $mappings = $this->config->getSearchMappings(); @@ -63,7 +61,7 @@ class SearchEngineFactory { $args = []; if ( isset( $spec['class'] ) && is_subclass_of( $spec['class'], SearchDatabase::class ) ) { - $args['extraArgs'][] = $this->loadBalancer; + $args['extraArgs'][] = $this->dbProvider; } // ObjectFactory::getObjectFromSpec accepts an array, not just a callable (phan bug) @@ -75,14 +73,12 @@ class SearchEngineFactory { } /** - * @param IDatabase|ILoadBalancer $dbOrLb + * @param IConnectionProvider $dbProvider * @return string SearchEngine subclass name * @since 1.28 */ - public static function getSearchEngineClass( $dbOrLb ) { - $type = ( $dbOrLb instanceof IDatabase ) - ? $dbOrLb->getType() - : $dbOrLb->getServerType( $dbOrLb->getWriterIndex() ); + public static function getSearchEngineClass( IConnectionProvider $dbProvider ) { + $type = $dbProvider->getReplicaDatabase()->getType(); switch ( $type ) { case 'sqlite': diff --git a/includes/search/SearchMySQL.php b/includes/search/SearchMySQL.php index 0f6abb51585..f91a80ebc96 100644 --- a/includes/search/SearchMySQL.php +++ b/includes/search/SearchMySQL.php @@ -128,7 +128,7 @@ class SearchMySQL extends SearchDatabase { wfDebug( __METHOD__ . ": Can't understand search query '{$filteredText}'" ); } - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $searchon = $dbr->addQuotes( $searchon ); $field = $this->getIndexField( $fulltext ); return [ @@ -191,7 +191,7 @@ class SearchMySQL extends SearchDatabase { $filteredTerm = $this->filter( $term ); $query = $this->getQuery( $filteredTerm, $fulltext ); - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $resultSet = $dbr->select( $query['tables'], $query['fields'], $query['conds'], __METHOD__, $query['options'], $query['joins'] @@ -230,7 +230,7 @@ class SearchMySQL extends SearchDatabase { protected function queryFeatures( &$query ) { foreach ( $this->features as $feature => $value ) { if ( $feature === 'title-suffix-filter' && $value ) { - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $query['conds'][] = 'page_title' . $dbr->buildLike( $dbr->anyString(), $value ); } } @@ -346,8 +346,7 @@ class SearchMySQL extends SearchDatabase { * @param string $text */ public function update( $id, $title, $text ) { - $dbw = $this->lb->getConnectionRef( DB_PRIMARY ); - $dbw->replace( + $this->dbProvider->getPrimaryDatabase()->replace( 'searchindex', 'si_page', [ @@ -367,8 +366,7 @@ class SearchMySQL extends SearchDatabase { * @param string $title */ public function updateTitle( $id, $title ) { - $dbw = $this->lb->getConnectionRef( DB_PRIMARY ); - $dbw->newUpdateQueryBuilder() + $this->dbProvider->getPrimaryDatabase()->newUpdateQueryBuilder() ->update( 'searchindex' ) ->set( [ 'si_title' => $this->normalizeText( $title ) ] ) ->where( [ 'si_page' => $id ] ) @@ -383,8 +381,7 @@ class SearchMySQL extends SearchDatabase { * @param string $title Title of page that was deleted */ public function delete( $id, $title ) { - $dbw = $this->lb->getConnectionRef( DB_PRIMARY ); - $dbw->newDeleteQueryBuilder() + $this->dbProvider->getPrimaryDatabase()->newDeleteQueryBuilder() ->delete( 'searchindex' ) ->where( [ 'si_page' => $id ] ) ->caller( __METHOD__ )->execute(); @@ -451,7 +448,7 @@ class SearchMySQL extends SearchDatabase { if ( self::$mMinSearchLength === null ) { $sql = "SHOW GLOBAL VARIABLES LIKE 'ft\\_min\\_word\\_len'"; - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); // phpcs:ignore MediaWiki.Usage.DbrQueryUsage.DbrQueryFound $result = $dbr->query( $sql, __METHOD__ ); $row = $result->fetchObject(); diff --git a/includes/search/SearchPostgres.php b/includes/search/SearchPostgres.php index a6c7e743edc..e11c61628d4 100644 --- a/includes/search/SearchPostgres.php +++ b/includes/search/SearchPostgres.php @@ -43,7 +43,7 @@ class SearchPostgres extends SearchDatabase { protected function doSearchTitleInDB( $term ) { $q = $this->searchQuery( $term, 'titlevector' ); $olderror = error_reporting( E_ERROR ); - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); // phpcs:ignore MediaWiki.Usage.DbrQueryUsage.DbrQueryFound $resultSet = $dbr->query( $q, 'SearchPostgres', IDatabase::QUERY_SILENCE_ERRORS ); error_reporting( $olderror ); @@ -53,7 +53,7 @@ class SearchPostgres extends SearchDatabase { protected function doSearchTextInDB( $term ) { $q = $this->searchQuery( $term, 'textvector' ); $olderror = error_reporting( E_ERROR ); - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); // phpcs:ignore MediaWiki.Usage.DbrQueryUsage.DbrQueryFound $resultSet = $dbr->query( $q, 'SearchPostgres', IDatabase::QUERY_SILENCE_ERRORS ); error_reporting( $olderror ); @@ -116,7 +116,7 @@ class SearchPostgres extends SearchDatabase { $searchstring = preg_replace( '/^[\'"](.*)[\'"]$/', "$1", $searchstring ); // Quote the whole thing - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $searchstring = $dbr->addQuotes( $searchstring ); wfDebug( "parseQuery returned: $searchstring" ); @@ -136,7 +136,7 @@ class SearchPostgres extends SearchDatabase { // We need a separate query here so gin does not complain about empty searches $sql = "SELECT to_tsquery($searchstring)"; - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); // phpcs:ignore MediaWiki.Usage.DbrQueryUsage.DbrQueryFound $res = $dbr->query( $sql, __METHOD__ ); if ( !$res ) { @@ -209,7 +209,7 @@ class SearchPostgres extends SearchDatabase { " AND c.content_id = s.slot_content_id " . " ORDER BY old_rev_text_id DESC OFFSET 1)"; - $dbw = $this->lb->getConnectionRef( DB_PRIMARY ); + $dbw = $this->dbProvider->getPrimaryDatabase(); $dbw->query( $sql, __METHOD__ ); return true; diff --git a/includes/search/SearchSqlite.php b/includes/search/SearchSqlite.php index e635f4b100a..939eacb9dfb 100644 --- a/includes/search/SearchSqlite.php +++ b/includes/search/SearchSqlite.php @@ -34,7 +34,7 @@ class SearchSqlite extends SearchDatabase { * @return bool */ private function fulltextSearchSupported() { - $dbr = $this->lb->getMaintenanceConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $sql = (string)$dbr->selectField( $dbr->addIdentifierQuotes( 'sqlite_master' ), 'sql', @@ -131,7 +131,7 @@ class SearchSqlite extends SearchDatabase { wfDebug( __METHOD__ . ": Can't understand search query '{$filteredText}'" ); } - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $searchon = $dbr->addQuotes( $searchon ); $field = $this->getIndexField( $fulltext ); @@ -191,7 +191,7 @@ class SearchSqlite extends SearchDatabase { $filteredTerm = $this->filter( MediaWikiServices::getInstance()->getContentLanguage()->lc( $term ) ); - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); // phpcs:ignore MediaWiki.Usage.DbrQueryUsage.DbrQueryFound $resultSet = $dbr->query( $this->getQuery( $filteredTerm, $fulltext ), __METHOD__ ); @@ -218,7 +218,7 @@ class SearchSqlite extends SearchDatabase { if ( $this->namespaces === [] ) { $namespaces = NS_MAIN; } else { - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $namespaces = $dbr->makeList( $this->namespaces ); } return 'AND page_namespace IN (' . $namespaces . ')'; @@ -230,9 +230,7 @@ class SearchSqlite extends SearchDatabase { * @return string */ private function limitResult( $sql ) { - $dbr = $this->lb->getConnectionRef( DB_REPLICA ); - - return $dbr->limitResult( $sql, $this->limit, $this->offset ); + return $this->dbProvider->getReplicaDatabase()->limitResult( $sql, $this->limit, $this->offset ); } /** @@ -267,7 +265,7 @@ class SearchSqlite extends SearchDatabase { */ private function queryMain( $filteredTerm, $fulltext ) { $match = $this->parseQuery( $filteredTerm, $fulltext ); - $dbr = $this->lb->getMaintenanceConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $page = $dbr->tableName( 'page' ); $searchindex = $dbr->tableName( 'searchindex' ); return "SELECT $searchindex.rowid, page_namespace, page_title " . @@ -277,7 +275,7 @@ class SearchSqlite extends SearchDatabase { private function getCountQuery( $filteredTerm, $fulltext ) { $match = $this->parseQuery( $filteredTerm, $fulltext ); - $dbr = $this->lb->getMaintenanceConnectionRef( DB_REPLICA ); + $dbr = $this->dbProvider->getReplicaDatabase(); $page = $dbr->tableName( 'page' ); $searchindex = $dbr->tableName( 'searchindex' ); return "SELECT COUNT(*) AS c " . @@ -300,7 +298,7 @@ class SearchSqlite extends SearchDatabase { } // @todo find a method to do it in a single request, // couldn't do it so far due to typelessness of FTS3 tables. - $dbw = $this->lb->getConnectionRef( DB_PRIMARY ); + $dbw = $this->dbProvider->getPrimaryDatabase(); $dbw->newDeleteQueryBuilder() ->delete( 'searchindex' ) ->where( [ 'rowid' => $id ] ) @@ -325,7 +323,7 @@ class SearchSqlite extends SearchDatabase { return; } - $dbw = $this->lb->getConnectionRef( DB_PRIMARY ); + $dbw = $this->dbProvider->getPrimaryDatabase(); $dbw->newUpdateQueryBuilder() ->update( 'searchindex' ) ->set( [ 'si_title' => $title ] ) diff --git a/tests/phpunit/includes/search/SearchEngineTest.php b/tests/phpunit/includes/search/SearchEngineTest.php index 0186a7af5c9..b82c894d057 100644 --- a/tests/phpunit/includes/search/SearchEngineTest.php +++ b/tests/phpunit/includes/search/SearchEngineTest.php @@ -1,7 +1,6 @@ markTestSkipped( "MySQL or SQLite with FTS3 only" ); } + $dbProvider = $this->getServiceContainer()->getDBLoadBalancerFactory(); - $searchType = SearchEngineFactory::getSearchEngineClass( $this->db ); + $searchType = SearchEngineFactory::getSearchEngineClass( $dbProvider ); $this->overrideConfigValues( [ MainConfigNames::SearchType => $searchType, MainConfigNames::CapitalLinks => true, @@ -42,8 +42,7 @@ class SearchEngineTest extends MediaWikiLangTestCase { ], ] ); - $lb = LoadBalancerSingle::newFromConnection( $this->db ); - $this->search = new $searchType( $lb ); + $this->search = new $searchType( $dbProvider ); $this->search->setHookContainer( $this->getServiceContainer()->getHookContainer() ); }