loadBalancer = $loadBalancer; } /** * Get a preloaded Category object or null when the Category does not exists. Loaded the Category on demand, * if not in cache, use self::doQuery when requesting a high number of category */ public function getCategory( LinkTarget $categoryTarget ): ?Category { if ( $categoryTarget->getNamespace() !== NS_CATEGORY ) { return null; } $categoryDbKey = $categoryTarget->getDBkey(); if ( !array_key_exists( $categoryDbKey, $this->cache ) ) { $this->doQuery( [ $categoryTarget ] ); } return $this->cache[$categoryDbKey]; } /** * Preloads category counts in this cache * @param LinkTarget[] $linkTargets */ public function doQuery( array $linkTargets ): void { $categoryDbKeys = []; foreach ( $linkTargets as $linkTarget ) { if ( $linkTarget->getNamespace() !== NS_CATEGORY ) { continue; } $categoryDbKey = $linkTarget->getDBkey(); if ( !array_key_exists( $categoryDbKey, $this->cache ) ) { $categoryDbKeys[] = $categoryDbKey; // To cache db misses, also avoid duplicates in the db query $this->cache[$categoryDbKey] = null; } } if ( $categoryDbKeys === [] ) { return; } $rows = $this->loadBalancer->getConnection( ILoadBalancer::DB_REPLICA ) ->newSelectQueryBuilder() ->select( [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ] ) ->from( 'category' ) ->where( [ 'cat_title' => $categoryDbKeys ] ) ->caller( __METHOD__ ) ->fetchResultSet(); $this->fillFromQuery( $rows ); } public function fillFromQuery( IResultWrapper $rows ): void { foreach ( $rows as $row ) { $this->cache[$row->cat_title] = Category::newFromRow( $row ); } } }