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