MediaWiki
master
|
00001 <?php 00027 class ExternalStoreDB { 00028 00032 function __construct( $params = array() ) { 00033 $this->mParams = $params; 00034 } 00035 00042 function &getLoadBalancer( $cluster ) { 00043 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false; 00044 00045 return wfGetLBFactory()->getExternalLB( $cluster, $wiki ); 00046 } 00047 00054 function &getSlave( $cluster ) { 00055 global $wgDefaultExternalStore; 00056 00057 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false; 00058 $lb =& $this->getLoadBalancer( $cluster ); 00059 00060 if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) { 00061 wfDebug( "read only external store" ); 00062 $lb->allowLagged(true); 00063 } else { 00064 wfDebug( "writable external store" ); 00065 } 00066 00067 return $lb->getConnection( DB_SLAVE, array(), $wiki ); 00068 } 00069 00076 function &getMaster( $cluster ) { 00077 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false; 00078 $lb =& $this->getLoadBalancer( $cluster ); 00079 return $lb->getConnection( DB_MASTER, array(), $wiki ); 00080 } 00081 00088 function getTable( &$db ) { 00089 $table = $db->getLBInfo( 'blobs table' ); 00090 if ( is_null( $table ) ) { 00091 $table = 'blobs'; 00092 } 00093 return $table; 00094 } 00095 00101 function fetchFromURL( $url ) { 00102 $path = explode( '/', $url ); 00103 $cluster = $path[2]; 00104 $id = $path[3]; 00105 if ( isset( $path[4] ) ) { 00106 $itemID = $path[4]; 00107 } else { 00108 $itemID = false; 00109 } 00110 00111 $ret =& $this->fetchBlob( $cluster, $id, $itemID ); 00112 00113 if ( $itemID !== false && $ret !== false ) { 00114 return $ret->getItem( $itemID ); 00115 } 00116 return $ret; 00117 } 00118 00129 function &fetchBlob( $cluster, $id, $itemID ) { 00136 static $externalBlobCache = array(); 00137 00138 $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/"; 00139 if( isset( $externalBlobCache[$cacheID] ) ) { 00140 wfDebug( "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" ); 00141 return $externalBlobCache[$cacheID]; 00142 } 00143 00144 wfDebug( "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" ); 00145 00146 $dbr =& $this->getSlave( $cluster ); 00147 $ret = $dbr->selectField( $this->getTable( $dbr ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ ); 00148 if ( $ret === false ) { 00149 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" ); 00150 // Try the master 00151 $dbw =& $this->getMaster( $cluster ); 00152 $ret = $dbw->selectField( $this->getTable( $dbw ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ ); 00153 if( $ret === false) { 00154 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" ); 00155 } 00156 } 00157 if( $itemID !== false && $ret !== false ) { 00158 // Unserialise object; caller extracts item 00159 $ret = unserialize( $ret ); 00160 } 00161 00162 $externalBlobCache = array( $cacheID => &$ret ); 00163 return $ret; 00164 } 00165 00174 function store( $cluster, $data ) { 00175 $dbw = $this->getMaster( $cluster ); 00176 $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' ); 00177 $dbw->insert( $this->getTable( $dbw ), 00178 array( 'blob_id' => $id, 'blob_text' => $data ), 00179 __METHOD__ ); 00180 $id = $dbw->insertId(); 00181 if ( !$id ) { 00182 throw new MWException( __METHOD__.': no insert ID' ); 00183 } 00184 if ( $dbw->getFlag( DBO_TRX ) ) { 00185 $dbw->commit( __METHOD__ ); 00186 } 00187 return "DB://$cluster/$id"; 00188 } 00189 }