Merge "Update limit/urlwidth param doc of prop=imageinfo"
[lhc/web/wiklou.git] / includes / site / SiteSQLStore.php
index 724f115..4123805 100644 (file)
@@ -42,6 +42,16 @@ class SiteSQLStore implements SiteStore {
         */
        protected $sitesTable;
 
+       /**
+        * @var string|null
+        */
+       private $cacheKey = null;
+
+       /**
+        * @var int
+        */
+       private $cacheTimeout = 3600;
+
        /**
         * @since 1.21
         *
@@ -68,6 +78,38 @@ class SiteSQLStore implements SiteStore {
                $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() {
+               wfProfileIn( __METHOD__ );
+
+               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" );
+               }
+
+               wfProfileOut( __METHOD__ );
+               return $this->cacheKey;
+       }
+
        /**
         * @see SiteStore::getSites
         *
@@ -78,10 +120,12 @@ class SiteSQLStore implements SiteStore {
         * @return SiteList
         */
        public function getSites( $source = 'cache' ) {
+               wfProfileIn( __METHOD__ );
+
                if ( $source === 'cache' ) {
                        if ( $this->sites === null ) {
                                $cache = wfGetMainCache();
-                               $sites = $cache->get( wfMemcKey( 'SiteList' ) );
+                               $sites = $cache->get( $this->getCacheKey() );
 
                                if ( is_object( $sites ) ) {
                                        $this->sites = $sites;
@@ -94,6 +138,7 @@ class SiteSQLStore implements SiteStore {
                        $this->loadSites();
                }
 
+               wfProfileOut( __METHOD__ );
                return $this->sites;
        }
 
@@ -107,10 +152,14 @@ class SiteSQLStore implements SiteStore {
         * @return Site
         */
        protected function siteFromRow( ORMRow $siteRow ) {
+               wfProfileIn( __METHOD__ );
+
                $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' ) );
                }
@@ -135,6 +184,7 @@ class SiteSQLStore implements SiteStore {
                        $site->setExtraConfig( $siteRow->getField( 'config' ) );
                }
 
+               wfProfileOut( __METHOD__ );
                return $site;
        }
 
@@ -144,6 +194,8 @@ class SiteSQLStore implements SiteStore {
         * @since 1.21
         */
        protected function loadSites() {
+               wfProfileIn( __METHOD__ );
+
                $this->sites = new SiteList();
 
                foreach ( $this->sitesTable->select() as $siteRow ) {
@@ -171,7 +223,9 @@ class SiteSQLStore implements SiteStore {
                }
 
                $cache = wfGetMainCache();
-               $cache->set( wfMemcKey( 'SiteList' ), $this->sites );
+               $cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout );
+
+               wfProfileOut( __METHOD__ );
        }
 
        /**
@@ -185,8 +239,11 @@ class SiteSQLStore implements SiteStore {
         * @return Site|null
         */
        public function getSite( $globalId, $source = 'cache' ) {
+               wfProfileIn( __METHOD__ );
+
                $sites = $this->getSites( $source );
 
+               wfProfileOut( __METHOD__ );
                return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null;
        }
 
@@ -213,7 +270,10 @@ class SiteSQLStore implements SiteStore {
         * @return boolean Success indicator
         */
        public function saveSites( array $sites ) {
+               wfProfileIn( __METHOD__ );
+
                if ( empty( $sites ) ) {
+                       wfProfileOut( __METHOD__ );
                        return true;
                }
 
@@ -286,9 +346,59 @@ class SiteSQLStore implements SiteStore {
                        $dbw->commit( __METHOD__ );
                }
 
+               // purge cache
+               $this->reset();
+
+               wfProfileOut( __METHOD__ );
                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() {
+               wfProfileIn( __METHOD__ );
+               // purge cache
+               $cache = wfGetMainCache();
+               $cache->delete( $this->getCacheKey() );
+               $this->sites = null;
+
+               wfProfileOut( __METHOD__ );
+       }
+
+       /**
+        * Clears the list of sites stored in the database.
+        *
+        * @see SiteStore::clear()
+        *
+        * @return bool success
+        */
+       public function clear() {
+               wfProfileIn( __METHOD__ );
+               $dbw = $this->sitesTable->getWriteDbConnection();
+
+               $trx = $dbw->trxLevel();
+
+               if ( $trx == 0 ) {
+                       $dbw->begin( __METHOD__ );
+               }
+
+               $ok = $dbw->delete( 'sites', '*', __METHOD__ );
+               $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
+
+               if ( $trx == 0 ) {
+                       $dbw->commit( __METHOD__ );
+               }
+
+               $this->reset();
+
+               wfProfileOut( __METHOD__ );
+               return $ok;
+       }
+
        /**
         * @since 1.21
         *
@@ -361,7 +471,13 @@ class Sites extends SiteSQLStore {
         * @return SiteStore
         */
        public static function singleton() {
-               return new static();
+               static $singleton;
+
+               if ( $singleton === null ) {
+                       $singleton = new static();
+               }
+
+               return $singleton;
        }
 
        /**
@@ -372,4 +488,4 @@ class Sites extends SiteSQLStore {
                return $this->getSites()->getGroup( $group );
        }
 
-}
\ No newline at end of file
+}