MediaWiki  REL1_24
SiteSQLStore.php
Go to the documentation of this file.
00001 <?php
00002 
00031 class SiteSQLStore implements SiteStore {
00037     protected $sites = null;
00038 
00042     protected $sitesTable;
00043 
00047     private $cacheKey = null;
00048 
00052     private $cacheTimeout = 3600;
00053 
00061     public static function newInstance( ORMTable $sitesTable = null ) {
00062         return new static( $sitesTable );
00063     }
00064 
00072     protected function __construct( ORMTable $sitesTable = null ) {
00073         if ( $sitesTable === null ) {
00074             $sitesTable = $this->newSitesTable();
00075         }
00076 
00077         $this->sitesTable = $sitesTable;
00078     }
00079 
00094     protected function getCacheKey() {
00095         wfProfileIn( __METHOD__ );
00096 
00097         if ( $this->cacheKey === null ) {
00098             $type = 'SiteList#' . SiteList::getSerialVersionId();
00099             $source = $this->sitesTable->getName();
00100 
00101             if ( $this->sitesTable->getTargetWiki() !== false ) {
00102                 $source = $this->sitesTable->getTargetWiki() . '.' . $source;
00103             }
00104 
00105             $this->cacheKey = wfMemcKey( "$source/$type" );
00106         }
00107 
00108         wfProfileOut( __METHOD__ );
00109         return $this->cacheKey;
00110     }
00111 
00121     public function getSites( $source = 'cache' ) {
00122         wfProfileIn( __METHOD__ );
00123 
00124         if ( $source === 'cache' ) {
00125             if ( $this->sites === null ) {
00126                 $cache = wfGetMainCache();
00127                 $sites = $cache->get( $this->getCacheKey() );
00128 
00129                 if ( is_object( $sites ) ) {
00130                     $this->sites = $sites;
00131                 } else {
00132                     $this->loadSites();
00133                 }
00134             }
00135         }
00136         else {
00137             $this->loadSites();
00138         }
00139 
00140         wfProfileOut( __METHOD__ );
00141         return $this->sites;
00142     }
00143 
00153     protected function siteFromRow( ORMRow $siteRow ) {
00154         wfProfileIn( __METHOD__ );
00155 
00156         $site = Site::newForType( $siteRow->getField( 'type', Site::TYPE_UNKNOWN ) );
00157 
00158         $site->setGlobalId( $siteRow->getField( 'global_key' ) );
00159 
00160         $site->setInternalId( $siteRow->getField( 'id' ) );
00161 
00162         if ( $siteRow->hasField( 'forward' ) ) {
00163             $site->setForward( $siteRow->getField( 'forward' ) );
00164         }
00165 
00166         if ( $siteRow->hasField( 'group' ) ) {
00167             $site->setGroup( $siteRow->getField( 'group' ) );
00168         }
00169 
00170         if ( $siteRow->hasField( 'language' ) ) {
00171             $site->setLanguageCode( $siteRow->getField( 'language' ) === ''
00172                 ? null
00173                 : $siteRow->getField( 'language' )
00174             );
00175         }
00176 
00177         if ( $siteRow->hasField( 'source' ) ) {
00178             $site->setSource( $siteRow->getField( 'source' ) );
00179         }
00180 
00181         if ( $siteRow->hasField( 'data' ) ) {
00182             $site->setExtraData( $siteRow->getField( 'data' ) );
00183         }
00184 
00185         if ( $siteRow->hasField( 'config' ) ) {
00186             $site->setExtraConfig( $siteRow->getField( 'config' ) );
00187         }
00188 
00189         wfProfileOut( __METHOD__ );
00190         return $site;
00191     }
00192 
00202     protected function getRowFromSite( Site $site ) {
00203         $fields = array(
00204             // Site data
00205             'global_key' => $site->getGlobalId(), // TODO: check not null
00206             'type' => $site->getType(),
00207             'group' => $site->getGroup(),
00208             'source' => $site->getSource(),
00209             'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
00210             'protocol' => $site->getProtocol(),
00211             'domain' => strrev( $site->getDomain() ) . '.',
00212             'data' => $site->getExtraData(),
00213 
00214             // Site config
00215             'forward' => $site->shouldForward(),
00216             'config' => $site->getExtraConfig(),
00217         );
00218 
00219         if ( $site->getInternalId() !== null ) {
00220             $fields['id'] = $site->getInternalId();
00221         }
00222 
00223         return new ORMRow( $this->sitesTable, $fields );
00224     }
00225 
00231     protected function loadSites() {
00232         wfProfileIn( __METHOD__ );
00233 
00234         $this->sites = new SiteList();
00235 
00236         foreach ( $this->sitesTable->select() as $siteRow ) {
00237             $this->sites[] = $this->siteFromRow( $siteRow );
00238         }
00239 
00240         // Batch load the local site identifiers.
00241         $ids = wfGetDB( $this->sitesTable->getReadDb() )->select(
00242             'site_identifiers',
00243             array(
00244                 'si_site',
00245                 'si_type',
00246                 'si_key',
00247             ),
00248             array(),
00249             __METHOD__
00250         );
00251 
00252         foreach ( $ids as $id ) {
00253             if ( $this->sites->hasInternalId( $id->si_site ) ) {
00254                 $site = $this->sites->getSiteByInternalId( $id->si_site );
00255                 $site->addLocalId( $id->si_type, $id->si_key );
00256                 $this->sites->setSite( $site );
00257             }
00258         }
00259 
00260         $cache = wfGetMainCache();
00261         $cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout );
00262 
00263         wfProfileOut( __METHOD__ );
00264     }
00265 
00276     public function getSite( $globalId, $source = 'cache' ) {
00277         wfProfileIn( __METHOD__ );
00278 
00279         $sites = $this->getSites( $source );
00280 
00281         wfProfileOut( __METHOD__ );
00282         return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null;
00283     }
00284 
00294     public function saveSite( Site $site ) {
00295         return $this->saveSites( array( $site ) );
00296     }
00297 
00307     public function saveSites( array $sites ) {
00308         wfProfileIn( __METHOD__ );
00309 
00310         if ( empty( $sites ) ) {
00311             wfProfileOut( __METHOD__ );
00312             return true;
00313         }
00314 
00315         $dbw = $this->sitesTable->getWriteDbConnection();
00316 
00317         $dbw->startAtomic( __METHOD__ );
00318 
00319         $success = true;
00320 
00321         $internalIds = array();
00322         $localIds = array();
00323 
00324         foreach ( $sites as $site ) {
00325             if ( $site->getInternalId() !== null ) {
00326                 $internalIds[] = $site->getInternalId();
00327             }
00328 
00329             $siteRow = $this->getRowFromSite( $site );
00330             $success = $siteRow->save( __METHOD__ ) && $success;
00331 
00332             foreach ( $site->getLocalIds() as $idType => $ids ) {
00333                 foreach ( $ids as $id ) {
00334                     $localIds[] = array( $siteRow->getId(), $idType, $id );
00335                 }
00336             }
00337         }
00338 
00339         if ( $internalIds !== array() ) {
00340             $dbw->delete(
00341                 'site_identifiers',
00342                 array( 'si_site' => $internalIds ),
00343                 __METHOD__
00344             );
00345         }
00346 
00347         foreach ( $localIds as $localId ) {
00348             $dbw->insert(
00349                 'site_identifiers',
00350                 array(
00351                     'si_site' => $localId[0],
00352                     'si_type' => $localId[1],
00353                     'si_key' => $localId[2],
00354                 ),
00355                 __METHOD__
00356             );
00357         }
00358 
00359         $dbw->endAtomic( __METHOD__ );
00360 
00361         // purge cache
00362         $this->reset();
00363 
00364         wfProfileOut( __METHOD__ );
00365         return $success;
00366     }
00367 
00374     public function reset() {
00375         wfProfileIn( __METHOD__ );
00376         // purge cache
00377         $cache = wfGetMainCache();
00378         $cache->delete( $this->getCacheKey() );
00379         $this->sites = null;
00380 
00381         wfProfileOut( __METHOD__ );
00382     }
00383 
00391     public function clear() {
00392         wfProfileIn( __METHOD__ );
00393         $dbw = $this->sitesTable->getWriteDbConnection();
00394 
00395         $dbw->startAtomic( __METHOD__ );
00396         $ok = $dbw->delete( 'sites', '*', __METHOD__ );
00397         $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
00398         $dbw->endAtomic( __METHOD__);
00399 
00400         $this->reset();
00401 
00402         wfProfileOut( __METHOD__ );
00403         return $ok;
00404     }
00405 
00411     protected function newSitesTable() {
00412         return new ORMTable(
00413             'sites',
00414             array(
00415                 'id' => 'id',
00416 
00417                 // Site data
00418                 'global_key' => 'str',
00419                 'type' => 'str',
00420                 'group' => 'str',
00421                 'source' => 'str',
00422                 'language' => 'str',
00423                 'protocol' => 'str',
00424                 'domain' => 'str',
00425                 'data' => 'array',
00426 
00427                 // Site config
00428                 'forward' => 'bool',
00429                 'config' => 'array',
00430             ),
00431             array(
00432                 'type' => Site::TYPE_UNKNOWN,
00433                 'group' => Site::GROUP_NONE,
00434                 'source' => Site::SOURCE_LOCAL,
00435                 'data' => array(),
00436 
00437                 'forward' => false,
00438                 'config' => array(),
00439                 'language' => '',
00440             ),
00441             'ORMRow',
00442             'site_'
00443         );
00444     }
00445 
00446 }
00447 
00451 class Sites extends SiteSQLStore {
00452 
00463     public static function newSite( $globalId = false ) {
00464         $site = new Site();
00465 
00466         if ( $globalId !== false ) {
00467             $site->setGlobalId( $globalId );
00468         }
00469 
00470         return $site;
00471     }
00472 
00477     public static function singleton() {
00478         static $singleton;
00479 
00480         if ( $singleton === null ) {
00481             $singleton = new static();
00482         }
00483 
00484         return $singleton;
00485     }
00486 
00492     public function getSiteGroup( $group ) {
00493         return $this->getSites()->getGroup( $group );
00494     }
00495 }