37private array $virtualDBs;
38privatestring|
false $currentDomain;
52 parent::__construct( $queryModule->
getMain(), $moduleName, $paramPrefix );
53 $this->mQueryModule = $queryModule;
55 $this->virtualDBs = [];
56 $this->currentDomain =
false;
60 /***************************************************************************/ 61// region Methods to implement 93// endregion -- end of methods to implement 95 /***************************************************************************/ 104return $this->mQueryModule;
120if ( $this->currentDomain ) {
121if ( !isset( $this->virtualDBs[$this->currentDomain] ) ) {
123 ->getConnectionProvider()
124 ->getReplicaDatabase( $this->currentDomain );
125 $this->virtualDBs[$this->currentDomain] = $db;
127return $this->virtualDBs[$this->currentDomain];
130 $this->mDb ??= $this->
getQuery()->getDB();
142 $this->currentDomain = $virtualDomain;
143 $this->updateQueryBuilderConnection();
152 $this->currentDomain =
false;
153 $this->updateQueryBuilderConnection();
156privatefunction updateQueryBuilderConnection() {
157if ( $this->queryBuilder ) {
158 $this->queryBuilder->connection( $this->
getDB() );
168return $this->
getQuery()->getPageSet();
171// endregion -- end of data access 173 /***************************************************************************/ 181 $this->queryBuilder =
null;
193 $this->queryBuilder ??= $this->
getDB()->newSelectQueryBuilder();
194return $this->queryBuilder;
205if ( is_array( $tables ) ) {
206if ( $alias !==
null ) {
224if ( !is_array( $join_conds ) ) {
268if ( is_array( $value ) ) {
269// Double check: don't insert empty arrays, 270// Database::makeList() chokes on them 271if ( count( $value ) ) {
305if ( $value !==
null && !( is_array( $value ) && !$value ) ) {
332// Use count() to its full documented capabilities to simultaneously 333// test for null, empty array or empty countable object 334if ( count( $ids ) ) {
335 $ids = $this->
filterIDs( [ [ $table, $field ] ], $ids );
338// Return nothing, no IDs are valid 360 $isDirNewer = ( $dir ===
'newer' );
361 $after = ( $isDirNewer ?
'>=' :
'<=' );
362 $before = ( $isDirNewer ?
'<=' :
'>=' );
363 $db = $this->
getDB();
365if ( $start !==
null ) {
366 $this->
addWhere( $db->expr( $field, $after, $start ) );
370 $this->
addWhere( $db->expr( $field, $before, $end ) );
374 $this->
getQueryBuilder()->orderBy( $field, $isDirNewer ?
null :
'DESC' );
389 $db = $this->
getDB();
391 $db->timestampOrNull( $start ), $db->timestampOrNull( $end ), $sort );
421protectedfunctionselect( $method, $extraQuery = [], ?array &$hookData =
null ) {
423if ( isset( $extraQuery[
'tables'] ) ) {
424 $queryBuilder->
rawTables( (array)$extraQuery[
'tables'] );
426if ( isset( $extraQuery[
'fields'] ) ) {
427 $queryBuilder->
fields( (array)$extraQuery[
'fields'] );
429if ( isset( $extraQuery[
'where'] ) ) {
430 $queryBuilder->
where( (array)$extraQuery[
'where'] );
432if ( isset( $extraQuery[
'options'] ) ) {
433 $queryBuilder->
options( (array)$extraQuery[
'options'] );
435if ( isset( $extraQuery[
'join_conds'] ) ) {
436 $queryBuilder->
joinConds( (array)$extraQuery[
'join_conds'] );
439if ( $hookData !==
null && $this->
getHookContainer()->isRegistered(
'ApiQueryBaseBeforeQuery' ) ) {
442 $this, $info[
'tables'], $info[
'fields'], $info[
'conds'],
443 $info[
'options'], $info[
'join_conds'], $hookData
445 $queryBuilder = $this->
getDB()->newSelectQueryBuilder()->
queryInfo( $info );
448 $queryBuilder->
caller( $method );
451if ( $hookData !==
null ) {
452 $this->
getHookRunner()->onApiQueryBaseAfterQuery( $this, $res, $hookData );
471protectedfunctionprocessRow( $row, array &$data, array &$hookData ) {
472return $this->
getHookRunner()->onApiQueryBaseProcessRow( $this, $row, $data, $hookData );
475// endregion -- end of querying 477 /***************************************************************************/ 478// region Utility methods 489 $arr[$prefix .
'ns'] = $title->getNamespace();
490 $arr[$prefix .
'title'] = $title->getPrefixedText();
503return $result->addValue( [
'query',
'pages', (
int)$pageId ],
518 $fit = $result->addValue( [
'query',
'pages', $pageId,
523 $result->addIndexedTagName(
551 $t = Title::makeTitleSafe( $namespace, $titlePart .
'x' );
552if ( !$t || $t->hasFragment() ) {
553// Invalid title (e.g. bad chars) or contained a '#'. 556if ( $namespace != $t->getNamespace() || $t->isExternal() ) {
557// This can happen in two cases. First, if you call titlePartToKey with a title part 558// that looks like a namespace, but with $defaultNamespace = NS_MAIN. It would be very 559// difficult to handle such a case. Such cases cannot exist and are therefore treated 560// as invalid user input. The second case is when somebody specifies a title interwiki 565return substr( $t->getDBkey(), 0, -1 );
579 $t = $titleParser->parseTitle( $titlePart .
'X', $defaultNamespace );
584if ( !$t || $t->hasFragment() || $t->isExternal() || $t->getDBkey() ===
'X' ) {
585// Invalid title (e.g. bad chars) or contained a '#'. 589returnnewTitleValue( $t->getNamespace(), substr( $t->getDBkey(), 0, -1 ) );
597return (
bool)preg_match(
'/^[a-f0-9]{40}$/', $hash );
605return (
bool)preg_match(
'/^[a-z0-9]{31}$/', $hash );
640if ( !$services->getContentLanguage()->needsGenderDistinction() ) {
644 $nsInfo = $services->getNamespaceInfo();
645 $namespaceField = $fieldPrefix .
'_namespace';
646 $titleField = $fieldPrefix .
'_title';
649foreach ( $res as $row ) {
650if ( $nsInfo->hasGenderDistinction( $row->$namespaceField ) ) {
651 $usernames[] = $row->$titleField;
655if ( $usernames === [] ) {
659 $genderCache = $services->getGenderCache();
660 $genderCache->doQuery( $usernames, $fname );
663// endregion -- end of utility methods 667class_alias( ApiQueryBase::class,
'ApiQueryBase' );
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
This abstract class implements many basic API functions, and is the base of all API classes.
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
getModuleName()
Get the name of the module being executed by this instance.
getHookRunner()
Get an ApiHookRunner for running core API hooks.
getMain()
Get the main module.
getResult()
Get the result object.
filterIDs( $fields, array $ids)
Filter out-of-range values from a list of positive integer IDs.
static dieDebug( $method, $message)
Internal code errors should be reported with this method.
getHookContainer()
Get a HookContainer, for running extension hooks or for hook metadata.
This is a base class for all Query modules.
addOption( $name, $value=null)
Add an option such as LIMIT or USE INDEX.
getParent()
Get the parent of this module.to override 1.25 ApiBase|null
addFieldsIf( $value, $condition)
Same as addFields(), but add the fields only if a condition is met.
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
addWhereIf( $value, $condition)
Same as addWhere(), but add the WHERE clauses only if a condition is met.
addPageSubItems( $pageId, $data)
Add a sub-element under the page element with the given page ID.
validateSha1Base36Hash( $hash)
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
addPageSubItem( $pageId, $item, $elemname=null)
Same as addPageSubItems(), but one element of $data at a time.
addJoinConds( $join_conds)
Add a set of JOIN conditions to the internal array.
addWhereIDsFld( $table, $field, $ids)
Like addWhereFld for an integer list of IDs.
resetVirtualDomain()
Reset the virtual domain to the main database.
setVirtualDomain(string|false $virtualDomain)
Set the Query database connection (read-only)
getDB()
Get the Query database connection (read-only).
requestExtraData( $pageSet)
Override this method to request extra fields from the pageSet using $pageSet->requestField('fieldName...
select( $method, $extraQuery=[], ?array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
titlePartToKey( $titlePart, $namespace=NS_MAIN)
Convert an input title or title prefix into a dbkey.
addWhere( $value)
Add a set of WHERE clauses to the internal array.
executeGenderCacheFromResultWrapper(IResultWrapper $res, $fname=__METHOD__, $fieldPrefix='page')
Preprocess the result set to fill the GenderCache with the necessary information before using self::a...
parsePrefixedTitlePart( $titlePart, $defaultNamespace=NS_MAIN)
Convert an input title or title prefix into a TitleValue.
getPageSet()
Get the PageSet object to work on.
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getQuery()
Get the main Query module.
addTimestampWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, similar to addWhereRange, but converts $start and $end t...
getQueryBuilder()
Get the SelectQueryBuilder.
userCanSeeRevDel()
Check whether the current user has permission to view revision-deleted fields.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
processRow( $row, array &$data, array &$hookData)
Call the ApiQueryBaseProcessRow hook.
resetQueryParams()
Blank the internal arrays with query parameters.
__construct(ApiQuery $queryModule, string $moduleName, $paramPrefix='')
addWhereFld( $field, $value)
Equivalent to addWhere( [ $field => $value ] )
addFields( $value)
Add a set of fields to select to the internal array.
addWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, and an ORDER BY clause to sort in the right direction.
This is the main query class.
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
Represents the target of a wiki link.
Represents a title within MediaWiki.
Build SELECT queries with a fluent interface.
getQueryInfo( $joinsName='join_conds')
Get an associative array describing the query in terms of its raw parameters to IReadableDatabase::se...
rawTables( $tables)
Given a table or table array as might be passed to IReadableDatabase::select(), append it to the exis...
fetchResultSet()
Run the constructed SELECT query and return all results.
queryInfo( $info)
Set the query parameters to the given values, appending to the values which were already set.
options(array $options)
Manually set multiple options in the $options array to be passed to IReadableDatabase::select().
caller( $fname)
Set the method name to be included in an SQL comment.
joinConds(array $joinConds)
Manually append to the $join_conds array which will be passed to IReadableDatabase::select().
fields( $fields)
Add a field or an array of fields to the query.
where( $conds)
Add conditions to the query.
trait ApiQueryBlockInfoTrait
Interface to a relational database.
A database connection without write operations.
Result wrapper for grabbing data queried from an IDatabase object.
numRows()
Get the number of rows in a result object.