MediaWiki
REL1_20
|
00001 <?php 00027 class ExternalStoreDB { 00028 00029 function __construct( $params = array() ) { 00030 $this->mParams = $params; 00031 } 00032 00039 function &getLoadBalancer( $cluster ) { 00040 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false; 00041 00042 return wfGetLBFactory()->getExternalLB( $cluster, $wiki ); 00043 } 00044 00051 function &getSlave( $cluster ) { 00052 global $wgDefaultExternalStore; 00053 00054 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false; 00055 $lb =& $this->getLoadBalancer( $cluster ); 00056 00057 if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) { 00058 wfDebug( "read only external store" ); 00059 $lb->allowLagged(true); 00060 } else { 00061 wfDebug( "writable external store" ); 00062 } 00063 00064 return $lb->getConnection( DB_SLAVE, array(), $wiki ); 00065 } 00066 00073 function &getMaster( $cluster ) { 00074 $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false; 00075 $lb =& $this->getLoadBalancer( $cluster ); 00076 return $lb->getConnection( DB_MASTER, array(), $wiki ); 00077 } 00078 00085 function getTable( &$db ) { 00086 $table = $db->getLBInfo( 'blobs table' ); 00087 if ( is_null( $table ) ) { 00088 $table = 'blobs'; 00089 } 00090 return $table; 00091 } 00092 00098 function fetchFromURL( $url ) { 00099 $path = explode( '/', $url ); 00100 $cluster = $path[2]; 00101 $id = $path[3]; 00102 if ( isset( $path[4] ) ) { 00103 $itemID = $path[4]; 00104 } else { 00105 $itemID = false; 00106 } 00107 00108 $ret =& $this->fetchBlob( $cluster, $id, $itemID ); 00109 00110 if ( $itemID !== false && $ret !== false ) { 00111 return $ret->getItem( $itemID ); 00112 } 00113 return $ret; 00114 } 00115 00126 function &fetchBlob( $cluster, $id, $itemID ) { 00133 static $externalBlobCache = array(); 00134 00135 $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/"; 00136 if( isset( $externalBlobCache[$cacheID] ) ) { 00137 wfDebug( "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" ); 00138 return $externalBlobCache[$cacheID]; 00139 } 00140 00141 wfDebug( "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" ); 00142 00143 $dbr =& $this->getSlave( $cluster ); 00144 $ret = $dbr->selectField( $this->getTable( $dbr ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ ); 00145 if ( $ret === false ) { 00146 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" ); 00147 // Try the master 00148 $dbw =& $this->getMaster( $cluster ); 00149 $ret = $dbw->selectField( $this->getTable( $dbw ), 'blob_text', array( 'blob_id' => $id ), __METHOD__ ); 00150 if( $ret === false) { 00151 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" ); 00152 } 00153 } 00154 if( $itemID !== false && $ret !== false ) { 00155 // Unserialise object; caller extracts item 00156 $ret = unserialize( $ret ); 00157 } 00158 00159 $externalBlobCache = array( $cacheID => &$ret ); 00160 return $ret; 00161 } 00162 00170 function store( $cluster, $data ) { 00171 $dbw = $this->getMaster( $cluster ); 00172 $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' ); 00173 $dbw->insert( $this->getTable( $dbw ), 00174 array( 'blob_id' => $id, 'blob_text' => $data ), 00175 __METHOD__ ); 00176 $id = $dbw->insertId(); 00177 if ( !$id ) { 00178 throw new MWException( __METHOD__.': no insert ID' ); 00179 } 00180 if ( $dbw->getFlag( DBO_TRX ) ) { 00181 $dbw->commit( __METHOD__ ); 00182 } 00183 return "DB://$cluster/$id"; 00184 } 00185 }