MediaWiki  REL1_19
ExternalStoreDB.php
Go to the documentation of this file.
00001 <?php
00002 
00007 class ExternalStoreDB {
00008 
00009         function __construct( $params = array() ) {
00010                 $this->mParams = $params;
00011         }
00012 
00019         function &getLoadBalancer( $cluster ) {
00020                 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
00021 
00022                 return wfGetLBFactory()->getExternalLB( $cluster, $wiki );
00023         }
00024 
00031         function &getSlave( $cluster ) {
00032                 global $wgDefaultExternalStore;
00033 
00034                 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
00035                 $lb =& $this->getLoadBalancer( $cluster );
00036 
00037                 if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) {
00038                         wfDebug( "read only external store" );
00039                         $lb->allowLagged(true);
00040                 } else {
00041                         wfDebug( "writable external store" );
00042                 }
00043 
00044                 return $lb->getConnection( DB_SLAVE, array(), $wiki );
00045         }
00046 
00053         function &getMaster( $cluster ) {
00054                 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
00055                 $lb =& $this->getLoadBalancer( $cluster );
00056                 return $lb->getConnection( DB_MASTER, array(), $wiki );
00057         }
00058 
00065         function getTable( &$db ) {
00066                 $table = $db->getLBInfo( 'blobs table' );
00067                 if ( is_null( $table ) ) {
00068                         $table = 'blobs';
00069                 }
00070                 return $table;
00071         }
00072 
00077         function fetchFromURL( $url ) {
00078                 $path = explode( '/', $url );
00079                 $cluster  = $path[2];
00080                 $id       = $path[3];
00081                 if ( isset( $path[4] ) ) {
00082                         $itemID = $path[4];
00083                 } else {
00084                         $itemID = false;
00085                 }
00086 
00087                 $ret =& $this->fetchBlob( $cluster, $id, $itemID );
00088 
00089                 if ( $itemID !== false && $ret !== false ) {
00090                         return $ret->getItem( $itemID );
00091                 }
00092                 return $ret;
00093         }
00094 
00105         function &fetchBlob( $cluster, $id, $itemID ) {
00112                 static $externalBlobCache = array();
00113 
00114                 $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/";
00115                 if( isset( $externalBlobCache[$cacheID] ) ) {
00116                         wfDebug( "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" );
00117                         return $externalBlobCache[$cacheID];
00118                 }
00119 
00120                 wfDebug( "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" );
00121 
00122                 $dbr =& $this->getSlave( $cluster );
00123                 $ret = $dbr->selectField( $this->getTable( $dbr ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ );
00124                 if ( $ret === false ) {
00125                         wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" );
00126                         // Try the master
00127                         $dbw =& $this->getMaster( $cluster );
00128                         $ret = $dbw->selectField( $this->getTable( $dbw ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ );
00129                         if( $ret === false) {
00130                                 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" );
00131                         }
00132                 }
00133                 if( $itemID !== false && $ret !== false ) {
00134                         // Unserialise object; caller extracts item
00135                         $ret = unserialize( $ret );
00136                 }
00137 
00138                 $externalBlobCache = array( $cacheID => &$ret );
00139                 return $ret;
00140         }
00141 
00149         function store( $cluster, $data ) {
00150                 $dbw = $this->getMaster( $cluster );
00151                 $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
00152                 $dbw->insert( $this->getTable( $dbw ),
00153                         array( 'blob_id' => $id, 'blob_text' => $data ),
00154                         __METHOD__ );
00155                 $id = $dbw->insertId();
00156                 if ( !$id ) {
00157                         throw new MWException( __METHOD__.': no insert ID' );
00158                 }
00159                 if ( $dbw->getFlag( DBO_TRX ) ) {
00160                         $dbw->commit();
00161                 }
00162                 return "DB://$cluster/$id";
00163         }
00164 }