Ladsgroup has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/405535 )
Change subject: Introduce SqlScoreLookup and use it in API ...................................................................... Introduce SqlScoreLookup and use it in API This will be used in redesigned RecentChange_save hook handler Bug: T181335 Change-Id: Ic06d6fbc0a26d1381e4d3c1dee4f688b1dd4ef2f --- M includes/Hooks/ApiHooksHandler.php A includes/Storage/SqlScoreLookup.php A tests/phpunit/includes/Storage/SqlScoreLookupTest.php 3 files changed, 138 insertions(+), 14 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ORES refs/changes/35/405535/1 diff --git a/includes/Hooks/ApiHooksHandler.php b/includes/Hooks/ApiHooksHandler.php index 02f3b33..755c32d 100644 --- a/includes/Hooks/ApiHooksHandler.php +++ b/includes/Hooks/ApiHooksHandler.php @@ -35,6 +35,7 @@ use ORES\FetchScoreJob; use ORES\Parser\ScoreParser; use ORES\ScoreFetcher; +use ORES\Storage\SqlScoreLookup; use ORES\WatchedItemQueryServiceExtension; use RequestContext; use Title; @@ -260,26 +261,19 @@ $needsContinuation = false; $scores = []; - $modelData = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' ) - ->getModels(); + $modelLookup = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' ); $models = []; - foreach ( $modelData as $modelName => $modelDatum ) { + foreach ( $modelLookup->getModels() as $modelName => $modelDatum ) { $models[$modelDatum['id']] = $modelName; } // Load cached score data - $dbr = \wfGetDB( DB_REPLICA ); - $res2 = $dbr->select( - [ 'ores_classification' ], - [ 'oresc_rev', 'oresc_class', 'oresc_probability', 'oresc_model' ], - [ - 'oresc_rev' => $revids, - 'oresc_model' => array_keys( $models ), - ], - __METHOD__ + $scoreLookup = new SqlScoreLookup( + $modelLookup, + MediaWikiServices::getInstance()->getDBLoadBalancer() ); - foreach ( $res2 as $row ) { + foreach ( $scoreLookup->getScores( $revids, array_values( $models ) ) as $row ) { $scores[$row->oresc_rev][] = $row; } @@ -289,7 +283,7 @@ $revids = array_diff( $revids, array_keys( $scores ) ); if ( $revids && $wgOresRevisionsPerBatch ) { // To limit data size, only scores for revisions still in RC will be cached in DB. - $cacheableRevids = $dbr->selectFieldValues( + $cacheableRevids = wfGetDB( DB_REPLICA )->selectFieldValues( [ 'recentchanges' ], 'rc_this_oldid', [ diff --git a/includes/Storage/SqlScoreLookup.php b/includes/Storage/SqlScoreLookup.php new file mode 100644 index 0000000..90a9545 --- /dev/null +++ b/includes/Storage/SqlScoreLookup.php @@ -0,0 +1,70 @@ +<?php +/** + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +namespace ORES\Storage; + +use ORES\ScoreLookup; +use Wikimedia\Rdbms\LoadBalancer; +use Wikimedia\Rdbms\ResultWrapper; + +class SqlScoreLookup implements ScoreLookup { + + private $modelLookup; + + private $loadBalancer; + + public function __construct( + ModelLookup $modelLookup, + LoadBalancer $loadBalancer + ) { + $this->modelLookup = $modelLookup; + $this->loadBalancer = $loadBalancer; + } + + /** + * Method to retrieve scores of given revision and models + * + * @param int|array $revisions Single or multiple revisions + * @param string|array|null $models Single or multiple model names. If + * left empty, all configured models are queried. + * @param bool $precache either the request is made for precaching or not + * + * @todo This method return scores in a syntax that is different than the other implementations + * Either they should implement different interfaces or make the other one return a parsed + * output + * + * @return ResultWrapper + */ + public function getScores( $revisions, $models = null, $precache = false ) { + if ( !$models ) { + global $wgOresModels; + $models = array_keys( array_filter( $wgOresModels ) ); + } + + $models = array_map( [ $this->modelLookup, 'getModelId' ], $models ); + + return $this->loadBalancer->getConnection( DB_REPLICA )->select( + [ 'ores_classification' ], + [ 'oresc_rev', 'oresc_class', 'oresc_probability', 'oresc_model' ], + [ + 'oresc_rev' => $revisions, + 'oresc_model' => $models, + ], + __METHOD__ + ); + } + +} diff --git a/tests/phpunit/includes/Storage/SqlScoreLookupTest.php b/tests/phpunit/includes/Storage/SqlScoreLookupTest.php new file mode 100644 index 0000000..79faa16 --- /dev/null +++ b/tests/phpunit/includes/Storage/SqlScoreLookupTest.php @@ -0,0 +1,60 @@ +<?php + +namespace ORES\Tests\Storage; + +use MediaWiki\MediaWikiServices; +use MediaWikiLangTestCase; +use ORES\Storage\HashModelLookup; +use ORES\Storage\SqlScoreLookup; +use ORES\Tests\TestHelper; + +/** + * @group ORES + * @group Database + * @covers ORES\Storage\SqlScoreLookup + */ +class SqlScoreLookupTest extends MediaWikiLangTestCase { + + protected function setUp() { + parent::setUp(); + $this->tablesUsed[] = 'ores_classification'; + } + + /** + * @covers ORES\Storage\SqlScoreLookup::getScores + */ + public function testGetScores() { + $modelData = [ + 'damaging' => [ 'id' => 5, 'version' => '0.0.2' ], + 'goodfaith' => [ 'id' => 6, 'version' => '0.0.3' ], + ]; + $this->setService( 'ORESModelLookup', new HashModelLookup( $modelData ) ); + TestHelper::insertOresData( 123, [ 'damaging' => 0.45, 'goodfaith' => 0.6 ] ); + TestHelper::insertOresData( 223, [ 'damaging' => 0.666, 'goodfaith' => 0.7 ] ); + $storage = new SqlScoreLookup( + new HashModelLookup( $modelData ), + MediaWikiServices::getInstance()->getDBLoadBalancer() + ); + + $expected = [ + (object)[ + 'oresc_rev' => 123, + 'oresc_class' => 1, + 'oresc_probability' => 0.45, + 'oresc_model' => 5, + ], + (object)[ + 'oresc_rev' => 123, + 'oresc_class' => 1, + 'oresc_probability' => 0.6, + 'oresc_model' => 6, + ] + ]; + $actual = iterator_to_array( + $storage->getScores( 123, [ 'damaging', 'goodfaith' ] ), + false + ); + $this->assertEquals( $expected, $actual ); + } + +} -- To view, visit https://gerrit.wikimedia.org/r/405535 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ic06d6fbc0a26d1381e4d3c1dee4f688b1dd4ef2f Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/ORES Gerrit-Branch: master Gerrit-Owner: Ladsgroup <ladsgr...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits