MediaWiki
REL1_19
|
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 }