search: Make DB-backed search engines use ICP instead of LB/LBF
Bug: T330641 Change-Id: I5eff8865d77bbcca78b891a440fdde9f312a013c
This commit is contained in:
parent
0c01872114
commit
5eae1de53f
8 changed files with 43 additions and 57 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -1857,7 +1857,7 @@ return [
|
|||
return new SearchEngineFactory(
|
||||
$services->getSearchEngineConfig(),
|
||||
$services->getHookContainer(),
|
||||
$services->getDBLoadBalancer()
|
||||
$services->getDBLoadBalancerFactory()
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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':
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ] )
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\MainConfigNames;
|
||||
use Wikimedia\Rdbms\LoadBalancerSingle;
|
||||
|
||||
/**
|
||||
* @group Search
|
||||
|
|
@ -32,8 +31,9 @@ class SearchEngineTest extends MediaWikiLangTestCase {
|
|||
if ( !$dbSupported ) {
|
||||
$this->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() );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue