Aude has uploaded a new change for review.
https://gerrit.wikimedia.org/r/188965
Change subject: Split SiteLookup interface from SiteStore
......................................................................
Split SiteLookup interface from SiteStore
* SiteLookup interface is added, and SiteStore extends
it. (any SiteStore type hints can be changed to use
SiteLookup if all they need is lookup functionality)
* Memcached based SiteStore code is split from the
database SiteStore, and SiteSQLStore is deprecated.
If no caching is desired when using a SiteStore, then
use a SiteDBStore instance, instead of passing $source
parameter in SiteStore::getSite and SiteStore::getSites.
* SiteListFileCache renamed to FileBasedSiteLookup and
implements SiteLookup, and SitesListFileCacheBuilder
to SitesFileCacheBuilder.
* Renamed config sites cache setting, from wgSitesCacheFile
to wgSitesFileCache, for more naming consistency.
Bug: T77990
Change-Id: I36b599884c211580ea6806a8a190c65c4f9087cf
---
M autoload.php
M includes/DefaultSettings.php
A includes/site/CachingSiteStore.php
R includes/site/FileBasedSiteLookup.php
A includes/site/SiteDBStore.php
A includes/site/SiteLookup.php
M includes/site/SiteSQLStore.php
M includes/site/SiteStore.php
R includes/site/SitesFileCacheBuilder.php
R maintenance/rebuildSitesFileCache.php
C tests/phpunit/includes/site/CachingSiteStoreTest.php
R tests/phpunit/includes/site/FileBasedSiteLookupTest.php
R tests/phpunit/includes/site/SiteDBStoreTest.php
R tests/phpunit/includes/site/SitesFileCacheBuilderTest.php
M tests/phpunit/includes/site/TestSites.php
15 files changed, 662 insertions(+), 470 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/65/188965/1
diff --git a/autoload.php b/autoload.php
index 90cd074..5868989 100644
--- a/autoload.php
+++ b/autoload.php
@@ -185,6 +185,7 @@
'CacheHelper' => __DIR__ . '/includes/cache/CacheHelper.php',
'CacheTime' => __DIR__ . '/includes/parser/CacheTime.php',
'CachedAction' => __DIR__ . '/includes/actions/CachedAction.php',
+ 'CachingSiteStore' => __DIR__ . '/includes/site/CachingSiteStore.php',
'CapsCleanup' => __DIR__ . '/maintenance/cleanupCaps.php',
'Category' => __DIR__ . '/includes/Category.php',
'CategoryFinder' => __DIR__ . '/includes/CategoryFinder.php',
@@ -413,6 +414,7 @@
'FileBackendStoreShardDirIterator' => __DIR__ .
'/includes/filebackend/FileBackendStore.php',
'FileBackendStoreShardFileIterator' => __DIR__ .
'/includes/filebackend/FileBackendStore.php',
'FileBackendStoreShardListIterator' => __DIR__ .
'/includes/filebackend/FileBackendStore.php',
+ 'FileBasedSiteLookup' => __DIR__ .
'/includes/site/FileBasedSiteLookup.php',
'FileCacheBase' => __DIR__ . '/includes/cache/FileCacheBase.php',
'FileDeleteForm' => __DIR__ . '/includes/FileDeleteForm.php',
'FileDependency' => __DIR__ . '/includes/cache/CacheDependency.php',
@@ -936,7 +938,7 @@
'RebuildLocalisationCache' => __DIR__ .
'/maintenance/rebuildLocalisationCache.php',
'RebuildMessages' => __DIR__ . '/maintenance/rebuildmessages.php',
'RebuildRecentchanges' => __DIR__ .
'/maintenance/rebuildrecentchanges.php',
- 'RebuildSitesCache' => __DIR__ . '/maintenance/rebuildSitesCache.php',
+ 'RebuildSitesFileCache' => __DIR__ .
'/maintenance/rebuildSitesFileCache.php',
'RebuildTextIndex' => __DIR__ . '/maintenance/rebuildtextindex.php',
'RecentChange' => __DIR__ . '/includes/changes/RecentChange.php',
'RecompressTracked' => __DIR__ .
'/maintenance/storage/recompressTracked.php',
@@ -1047,15 +1049,16 @@
'Site' => __DIR__ . '/includes/site/Site.php',
'SiteArray' => __DIR__ . '/includes/site/SiteList.php',
'SiteConfiguration' => __DIR__ . '/includes/SiteConfiguration.php',
+ 'SiteDBStore' => __DIR__ . '/includes/site/SiteDBStore.php',
'SiteList' => __DIR__ . '/includes/site/SiteList.php',
- 'SiteListFileCache' => __DIR__ . '/includes/site/SiteListFileCache.php',
- 'SiteListFileCacheBuilder' => __DIR__ .
'/includes/site/SiteListFileCacheBuilder.php',
+ 'SiteLookup' => __DIR__ . '/includes/site/SiteLookup.php',
'SiteObject' => __DIR__ . '/includes/site/Site.php',
'SiteSQLStore' => __DIR__ . '/includes/site/SiteSQLStore.php',
'SiteStats' => __DIR__ . '/includes/SiteStats.php',
'SiteStatsInit' => __DIR__ . '/includes/SiteStats.php',
'SiteStatsUpdate' => __DIR__ . '/includes/deferred/SiteStatsUpdate.php',
'SiteStore' => __DIR__ . '/includes/site/SiteStore.php',
+ 'SitesFileCacheBuilder' => __DIR__ .
'/includes/site/SitesFileCacheBuilder.php',
'Skin' => __DIR__ . '/includes/skins/Skin.php',
'SkinApi' => __DIR__ . '/includes/skins/SkinApi.php',
'SkinApiTemplate' => __DIR__ . '/includes/skins/SkinApiTemplate.php',
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 7bd80c4..fdf8583 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -3781,9 +3781,9 @@
*/
/**
- * Specify the file location for the SiteStore json cache file.
+ * Specify the file location for the Sites json cache file.
*/
-$wgSitesCacheFile = false;
+$wgSitesFileCache = false;
/** @} */ # end of SiteStore caching settings.
diff --git a/includes/site/CachingSiteStore.php
b/includes/site/CachingSiteStore.php
new file mode 100644
index 0000000..4d983e8
--- /dev/null
+++ b/includes/site/CachingSiteStore.php
@@ -0,0 +1,187 @@
+<?php
+
+/**
+ * Represents the site configuration of a wiki.
+ * Holds a list of sites (ie SiteList), with a caching layer.
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.25
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @license GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ * @author Katie Filbert < [email protected] >
+ */
+class CachingSiteStore implements SiteStore {
+
+ /**
+ * @var SiteList|null
+ */
+ private $sites = null;
+
+ /**
+ * @var string|null
+ */
+ private $cacheKey = null;
+
+ /**
+ * @var int
+ */
+ private $cacheTimeout = 3600;
+
+ /**
+ * @var BagOStuff
+ */
+ private $cache;
+
+ /**
+ * @var SiteStore
+ */
+ private $siteStore;
+
+ /**
+ * @param SiteStore $siteStore
+ * @param BagOStuff $cache
+ */
+ public function __construct( SiteStore $siteStore, BagOStuff $cache ) {
+ $this->siteStore = $siteStore;
+ $this->cache = $cache;
+ }
+
+ /**
+ * Constructs a cache key to use for caching the list of sites.
+ *
+ * This includes the concrete class name of the site list as well as a
version identifier
+ * for the list's serialization, to avoid problems when unserializing
site lists serialized
+ * by an older version, e.g. when reading from a cache.
+ *
+ * The cache key also includes information about where the sites were
loaded from, e.g.
+ * the name of a database table.
+ *
+ * @see SiteList::getSerialVersionId
+ *
+ * @return string The cache key.
+ */
+ private function getCacheKey() {
+ if ( $this->cacheKey === null ) {
+ $type = 'SiteList#' . SiteList::getSerialVersionId();
+ $this->cacheKey = wfMemcKey( "sites/$type" );
+ }
+
+ return $this->cacheKey;
+ }
+
+ /**
+ * @see SiteStore::getSites
+ *
+ * @since 1.25
+ *
+ * @return SiteList
+ */
+ public function getSites() {
+ if ( $this->sites === null ) {
+ $this->sites = $this->cache->get( $this->getCacheKey()
);
+
+ if ( !is_object( $this->sites ) ) {
+ $this->sites = $this->siteStore->getSites();
+
+ $this->cache->set( $this->getCacheKey(),
$this->sites, $this->cacheTimeout );
+ }
+ }
+
+ return $this->sites;
+ }
+
+ /**
+ * @see SiteStore::getSite
+ *
+ * @since 1.25
+ *
+ * @param string $globalId
+ *
+ * @return Site|null
+ */
+ public function getSite( $globalId ) {
+ $sites = $this->getSites();
+
+ return $sites->hasSite( $globalId ) ? $sites->getSite(
$globalId ) : null;
+ }
+
+ /**
+ * @see SiteStore::saveSite
+ *
+ * @since 1.25
+ *
+ * @param Site $site
+ *
+ * @return bool Success indicator
+ */
+ public function saveSite( Site $site ) {
+ return $this->saveSites( array( $site ) );
+ }
+
+ /**
+ * @see SiteStore::saveSites
+ *
+ * @since 1.25
+ *
+ * @param Site[] $sites
+ *
+ * @return bool Success indicator
+ */
+ public function saveSites( array $sites ) {
+ if ( empty( $sites ) ) {
+ return true;
+ }
+
+ $success = $this->siteStore->saveSites( $sites );
+
+ // purge cache
+ $this->reset();
+
+ return $success;
+ }
+
+ /**
+ * Purges the internal and external cache of the site list, forcing the
list
+ * of sites to be reloaded.
+ *
+ * @since 1.25
+ */
+ public function reset() {
+ // purge cache
+ $this->cache->delete( $this->getCacheKey() );
+ $this->sites = null;
+
+ }
+
+ /**
+ * Clears the list of sites stored.
+ *
+ * @see SiteStore::clear()
+ *
+ * @return bool Success
+ */
+ public function clear() {
+ $this->reset();
+
+ return $this->siteStore->clear();
+ }
+
+}
diff --git a/includes/site/SiteListFileCache.php
b/includes/site/FileBasedSiteLookup.php
similarity index 96%
rename from includes/site/SiteListFileCache.php
rename to includes/site/FileBasedSiteLookup.php
index e48a187..03121f8 100644
--- a/includes/site/SiteListFileCache.php
+++ b/includes/site/FileBasedSiteLookup.php
@@ -24,11 +24,11 @@
* Provides a file-based cache of a SiteStore, stored as a json file.
* The cache can be built with the rebuildSitesCache.php maintenance script,
* and a MediaWiki instance can be setup to use this by setting the
- * 'wgSitesCacheFile' configuration to the cache file location.
+ * 'wgSitesFileCache' configuration to the cache file location.
*
* @since 1.25
*/
-class SiteListFileCache {
+class FileBasedSiteLookup implements SiteLookup {
/**
* @var SiteList
diff --git a/includes/site/SiteDBStore.php b/includes/site/SiteDBStore.php
new file mode 100644
index 0000000..315c396
--- /dev/null
+++ b/includes/site/SiteDBStore.php
@@ -0,0 +1,345 @@
+<?php
+
+/**
+ * Represents the site configuration of a wiki.
+ * Holds a list of sites (ie SiteList), stored in the database.
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.25
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @license GNU GPL v2+
+ * @author Jeroen De Dauw < [email protected] >
+ */
+class SiteDBStore implements SiteStore {
+
+ /**
+ * @var SiteList|null
+ */
+ protected $sites = null;
+
+ /**
+ * @var ORMTable
+ */
+ protected $sitesTable;
+
+ /**
+ * @since 1.25
+ *
+ * @param ORMTable|null $sitesTable
+ */
+ public function __construct( ORMTable $sitesTable = null ) {
+ if ( $sitesTable === null ) {
+ $sitesTable = $this->newSitesTable();
+ }
+
+ $this->sitesTable = $sitesTable;
+ }
+
+ /**
+ * @see SiteStore::getSites
+ *
+ * @since 1.25
+ *
+ * @return SiteList
+ */
+ public function getSites() {
+ $this->loadSites();
+
+ return $this->sites;
+ }
+
+ /**
+ * Returns a new Site object constructed from the provided ORMRow.
+ *
+ * @since 1.25
+ *
+ * @param ORMRow $siteRow
+ *
+ * @return Site
+ */
+ protected function siteFromRow( ORMRow $siteRow ) {
+
+ $site = Site::newForType( $siteRow->getField( 'type',
Site::TYPE_UNKNOWN ) );
+
+ $site->setGlobalId( $siteRow->getField( 'global_key' ) );
+
+ $site->setInternalId( $siteRow->getField( 'id' ) );
+
+ if ( $siteRow->hasField( 'forward' ) ) {
+ $site->setForward( $siteRow->getField( 'forward' ) );
+ }
+
+ if ( $siteRow->hasField( 'group' ) ) {
+ $site->setGroup( $siteRow->getField( 'group' ) );
+ }
+
+ if ( $siteRow->hasField( 'language' ) ) {
+ $site->setLanguageCode( $siteRow->getField( 'language'
) === ''
+ ? null
+ : $siteRow->getField( 'language' )
+ );
+ }
+
+ if ( $siteRow->hasField( 'source' ) ) {
+ $site->setSource( $siteRow->getField( 'source' ) );
+ }
+
+ if ( $siteRow->hasField( 'data' ) ) {
+ $site->setExtraData( $siteRow->getField( 'data' ) );
+ }
+
+ if ( $siteRow->hasField( 'config' ) ) {
+ $site->setExtraConfig( $siteRow->getField( 'config' ) );
+ }
+
+ return $site;
+ }
+
+ /**
+ * Get a new ORMRow from a Site object
+ *
+ * @since 1.25
+ *
+ * @param Site $site
+ *
+ * @return ORMRow
+ */
+ protected function getRowFromSite( Site $site ) {
+ $fields = array(
+ // Site data
+ 'global_key' => $site->getGlobalId(), // TODO: check
not null
+ 'type' => $site->getType(),
+ 'group' => $site->getGroup(),
+ 'source' => $site->getSource(),
+ 'language' => $site->getLanguageCode() === null ? '' :
$site->getLanguageCode(),
+ 'protocol' => $site->getProtocol(),
+ 'domain' => strrev( $site->getDomain() ) . '.',
+ 'data' => $site->getExtraData(),
+
+ // Site config
+ 'forward' => $site->shouldForward(),
+ 'config' => $site->getExtraConfig(),
+ );
+
+ if ( $site->getInternalId() !== null ) {
+ $fields['id'] = $site->getInternalId();
+ }
+
+ return new ORMRow( $this->sitesTable, $fields );
+ }
+
+ /**
+ * Fetches the site from the database and loads them into the sites
field.
+ *
+ * @since 1.25
+ */
+ protected function loadSites() {
+ $this->sites = new SiteList();
+
+ foreach ( $this->sitesTable->select() as $siteRow ) {
+ $this->sites[] = $this->siteFromRow( $siteRow );
+ }
+
+ // Batch load the local site identifiers.
+ $ids = wfGetDB( $this->sitesTable->getReadDb() )->select(
+ 'site_identifiers',
+ array(
+ 'si_site',
+ 'si_type',
+ 'si_key',
+ ),
+ array(),
+ __METHOD__
+ );
+
+ foreach ( $ids as $id ) {
+ if ( $this->sites->hasInternalId( $id->si_site ) ) {
+ $site = $this->sites->getSiteByInternalId(
$id->si_site );
+ $site->addLocalId( $id->si_type, $id->si_key );
+ $this->sites->setSite( $site );
+ }
+ }
+ }
+
+ /**
+ * @see SiteStore::getSite
+ *
+ * @since 1.25
+ *
+ * @param string $globalId
+ *
+ * @return Site|null
+ */
+ public function getSite( $globalId ) {
+ if ( $this->sites === null ) {
+ $this->sites = $this->getSites();
+ }
+
+ return $this->sites->hasSite( $globalId ) ?
$this->sites->getSite( $globalId ) : null;
+ }
+
+ /**
+ * @see SiteStore::saveSite
+ *
+ * @since 1.25
+ *
+ * @param Site $site
+ *
+ * @return bool Success indicator
+ */
+ public function saveSite( Site $site ) {
+ return $this->saveSites( array( $site ) );
+ }
+
+ /**
+ * @see SiteStore::saveSites
+ *
+ * @since 1.25
+ *
+ * @param Site[] $sites
+ *
+ * @return bool Success indicator
+ */
+ public function saveSites( array $sites ) {
+ if ( empty( $sites ) ) {
+ return true;
+ }
+
+ $dbw = $this->sitesTable->getWriteDbConnection();
+
+ $dbw->startAtomic( __METHOD__ );
+
+ $success = true;
+
+ $internalIds = array();
+ $localIds = array();
+
+ foreach ( $sites as $site ) {
+ if ( $site->getInternalId() !== null ) {
+ $internalIds[] = $site->getInternalId();
+ }
+
+ $siteRow = $this->getRowFromSite( $site );
+ $success = $siteRow->save( __METHOD__ ) && $success;
+
+ foreach ( $site->getLocalIds() as $idType => $ids ) {
+ foreach ( $ids as $id ) {
+ $localIds[] = array( $siteRow->getId(),
$idType, $id );
+ }
+ }
+ }
+
+ if ( $internalIds !== array() ) {
+ $dbw->delete(
+ 'site_identifiers',
+ array( 'si_site' => $internalIds ),
+ __METHOD__
+ );
+ }
+
+ foreach ( $localIds as $localId ) {
+ $dbw->insert(
+ 'site_identifiers',
+ array(
+ 'si_site' => $localId[0],
+ 'si_type' => $localId[1],
+ 'si_key' => $localId[2],
+ ),
+ __METHOD__
+ );
+ }
+
+ $dbw->endAtomic( __METHOD__ );
+
+ $this->reset();
+
+ return $success;
+ }
+
+ /**
+ * Resets the SiteList
+ *
+ * @since 1.25
+ */
+ public function reset() {
+ $this->sites = null;
+ }
+
+ /**
+ * Clears the list of sites stored in the database.
+ *
+ * @see SiteStore::clear()
+ *
+ * @return bool Success
+ */
+ public function clear() {
+ $dbw = $this->sitesTable->getWriteDbConnection();
+
+ $dbw->startAtomic( __METHOD__ );
+ $ok = $dbw->delete( 'sites', '*', __METHOD__ );
+ $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) &&
$ok;
+ $dbw->endAtomic( __METHOD__ );
+
+ $this->reset();
+
+ return $ok;
+ }
+
+ /**
+ * @since 1.25
+ *
+ * @return ORMTable
+ */
+ protected function newSitesTable() {
+ return new ORMTable(
+ 'sites',
+ array(
+ 'id' => 'id',
+
+ // Site data
+ 'global_key' => 'str',
+ 'type' => 'str',
+ 'group' => 'str',
+ 'source' => 'str',
+ 'language' => 'str',
+ 'protocol' => 'str',
+ 'domain' => 'str',
+ 'data' => 'array',
+
+ // Site config
+ 'forward' => 'bool',
+ 'config' => 'array',
+ ),
+ array(
+ 'type' => Site::TYPE_UNKNOWN,
+ 'group' => Site::GROUP_NONE,
+ 'source' => Site::SOURCE_LOCAL,
+ 'data' => array(),
+
+ 'forward' => false,
+ 'config' => array(),
+ 'language' => '',
+ ),
+ 'ORMRow',
+ 'site_'
+ );
+ }
+
+}
diff --git a/includes/site/SiteLookup.php b/includes/site/SiteLookup.php
new file mode 100644
index 0000000..610bf0b
--- /dev/null
+++ b/includes/site/SiteLookup.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Interface for service objects providing a lookup of Site objects.
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.25
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @license GNU GPL v2+
+ */
+interface SiteLookup {
+
+ /**
+ * Returns the site with provided global id, or null if there is no
such site.
+ *
+ * @since 1.25
+ *
+ * @param string $globalId
+ *
+ * @return Site|null
+ */
+ public function getSite( $globalId );
+
+ /**
+ * Returns a list of all sites.
+ *
+ * @since 1.25
+ *
+ * @return SiteList
+ */
+ public function getSites();
+
+}
diff --git a/includes/site/SiteSQLStore.php b/includes/site/SiteSQLStore.php
index 8f25c76..3e8a932 100644
--- a/includes/site/SiteSQLStore.php
+++ b/includes/site/SiteSQLStore.php
@@ -28,36 +28,11 @@
* @license GNU GPL v2+
* @author Jeroen De Dauw < [email protected] >
*/
-class SiteSQLStore implements SiteStore {
- /**
- * @since 1.21
- *
- * @var SiteList|null
- */
- protected $sites = null;
-
- /**
- * @var ORMTable
- */
- protected $sitesTable;
-
- /**
- * @var string|null
- */
- private $cacheKey = null;
-
- /**
- * @var int
- */
- private $cacheTimeout = 3600;
-
- /**
- * @var BagOStuff
- */
- private $cache;
+class SiteSQLStore extends CachingSiteStore {
/**
* @since 1.21
+ * @deprecated 1.25 Construct a SiteStore instance directly instead.
*
* @param ORMTable|null $sitesTable
* @param BagOStuff|null $cache
@@ -69,370 +44,9 @@
$cache = wfGetMainCache();
}
- return new static( $cache, $sitesTable );
- }
+ $siteStore = new SiteDBStore();
- /**
- * Constructor.
- *
- * @since 1.21
- *
- * @param BagOStuff $cache
- * @param ORMTable|null $sitesTable
- */
- protected function __construct( BagOStuff $cache, ORMTable $sitesTable
= null ) {
- if ( $sitesTable === null ) {
- $sitesTable = $this->newSitesTable();
- }
-
- $this->cache = $cache;
- $this->sitesTable = $sitesTable;
- }
-
- /**
- * Constructs a cache key to use for caching the list of sites.
- *
- * This includes the concrete class name of the site list as well as a
version identifier
- * for the list's serialization, to avoid problems when unserializing
site lists serialized
- * by an older version, e.g. when reading from a cache.
- *
- * The cache key also includes information about where the sites were
loaded from, e.g.
- * the name of a database table.
- *
- * @see SiteList::getSerialVersionId
- *
- * @return string The cache key.
- */
- protected function getCacheKey() {
-
- if ( $this->cacheKey === null ) {
- $type = 'SiteList#' . SiteList::getSerialVersionId();
- $source = $this->sitesTable->getName();
-
- if ( $this->sitesTable->getTargetWiki() !== false ) {
- $source = $this->sitesTable->getTargetWiki() .
'.' . $source;
- }
-
- $this->cacheKey = wfMemcKey( "$source/$type" );
- }
-
- return $this->cacheKey;
- }
-
- /**
- * @see SiteStore::getSites
- *
- * @since 1.21
- *
- * @param string $source Either 'cache' or 'recache'
- *
- * @return SiteList
- */
- public function getSites( $source = 'cache' ) {
-
- if ( $source === 'cache' ) {
- if ( $this->sites === null ) {
- $sites = $this->cache->get(
$this->getCacheKey() );
-
- if ( is_object( $sites ) ) {
- $this->sites = $sites;
- } else {
- $this->loadSites();
- }
- }
- }
- else {
- $this->loadSites();
- }
-
- return $this->sites;
- }
-
- /**
- * Returns a new Site object constructed from the provided ORMRow.
- *
- * @since 1.21
- *
- * @param ORMRow $siteRow
- *
- * @return Site
- */
- protected function siteFromRow( ORMRow $siteRow ) {
-
- $site = Site::newForType( $siteRow->getField( 'type',
Site::TYPE_UNKNOWN ) );
-
- $site->setGlobalId( $siteRow->getField( 'global_key' ) );
-
- $site->setInternalId( $siteRow->getField( 'id' ) );
-
- if ( $siteRow->hasField( 'forward' ) ) {
- $site->setForward( $siteRow->getField( 'forward' ) );
- }
-
- if ( $siteRow->hasField( 'group' ) ) {
- $site->setGroup( $siteRow->getField( 'group' ) );
- }
-
- if ( $siteRow->hasField( 'language' ) ) {
- $site->setLanguageCode( $siteRow->getField( 'language'
) === ''
- ? null
- : $siteRow->getField( 'language' )
- );
- }
-
- if ( $siteRow->hasField( 'source' ) ) {
- $site->setSource( $siteRow->getField( 'source' ) );
- }
-
- if ( $siteRow->hasField( 'data' ) ) {
- $site->setExtraData( $siteRow->getField( 'data' ) );
- }
-
- if ( $siteRow->hasField( 'config' ) ) {
- $site->setExtraConfig( $siteRow->getField( 'config' ) );
- }
-
- return $site;
- }
-
- /**
- * Get a new ORMRow from a Site object
- *
- * @since 1.22
- *
- * @param Site $site
- *
- * @return ORMRow
- */
- protected function getRowFromSite( Site $site ) {
- $fields = array(
- // Site data
- 'global_key' => $site->getGlobalId(), // TODO: check
not null
- 'type' => $site->getType(),
- 'group' => $site->getGroup(),
- 'source' => $site->getSource(),
- 'language' => $site->getLanguageCode() === null ? '' :
$site->getLanguageCode(),
- 'protocol' => $site->getProtocol(),
- 'domain' => strrev( $site->getDomain() ) . '.',
- 'data' => $site->getExtraData(),
-
- // Site config
- 'forward' => $site->shouldForward(),
- 'config' => $site->getExtraConfig(),
- );
-
- if ( $site->getInternalId() !== null ) {
- $fields['id'] = $site->getInternalId();
- }
-
- return new ORMRow( $this->sitesTable, $fields );
- }
-
- /**
- * Fetches the site from the database and loads them into the sites
field.
- *
- * @since 1.21
- */
- protected function loadSites() {
-
- $this->sites = new SiteList();
-
- foreach ( $this->sitesTable->select() as $siteRow ) {
- $this->sites[] = $this->siteFromRow( $siteRow );
- }
-
- // Batch load the local site identifiers.
- $ids = wfGetDB( $this->sitesTable->getReadDb() )->select(
- 'site_identifiers',
- array(
- 'si_site',
- 'si_type',
- 'si_key',
- ),
- array(),
- __METHOD__
- );
-
- foreach ( $ids as $id ) {
- if ( $this->sites->hasInternalId( $id->si_site ) ) {
- $site = $this->sites->getSiteByInternalId(
$id->si_site );
- $site->addLocalId( $id->si_type, $id->si_key );
- $this->sites->setSite( $site );
- }
- }
-
- $this->cache->set( $this->getCacheKey(), $this->sites,
$this->cacheTimeout );
-
- }
-
- /**
- * @see SiteStore::getSite
- *
- * @since 1.21
- *
- * @param string $globalId
- * @param string $source
- *
- * @return Site|null
- */
- public function getSite( $globalId, $source = 'cache' ) {
-
- $sites = $this->getSites( $source );
-
- return $sites->hasSite( $globalId ) ? $sites->getSite(
$globalId ) : null;
- }
-
- /**
- * @see SiteStore::saveSite
- *
- * @since 1.21
- *
- * @param Site $site
- *
- * @return bool Success indicator
- */
- public function saveSite( Site $site ) {
- return $this->saveSites( array( $site ) );
- }
-
- /**
- * @see SiteStore::saveSites
- *
- * @since 1.21
- *
- * @param Site[] $sites
- *
- * @return bool Success indicator
- */
- public function saveSites( array $sites ) {
-
- if ( empty( $sites ) ) {
- return true;
- }
-
- $dbw = $this->sitesTable->getWriteDbConnection();
-
- $dbw->startAtomic( __METHOD__ );
-
- $success = true;
-
- $internalIds = array();
- $localIds = array();
-
- foreach ( $sites as $site ) {
- if ( $site->getInternalId() !== null ) {
- $internalIds[] = $site->getInternalId();
- }
-
- $siteRow = $this->getRowFromSite( $site );
- $success = $siteRow->save( __METHOD__ ) && $success;
-
- foreach ( $site->getLocalIds() as $idType => $ids ) {
- foreach ( $ids as $id ) {
- $localIds[] = array( $siteRow->getId(),
$idType, $id );
- }
- }
- }
-
- if ( $internalIds !== array() ) {
- $dbw->delete(
- 'site_identifiers',
- array( 'si_site' => $internalIds ),
- __METHOD__
- );
- }
-
- foreach ( $localIds as $localId ) {
- $dbw->insert(
- 'site_identifiers',
- array(
- 'si_site' => $localId[0],
- 'si_type' => $localId[1],
- 'si_key' => $localId[2],
- ),
- __METHOD__
- );
- }
-
- $dbw->endAtomic( __METHOD__ );
-
- // purge cache
- $this->reset();
-
- return $success;
- }
-
- /**
- * Purges the internal and external cache of the site list, forcing the
list
- * of sites to be re-read from the database.
- *
- * @since 1.21
- */
- public function reset() {
- // purge cache
- $this->cache->delete( $this->getCacheKey() );
- $this->sites = null;
-
- }
-
- /**
- * Clears the list of sites stored in the database.
- *
- * @see SiteStore::clear()
- *
- * @return bool Success
- */
- public function clear() {
- $dbw = $this->sitesTable->getWriteDbConnection();
-
- $dbw->startAtomic( __METHOD__ );
- $ok = $dbw->delete( 'sites', '*', __METHOD__ );
- $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) &&
$ok;
- $dbw->endAtomic( __METHOD__ );
-
- $this->reset();
-
- return $ok;
- }
-
- /**
- * @since 1.21
- *
- * @return ORMTable
- */
- protected function newSitesTable() {
- return new ORMTable(
- 'sites',
- array(
- 'id' => 'id',
-
- // Site data
- 'global_key' => 'str',
- 'type' => 'str',
- 'group' => 'str',
- 'source' => 'str',
- 'language' => 'str',
- 'protocol' => 'str',
- 'domain' => 'str',
- 'data' => 'array',
-
- // Site config
- 'forward' => 'bool',
- 'config' => 'array',
- ),
- array(
- 'type' => Site::TYPE_UNKNOWN,
- 'group' => Site::GROUP_NONE,
- 'source' => Site::SOURCE_LOCAL,
- 'data' => array(),
-
- 'forward' => false,
- 'config' => array(),
- 'language' => '',
- ),
- 'ORMRow',
- 'site_'
- );
+ return new static( $siteStore, $cache );
}
}
diff --git a/includes/site/SiteStore.php b/includes/site/SiteStore.php
index 537f1cc..c645548 100644
--- a/includes/site/SiteStore.php
+++ b/includes/site/SiteStore.php
@@ -26,7 +26,7 @@
* @license GNU GPL v2+
* @author Jeroen De Dauw < [email protected] >
*/
-interface SiteStore {
+interface SiteStore extends SiteLookup {
/**
* Saves the provided site.
@@ -56,26 +56,19 @@
* @since 1.21
*
* @param string $globalId
- * @param string $source Either 'cache' or 'recache'.
- * If 'cache', the values are allowed (but not obliged) to come from a
cache.
*
* @return Site|null
*/
- public function getSite( $globalId, $source = 'cache' );
+ public function getSite( $globalId );
/**
- * Returns a list of all sites. By default this site is
- * fetched from the cache, which can be changed to loading
- * the list from the database using the $useCache parameter.
+ * Returns a list of all sites.
*
* @since 1.21
*
- * @param string $source Either 'cache' or 'recache'.
- * If 'cache', the values are allowed (but not obliged) to come from a
cache.
- *
* @return SiteList
*/
- public function getSites( $source = 'cache' );
+ public function getSites();
/**
* Deletes all sites from the database. After calling clear(),
getSites() will return an empty
diff --git a/includes/site/SiteListFileCacheBuilder.php
b/includes/site/SitesFileCacheBuilder.php
similarity index 89%
rename from includes/site/SiteListFileCacheBuilder.php
rename to includes/site/SitesFileCacheBuilder.php
index 7307a6f..89ae65b 100644
--- a/includes/site/SiteListFileCacheBuilder.php
+++ b/includes/site/SitesFileCacheBuilder.php
@@ -22,12 +22,12 @@
*
* @license GNU GPL v2+
*/
-class SiteListFileCacheBuilder {
+class SitesFileCacheBuilder {
/**
- * @var SiteStore
+ * @var SiteLookup
*/
- private $siteStore;
+ private $siteLookup;
/**
* @var string
@@ -35,16 +35,16 @@
private $cacheFile;
/**
- * @param SiteStore $siteStore
+ * @param SiteLookup $siteLookup
* @param string $cacheFile
*/
- public function __construct( SiteStore $siteStore, $cacheFile ) {
- $this->siteStore = $siteStore;
+ public function __construct( SiteLookup $siteLookup, $cacheFile ) {
+ $this->siteLookup = $siteLookup;
$this->cacheFile = $cacheFile;
}
public function build() {
- $this->sites = $this->siteStore->getSites( 'recache' );
+ $this->sites = $this->siteLookup->getSites();
$this->cacheSites( $this->sites->getArrayCopy() );
}
diff --git a/maintenance/rebuildSitesCache.php
b/maintenance/rebuildSitesFileCache.php
similarity index 73%
rename from maintenance/rebuildSitesCache.php
rename to maintenance/rebuildSitesFileCache.php
index 862a983..1c4b01b 100644
--- a/maintenance/rebuildSitesCache.php
+++ b/maintenance/rebuildSitesFileCache.php
@@ -23,26 +23,26 @@
require_once __DIR__ . '/Maintenance.php';
/**
- * Maintenance script to dump the SiteStore as a static json file.
+ * Maintenance script to dump a SiteStore as a static json file.
*
* @ingroup Maintenance
*/
-class RebuildSitesCache extends Maintenance {
+class RebuildSitesFileCache extends Maintenance {
public function __construct() {
parent::__construct();
- $this->mDescription = "Dumps site store as json";
+ $this->mDescription = "Cache sites as json for file-based
lookup.";
$this->addOption( 'file', 'File to output the json to', false,
true );
}
public function execute() {
- $siteListFileCacheBuilder = new SiteListFileCacheBuilder(
- SiteSQLStore::newInstance(),
+ $sitesFileCacheBuilder = new SitesFileCacheBuilder(
+ new SiteDBStore(),
$this->getCacheFile()
);
- $siteListFileCacheBuilder->build();
+ $sitesFileCacheBuilder->build();
}
/**
@@ -52,10 +52,10 @@
if ( $this->hasOption( 'file' ) ) {
$jsonFile = $this->getOption( 'file' );
} else {
- $jsonFile = $this->getConfig()->get( 'SitesCacheFile' );
+ $jsonFile = $this->getConfig()->get( 'SitesFileCache' );
if ( $jsonFile === false ) {
- $this->error( 'Error: No sites cache file is
set in configuration.', 1 );
+ $this->error( 'Error: No file set in
configuration for SitesFileCache.', 1 );
}
}
@@ -64,5 +64,5 @@
}
-$maintClass = "RebuildSitesCache";
+$maintClass = "RebuildSitesFileCache";
require_once RUN_MAINTENANCE_IF_MAIN;
diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php
b/tests/phpunit/includes/site/CachingSiteStoreTest.php
similarity index 84%
copy from tests/phpunit/includes/site/SiteSQLStoreTest.php
copy to tests/phpunit/includes/site/CachingSiteStoreTest.php
index 6002c1a..9db7b5a 100644
--- a/tests/phpunit/includes/site/SiteSQLStoreTest.php
+++ b/tests/phpunit/includes/site/CachingSiteStoreTest.php
@@ -1,7 +1,7 @@
<?php
/**
- * Tests for the SiteSQLStore class.
+ * Tests for the CachingSiteStore class.
*
* 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
@@ -30,16 +30,16 @@
* @licence GNU GPL v2+
* @author Jeroen De Dauw < [email protected] >
*/
-class SiteSQLStoreTest extends MediaWikiTestCase {
+class CachingSiteStoreTest extends MediaWikiTestCase {
/**
- * @covers SiteSQLStore::getSites
+ * @covers CachingSiteStore::getSites
*/
public function testGetSites() {
$expectedSites = TestSites::getSites();
TestSites::insertIntoDb();
- $store = SiteSQLStore::newInstance();
+ $store = new CachingSiteStore( new SiteDBStore(),
wfGetMainCache() );
$sites = $store->getSites();
@@ -60,10 +60,10 @@
}
/**
- * @covers SiteSQLStore::saveSites
+ * @covers CachingSiteStore::saveSites
*/
public function testSaveSites() {
- $store = SiteSQLStore::newInstance();
+ $store = new CachingSiteStore( new SiteDBStore(),
wfGetMainCache() );
$sites = array();
@@ -93,11 +93,11 @@
}
/**
- * @covers SiteSQLStore::reset
+ * @covers CachingSiteStore::reset
*/
public function testReset() {
- $store1 = SiteSQLStore::newInstance();
- $store2 = SiteSQLStore::newInstance();
+ $store1 = new CachingSiteStore( new SiteDBStore(),
wfGetMainCache() );
+ $store2 = new CachingSiteStore( new SiteDBStore(),
wfGetMainCache() );
// initialize internal cache
$this->assertGreaterThan( 0, $store1->getSites()->count() );
@@ -119,10 +119,10 @@
}
/**
- * @covers SiteSQLStore::clear
+ * @covers CachingSiteStore::clear
*/
public function testClear() {
- $store = SiteSQLStore::newInstance();
+ $store = new CachingSiteStore( new SiteDBStore(),
wfGetMainCache() );
$this->assertTrue( $store->clear() );
$site = $store->getSite( 'enwiki' );
diff --git a/tests/phpunit/includes/site/SiteListFileCacheTest.php
b/tests/phpunit/includes/site/FileBasedSiteLookupTest.php
similarity index 77%
rename from tests/phpunit/includes/site/SiteListFileCacheTest.php
rename to tests/phpunit/includes/site/FileBasedSiteLookupTest.php
index 05dcd8a..e9c1874 100644
--- a/tests/phpunit/includes/site/SiteListFileCacheTest.php
+++ b/tests/phpunit/includes/site/FileBasedSiteLookupTest.php
@@ -22,13 +22,13 @@
* @ingroup Site
* @ingroup Test
*
- * @covers SiteListFileCache
+ * @covers FileBasedSiteLookup
* @group Site
*
* @licence GNU GPL v2+
* @author Katie Filbert < [email protected] >
*/
-class SiteListFileCacheTest extends PHPUnit_Framework_TestCase {
+class FileBasedSiteLookupTest extends PHPUnit_Framework_TestCase {
protected function setUp() {
$this->cacheFile = $this->getCacheFile();
@@ -40,40 +40,40 @@
public function testGetSites() {
$sites = $this->getSites();
- $cacheBuilder = $this->newSiteListFileCacheBuilder( $sites );
+ $cacheBuilder = $this->newSitesFileCacheBuilder( $sites );
$cacheBuilder->build();
- $cache = new SiteListFileCache( $this->cacheFile );
+ $cache = new FileBasedSiteLookup( $this->cacheFile );
$this->assertEquals( $sites, $cache->getSites() );
}
public function testGetSite() {
$sites = $this->getSites();
- $cacheBuilder = $this->newSiteListFileCacheBuilder( $sites );
+ $cacheBuilder = $this->newSitesFileCacheBuilder( $sites );
$cacheBuilder->build();
- $cache = new SiteListFileCache( $this->cacheFile );
+ $cache = new FileBasedSiteLookup( $this->cacheFile );
$this->assertEquals( $sites->getSite( 'enwiktionary' ),
$cache->getSite( 'enwiktionary' ) );
}
- private function newSiteListFileCacheBuilder( SiteList $sites ) {
- return new SiteListFileCacheBuilder(
- $this->getSiteSQLStore( $sites ),
+ private function newSitesFileCacheBuilder( SiteList $sites ) {
+ return new SitesFileCacheBuilder(
+ $this->getSiteLookup( $sites ),
$this->cacheFile
);
}
- private function getSiteSQLStore( SiteList $sites ) {
- $siteSQLStore = $this->getMockBuilder( 'SiteSQLStore' )
+ private function getSiteLookup( SiteList $sites ) {
+ $siteLookup = $this->getMockBuilder( 'SiteLookup' )
->disableOriginalConstructor()
->getMock();
- $siteSQLStore->expects( $this->any() )
+ $siteLookup->expects( $this->any() )
->method( 'getSites' )
->will( $this->returnValue( $sites ) );
- return $siteSQLStore;
+ return $siteLookup;
}
private function getSites() {
diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php
b/tests/phpunit/includes/site/SiteDBStoreTest.php
similarity index 88%
rename from tests/phpunit/includes/site/SiteSQLStoreTest.php
rename to tests/phpunit/includes/site/SiteDBStoreTest.php
index 6002c1a..ae2720f 100644
--- a/tests/phpunit/includes/site/SiteSQLStoreTest.php
+++ b/tests/phpunit/includes/site/SiteDBStoreTest.php
@@ -1,7 +1,7 @@
<?php
/**
- * Tests for the SiteSQLStore class.
+ * Tests for the SiteDBStore class.
*
* 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
@@ -30,16 +30,16 @@
* @licence GNU GPL v2+
* @author Jeroen De Dauw < [email protected] >
*/
-class SiteSQLStoreTest extends MediaWikiTestCase {
+class SiteDBStoreTest extends MediaWikiTestCase {
/**
- * @covers SiteSQLStore::getSites
+ * @covers SiteDBStore::getSites
*/
public function testGetSites() {
$expectedSites = TestSites::getSites();
TestSites::insertIntoDb();
- $store = SiteSQLStore::newInstance();
+ $store = new SiteDBStore();
$sites = $store->getSites();
@@ -60,10 +60,10 @@
}
/**
- * @covers SiteSQLStore::saveSites
+ * @covers SiteDBStore::saveSites
*/
public function testSaveSites() {
- $store = SiteSQLStore::newInstance();
+ $store = new SiteDBStore();
$sites = array();
@@ -93,11 +93,11 @@
}
/**
- * @covers SiteSQLStore::reset
+ * @covers SiteDBStore::reset
*/
public function testReset() {
- $store1 = SiteSQLStore::newInstance();
- $store2 = SiteSQLStore::newInstance();
+ $store1 = new SiteDBStore();
+ $store2 = new SiteDBStore();
// initialize internal cache
$this->assertGreaterThan( 0, $store1->getSites()->count() );
@@ -119,10 +119,10 @@
}
/**
- * @covers SiteSQLStore::clear
+ * @covers SiteDBStore::clear
*/
public function testClear() {
- $store = SiteSQLStore::newInstance();
+ $store = new SiteDBStore();
$this->assertTrue( $store->clear() );
$site = $store->getSite( 'enwiki' );
diff --git a/tests/phpunit/includes/site/SiteListFileCacheBuilderTest.php
b/tests/phpunit/includes/site/SitesFileCacheBuilderTest.php
similarity index 86%
rename from tests/phpunit/includes/site/SiteListFileCacheBuilderTest.php
rename to tests/phpunit/includes/site/SitesFileCacheBuilderTest.php
index bbe8cc7..e44c25e 100644
--- a/tests/phpunit/includes/site/SiteListFileCacheBuilderTest.php
+++ b/tests/phpunit/includes/site/SitesFileCacheBuilderTest.php
@@ -22,13 +22,13 @@
* @ingroup Site
* @ingroup Test
*
- * @covers SiteListFileCacheBuilder
+ * @covers SitesFileCacheBuilder
* @group Site
*
* @licence GNU GPL v2+
* @author Katie Filbert < [email protected] >
*/
-class SiteListFileCacheBuilderTest extends PHPUnit_Framework_TestCase {
+class SitesFileCacheBuilderTest extends PHPUnit_Framework_TestCase {
protected function setUp() {
$this->cacheFile = $this->getCacheFile();
@@ -39,7 +39,7 @@
}
public function testBuild() {
- $cacheBuilder = $this->newSiteListFileCacheBuilder(
$this->getSites() );
+ $cacheBuilder = $this->newSitesFileCacheBuilder(
$this->getSites() );
$cacheBuilder->build();
$contents = file_get_contents( $this->cacheFile );
@@ -91,23 +91,23 @@
);
}
- private function newSiteListFileCacheBuilder( SiteList $sites ) {
- return new SiteListFileCacheBuilder(
- $this->getSiteSQLStore( $sites ),
+ private function newSitesFileCacheBuilder( SiteList $sites ) {
+ return new SitesFileCacheBuilder(
+ $this->getSiteLookup( $sites ),
$this->cacheFile
);
}
- private function getSiteSQLStore( SiteList $sites ) {
- $siteSQLStore = $this->getMockBuilder( 'SiteSQLStore' )
+ private function getSiteLookup( SiteList $sites ) {
+ $siteLookup = $this->getMockBuilder( 'SiteLookup' )
->disableOriginalConstructor()
->getMock();
- $siteSQLStore->expects( $this->any() )
+ $siteLookup->expects( $this->any() )
->method( 'getSites' )
->will( $this->returnValue( $sites ) );
- return $siteSQLStore;
+ return $siteLookup;
}
private function getSites() {
diff --git a/tests/phpunit/includes/site/TestSites.php
b/tests/phpunit/includes/site/TestSites.php
index af314ba..a11118d 100644
--- a/tests/phpunit/includes/site/TestSites.php
+++ b/tests/phpunit/includes/site/TestSites.php
@@ -108,7 +108,7 @@
* @since 0.1
*/
public static function insertIntoDb() {
- $sitesTable = SiteSQLStore::newInstance();
+ $sitesTable = new SiteDBStore();
$sitesTable->clear();
$sitesTable->saveSites( TestSites::getSites() );
}
--
To view, visit https://gerrit.wikimedia.org/r/188965
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I36b599884c211580ea6806a8a190c65c4f9087cf
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aude <[email protected]>
Gerrit-Reviewer: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits