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