'ExternalStore' => 'includes/externalstore/ExternalStore.php',
'ExternalStoreDB' => 'includes/externalstore/ExternalStoreDB.php',
'ExternalStoreHttp' => 'includes/externalstore/ExternalStoreHttp.php',
+ 'ExternalStoreMedium' => 'includes/externalstore/ExternalStoreMedium.php',
'ExternalUser' => 'includes/ExternalUser.php',
'FakeTitle' => 'includes/FakeTitle.php',
'Fallback' => 'includes/Fallback.php',
*/
/**
- * Constructor class for data kept in external repositories.
+ * Constructor class for key/value blob data kept in external repositories.
*
* Objects in external stores are defined by a special URL. The URL is of
- * the form "<store protocal>://<location>/<object name>". When an object
- * is inserted into a store, the calling code uses a partial URL of the form
- * "<store protocal>://<location>" and receives the full object URL on success.
+ * the form "<store protocal>://<location>/<object name>". The protocal is used
+ * to determine what ExternalStoreMedium class is used. The location identifies
+ * particular storage instances or database clusters for store class to use.
+ *
+ * When an object is inserted into a store, the calling code uses a partial URL of
+ * the form "<store protocal>://<location>" and receives the full object URL on success.
* This is useful since object names can be sequential IDs, UUIDs, or hashes.
* Callers are not responsible for unique name generation.
*
* External repositories might be populated by maintenance/async
* scripts, thus partial moving of data may be possible, as well
- * as possibility to have any storage format (i.e. for archives)
+ * as the possibility to have any storage format (i.e. for archives).
*
* @ingroup ExternalStorage
*/
/**
* Get an external store object of the given type, with the given parameters
*
- * @param $proto String: type of external storage, should be a value in $wgExternalStores
- * @param $params Array: associative array of parameters for the ExternalStore object.
- * @return ExternalStore|bool ExternalStore class or false on error
+ * @param $proto string Type of external storage, should be a value in $wgExternalStores
+ * @param $params array Associative array of ExternalStoreMedium parameters
+ * @return ExternalStoreMedium|bool The store class or false on error
*/
public static function getStoreObject( $proto, array $params = array() ) {
global $wgExternalStores;
/**
* Fetch data from given URL
*
- * @param $url String: The URL of the text to get
- * @param $params Array: associative array of parameters for the ExternalStore object.
+ * @param $url string The URL of the text to get
+ * @param $params array Associative array of ExternalStoreMedium parameters
* @return string|bool The text stored or false on error
* @throws MWException
*/
* Store a data item to an external store, identified by a partial URL
* The protocol part is used to identify the class, the rest is passed to the
* class itself as a parameter.
- * @param $url
- * @param $data
- * @param $params array
+ *
+ * @param $url String A partial external store URL ("<store type>://<location>")
+ * @param $data string
+ * @param $params array Associative array of ExternalStoreMedium parameters
* @return string|bool The URL of the stored data item, or false on error
* @throws MWException
*/
* This function does not need a url param, it builds it by
* itself. It also fails-over to the next possible clusters.
*
- * @param $data String
- * @param $params Array: associative array of parameters for the ExternalStore object.
+ * @param $data string
+ * @param $params array Associative array of ExternalStoreMedium parameters
* @return string|bool The URL of the stored data item, or false on error
* @throws MWException
*/
}
/**
- * @param $data
- * @param $wiki
+ * @param $data string
+ * @param $wiki string
* @return string|bool The URL of the stored data item, or false on error
* @throws MWException
*/
*/
/**
- * DB accessable external objects
+ * DB accessable external objects.
+ *
+ * In this system, each store "location" maps to a database "cluster".
+ * The clusters must be defined in the normal LBFactory configuration.
+ *
* @ingroup ExternalStorage
*/
-class ExternalStoreDB {
+class ExternalStoreDB extends ExternalStoreMedium {
+ /**
+ * The URL returned is of the form of the form DB://cluster/id
+ * or DB://cluster/id/itemid for concatened storage.
+ *
+ * @see ExternalStoreMedium::fetchFromURL()
+ */
+ public function fetchFromURL( $url ) {
+ $path = explode( '/', $url );
+ $cluster = $path[2];
+ $id = $path[3];
+ if ( isset( $path[4] ) ) {
+ $itemID = $path[4];
+ } else {
+ $itemID = false;
+ }
+
+ $ret =& $this->fetchBlob( $cluster, $id, $itemID );
+
+ if ( $itemID !== false && $ret !== false ) {
+ return $ret->getItem( $itemID );
+ }
+ return $ret;
+ }
/**
- * @param $params array
+ * @see ExternalStoreMedium::store()
*/
- function __construct( $params = array() ) {
- $this->mParams = $params;
+ public function store( $cluster, $data ) {
+ $dbw = $this->getMaster( $cluster );
+ $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
+ $dbw->insert( $this->getTable( $dbw ),
+ array( 'blob_id' => $id, 'blob_text' => $data ),
+ __METHOD__ );
+ $id = $dbw->insertId();
+ if ( !$id ) {
+ throw new MWException( __METHOD__.': no insert ID' );
+ }
+ if ( $dbw->getFlag( DBO_TRX ) ) {
+ $dbw->commit( __METHOD__ );
+ }
+ return "DB://$cluster/$id";
}
/**
* @return LoadBalancer object
*/
function &getLoadBalancer( $cluster ) {
- $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
+ $wiki = isset($this->params['wiki']) ? $this->params['wiki'] : false;
return wfGetLBFactory()->getExternalLB( $cluster, $wiki );
}
function &getSlave( $cluster ) {
global $wgDefaultExternalStore;
- $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
+ $wiki = isset($this->params['wiki']) ? $this->params['wiki'] : false;
$lb =& $this->getLoadBalancer( $cluster );
if ( !in_array( "DB://" . $cluster, (array)$wgDefaultExternalStore ) ) {
* @return DatabaseBase object
*/
function &getMaster( $cluster ) {
- $wiki = isset($this->mParams['wiki']) ? $this->mParams['wiki'] : false;
+ $wiki = isset($this->params['wiki']) ? $this->params['wiki'] : false;
$lb =& $this->getLoadBalancer( $cluster );
return $lb->getConnection( DB_MASTER, array(), $wiki );
}
return $table;
}
- /**
- * Fetch data from given URL
- * @param $url String: an url of the form DB://cluster/id or DB://cluster/id/itemid for concatened storage.
- * @return mixed
- */
- function fetchFromURL( $url ) {
- $path = explode( '/', $url );
- $cluster = $path[2];
- $id = $path[3];
- if ( isset( $path[4] ) ) {
- $itemID = $path[4];
- } else {
- $itemID = false;
- }
-
- $ret =& $this->fetchBlob( $cluster, $id, $itemID );
-
- if ( $itemID !== false && $ret !== false ) {
- return $ret->getItem( $itemID );
- }
- return $ret;
- }
-
/**
* Fetch a blob item out of the database; a cache of the last-loaded
* blob will be kept so that multiple loads out of a multi-item blob
$externalBlobCache = array( $cacheID => &$ret );
return $ret;
}
-
- /**
- * Insert a data item into a given cluster
- *
- * @param $cluster String: the cluster name
- * @param $data String: the data item
- * @throws MWException
- * @return string URL
- */
- function store( $cluster, $data ) {
- $dbw = $this->getMaster( $cluster );
- $id = $dbw->nextSequenceValue( 'blob_blob_id_seq' );
- $dbw->insert( $this->getTable( $dbw ),
- array( 'blob_id' => $id, 'blob_text' => $data ),
- __METHOD__ );
- $id = $dbw->insertId();
- if ( !$id ) {
- throw new MWException( __METHOD__.': no insert ID' );
- }
- if ( $dbw->getFlag( DBO_TRX ) ) {
- $dbw->commit( __METHOD__ );
- }
- return "DB://$cluster/$id";
- }
}
*
* @ingroup ExternalStorage
*/
-class ExternalStoreHttp {
-
+class ExternalStoreHttp extends ExternalStoreMedium {
/**
- * Fetch data from given URL
- *
- * @param $url String: the URL
- * @return String: the content at $url
+ * @see ExternalStoreMedium::fetchFromURL()
*/
- function fetchFromURL( $url ) {
- $ret = Http::get( $url );
- return $ret;
+ public function fetchFromURL( $url ) {
+ return Http::get( $url );
}
- /* XXX: may require other methods, for store, delete,
- * whatever, for initial ext storage
+ /**
+ * @see ExternalStoreMedium::store()
*/
+ public function store( $cluster, $data ) {
+ throw new MWException( "ExternalStoreHttp is read-only and does not support store()." );
+ }
}
--- /dev/null
+<?php
+/**
+ * External storage in some particular medium.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup ExternalStorage
+ * @author Aaron Schulz
+ */
+
+/**
+ * Accessable external objects
+ * @ingroup ExternalStorage
+ */
+abstract class ExternalStoreMedium {
+ /** @var Array */
+ protected $params = array();
+
+ /**
+ * @param $params array Options
+ */
+ public function __construct( array $params = array() ) {
+ $this->params = $params;
+ }
+
+ /**
+ * Fetch data from given external store URL
+ *
+ * @param $url string An external store URL
+ * @return string|bool The text stored or false on error
+ * @throws MWException
+ */
+ public abstract function fetchFromURL( $url );
+
+ /**
+ * Insert a data item into a given location
+ *
+ * @param $location string: the location name
+ * @param $data string: the data item
+ * @return string|bool The URL of the stored data item, or false on error
+ * @throws MWException
+ */
+ public abstract function store( $location, $data );
+}