00001 <?php
00002
00011 global $wgExternalLoadBalancers;
00012 $wgExternalLoadBalancers = array();
00013
00020 global $wgExternalBlobCache;
00021 $wgExternalBlobCache = array();
00022
00027 class ExternalStoreDB {
00028
00030 function &getLoadBalancer( $cluster ) {
00031 return wfGetLBFactory()->getExternalLB( $cluster );
00032 }
00033
00035 function &getSlave( $cluster ) {
00036 $lb =& $this->getLoadBalancer( $cluster );
00037 return $lb->getConnection( DB_SLAVE );
00038 }
00039
00041 function &getMaster( $cluster ) {
00042 $lb =& $this->getLoadBalancer( $cluster );
00043 return $lb->getConnection( DB_MASTER );
00044 }
00045
00047 function getTable( &$db ) {
00048 $table = $db->getLBInfo( 'blobs table' );
00049 if ( is_null( $table ) ) {
00050 $table = 'blobs';
00051 }
00052 return $table;
00053 }
00054
00059 function fetchFromURL( $url ) {
00060 $path = explode( '/', $url );
00061 $cluster = $path[2];
00062 $id = $path[3];
00063 if ( isset( $path[4] ) ) {
00064 $itemID = $path[4];
00065 } else {
00066 $itemID = false;
00067 }
00068
00069 $ret =& $this->fetchBlob( $cluster, $id, $itemID );
00070
00071 if ( $itemID !== false && $ret !== false ) {
00072 return $ret->getItem( $itemID );
00073 }
00074 return $ret;
00075 }
00076
00087 function &fetchBlob( $cluster, $id, $itemID ) {
00088 global $wgExternalBlobCache;
00089 $cacheID = ( $itemID === false ) ? "$cluster/$id" : "$cluster/$id/";
00090 if( isset( $wgExternalBlobCache[$cacheID] ) ) {
00091 wfDebug( "ExternalStoreDB::fetchBlob cache hit on $cacheID\n" );
00092 return $wgExternalBlobCache[$cacheID];
00093 }
00094
00095 wfDebug( "ExternalStoreDB::fetchBlob cache miss on $cacheID\n" );
00096
00097 $dbr =& $this->getSlave( $cluster );
00098 $ret = $dbr->selectField( $this->getTable( $dbr ), 'blob_text', array( 'blob_id' => $id ) );
00099 if ( $ret === false ) {
00100 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master fallback on $cacheID\n" );
00101
00102 $dbw =& $this->getMaster( $cluster );
00103 $ret = $dbw->selectField( $this->getTable( $dbw ), 'blob_text', array( 'blob_id' => $id ) );
00104 if( $ret === false) {
00105 wfDebugLog( 'ExternalStoreDB', "ExternalStoreDB::fetchBlob master failed to find $cacheID\n" );
00106 }
00107 }
00108 if( $itemID !== false && $ret !== false ) {
00109
00110 $ret = unserialize( $ret );
00111 }
00112
00113 $wgExternalBlobCache = array( $cacheID => &$ret );
00114 return $ret;
00115 }
00116
00124 function store( $cluster, $data ) {
00125 $dbw = $this->getMaster( $cluster );
00126 $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
00127 $dbw->insert( $this->getTable( $dbw ),
00128 array( 'blob_id' => $id, 'blob_text' => $data ),
00129 __METHOD__ );
00130 $id = $dbw->insertId();
00131 if ( $dbw->getFlag( DBO_TRX ) ) {
00132 $dbw->immediateCommit();
00133 }
00134 return "DB://$cluster/$id";
00135 }
00136 }