Mailing List Archive

[MediaWiki-commits] [Gerrit] mediawiki...ORES[master]: Introduce SqlScoreLookup and use it in API
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 <Ladsgroup@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
[MediaWiki-commits] [Gerrit] mediawiki...ORES[master]: Introduce SqlScoreLookup and use it in API [ In reply to ]
jenkins-bot has submitted this change and it was merged. ( 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
M includes/ServiceWiring.php
A includes/Storage/SqlScoreLookup.php
M tests/phpunit/includes/ServiceWiringTest.php
A tests/phpunit/includes/Storage/SqlScoreLookupTest.php
5 files changed, 147 insertions(+), 15 deletions(-)

Approvals:
jenkins-bot: Verified
Awight: Looks good to me, approved



diff --git a/includes/Hooks/ApiHooksHandler.php b/includes/Hooks/ApiHooksHandler.php
index 02f3b33..c457021 100644
--- a/includes/Hooks/ApiHooksHandler.php
+++ b/includes/Hooks/ApiHooksHandler.php
@@ -260,26 +260,18 @@
$needsContinuation = false;
$scores = [];

- $modelData = MediaWikiServices::getInstance()->getService( 'ORESModelLookup' )
- ->getModels();
+ $services = MediaWikiServices::getInstance();
+ $modelLookup = $services->getService( 'ORESModelLookup' );
+ $scoreLookup = $services->getService( 'OREScoreLookup' );

$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__
- );
- foreach ( $res2 as $row ) {
+ $dbResult = $scoreLookup->getScores( $revids, array_values( $models ) );
+ foreach ( $dbResult as $row ) {
$scores[$row->oresc_rev][] = $row;
}

@@ -289,7 +281,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/ServiceWiring.php b/includes/ServiceWiring.php
index 552139f..4a741cd 100644
--- a/includes/ServiceWiring.php
+++ b/includes/ServiceWiring.php
@@ -19,6 +19,7 @@
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
use ORES\Storage\SqlModelLookup;
+use ORES\Storage\SqlScoreLookup;
use ORES\Storage\SqlScoreStorage;

return [.
@@ -50,4 +51,11 @@
);
},

+ 'OREScoreLookup' => function ( MediaWikiServices $services ) {
+ return new SqlScoreLookup(
+ $services->getService( 'ORESModelLookup' ),
+ $services->getDBLoadBalancer()
+ );
+ },
+
];
diff --git a/includes/Storage/SqlScoreLookup.php b/includes/Storage/SqlScoreLookup.php
new file mode 100644
index 0000000..0ef9505
--- /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 ) );
+ }
+
+ $modelIds = 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' => $modelIds,
+ ],
+ __METHOD__
+ );
+ }
+
+}
diff --git a/tests/phpunit/includes/ServiceWiringTest.php b/tests/phpunit/includes/ServiceWiringTest.php
index f430584..9aef256 100644
--- a/tests/phpunit/includes/ServiceWiringTest.php
+++ b/tests/phpunit/includes/ServiceWiringTest.php
@@ -6,6 +6,7 @@
use ORES\ORESService;
use ORES\Storage\ModelLookup;
use ORES\Storage\ScoreStorage;
+use ORES\Storage\SqlScoreLookup;
use ORES\ThresholdLookup;

/**
@@ -21,6 +22,7 @@
[ 'ORESThresholdLookup', ThresholdLookup::class ],
[ 'ORESScoreStorage', ScoreStorage::class ],
[ 'ORESService', ORESService::class ],
+ [ 'OREScoreLookup', SqlScoreLookup::class ],
];
}

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: merged
Gerrit-Change-Id: Ic06d6fbc0a26d1381e4d3c1dee4f688b1dd4ef2f
Gerrit-PatchSet: 2
Gerrit-Project: mediawiki/extensions/ORES
Gerrit-Branch: master
Gerrit-Owner: Ladsgroup <Ladsgroup@gmail.com>
Gerrit-Reviewer: Awight <awight@wikimedia.org>
Gerrit-Reviewer: Ladsgroup <Ladsgroup@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits