MediaWiki  REL1_21
ExternalStoreDB.php
Go to the documentation of this file.
00001 <?php
00031 class ExternalStoreDB extends ExternalStoreMedium {
00038         public function fetchFromURL( $url ) {
00039                 $path = explode( '/', $url );
00040                 $cluster = $path[2];
00041                 $id = $path[3];
00042                 if ( isset( $path[4] ) ) {
00043                         $itemID = $path[4];
00044                 } else {
00045                         $itemID = false;
00046                 }
00047 
00048                 $ret =& $this->fetchBlob( $cluster, $id, $itemID );
00049 
00050                 if ( $itemID !== false && $ret !== false ) {
00051                         return $ret->getItem( $itemID );
00052                 }
00053                 return $ret;
00054         }
00055 
00059         public function store( $cluster, $data ) {
00060                 $dbw = $this->getMaster( $cluster );
00061                 $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
00062                 $dbw->insert( $this->getTable( $dbw ),
00063                         array( 'blob_id' => $id, 'blob_text' => $data ),
00064                         __METHOD__ );
00065                 $id = $dbw->insertId();
00066                 if ( !$id ) {
00067                         throw new MWException( __METHOD__.': no insert ID' );
00068                 }
00069                 if ( $dbw->getFlag( DBO_TRX ) ) {
00070                         $dbw->commit( __METHOD__ );
00071                 }
00072                 return "DB://$cluster/$id";
00073         }
00074 
00081         function &getLoadBalancer( $cluster ) {
00082                 $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
00083 
00084                 return wfGetLBFactory()->getExternalLB( $cluster, $wiki );
00085         }
00086 
00093         function &getSlave( $cluster ) {
00094                 global $wgDefaultExternalStore;
00095 
00096                 $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
00097                 $lb =& $this->getLoadBalancer( $cluster );
00098 
00099                 if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) {
00100                         wfDebug( "read only external store" );
00101                         $lb->allowLagged( true );
00102                 } else {
00103                         wfDebug( "writable external store" );
00104                 }
00105 
00106                 return $lb->getConnection( DB_SLAVE, array(), $wiki );
00107         }
00108 
00115         function &getMaster( $cluster ) {
00116                 $wiki = isset( $this->params['wiki'] ) ? $this->params['wiki'] : false;
00117                 $lb =& $this->getLoadBalancer( $cluster );
00118                 return $lb->getConnection( DB_MASTER, array(), $wiki );
00119         }
00120 
00127         function getTable( &$db ) {
00128                 $table = $db->getLBInfo( 'blobs table' );
00129                 if ( is_null( $table ) ) {
00130                         $table = 'blobs';
00131                 }
00132                 return $table;
00133         }
00134 
00145         function &fetchBlob( $cluster, $id, $itemID ) {
00152                 static $externalBlobCache = array();
00153 
00154                 $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/";
00155                 if( isset( $externalBlobCache[$cacheID] ) ) {
00156                         wfDebugLog( 'ExternalStoreDB-cache', "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" );
00157                         return $externalBlobCache[$cacheID];
00158                 }
00159 
00160                 wfDebugLog( 'ExternalStoreDB-cache', "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" );
00161 
00162                 $dbr =& $this->getSlave( $cluster );
00163                 $ret = $dbr->selectField( $this->getTable( $dbr ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ );
00164                 if ( $ret === false ) {
00165                         wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" );
00166                         // Try the master
00167                         $dbw =& $this->getMaster( $cluster );
00168                         $ret = $dbw->selectField( $this->getTable( $dbw ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ );
00169                         if( $ret === false) {
00170                                 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" );
00171                         }
00172                 }
00173                 if( $itemID !== false && $ret !== false ) {
00174                         // Unserialise object; caller extracts item
00175                         $ret = unserialize( $ret );
00176                 }
00177 
00178                 $externalBlobCache = array( $cacheID => &$ret );
00179                 return $ret;
00180         }
00181 }