<?php/** * 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 * @since 1.23 *//** * Base class for generic key-value store */abstractclassDataStore{/** * Maximum key length. Must be enforced in all implementations to guarantee data portability */constMAX_KEY_LENGTH=255;privatestatic$stores=array();/** * Default constructor, sets class properties from config array * @param array $config: Associative array of store configuration */publicfunction__construct(array$config){foreach($configas$name=>$value){$this->$name=$value;}}/** * Creates a store with a given name * The store must be configured in $wgDataStores * * @param string $name * @return DataStore */publicstaticfunctiongetStore($name='default'){if(isset(self::$stores[$name])){returnself::$stores[$name];}global$wgDataStores;wfProfileIn(__METHOD__);if(!isset($wgDataStores[$name])){thrownewMWException("Unrecognised data store '$name'");}$config=$wgDataStores[$name];$store=new$config['class']($config);self::$stores[$name]=$store;wfProfileOut(__METHOD__);return$store;}/** * Returns value for a given key or null if not found * * @param string|array $key: Storage key * @param bool $latest: Whether a replicated or distributed store should ensure that the data returned is latest * @return mixed */publicabstractfunctionget($key,$latest=false);/** * Gets multiple values at once. * The default implementation is a slow fallback that calls get() multiple times. * Ideally, it should be overridden with something faster. * * @param array $keys: Array of keys * @param bool $latest: Whether a replicated or distributed store should ensure that the data returned is latest * * @return array: Associative array of key => value. If a key wasn't found, it will be omitted */publicfunctiongetMulti(array$keys,$latest=false){wfProfileIn(__METHOD__);$result=array();foreach($keysas$key){$value=$this->get($key,$latest);if($value!==null){$result[$key]=$value;}}wfProfileOut(__METHOD__);return$result;}/** * Sets value for a given key or keys * * @param string $key * @param mixed $value */publicabstractfunctionset($key,$value);/** * Sets multiple values at once. * The default implementation is a slow fallback that calls set() multiple times. * Ideally, it should be overridden with something faster. * * @param array $data: Associative array of key => value pairs to be set */publicfunctionsetMulti(array$data){wfProfileIn(__METHOD__);foreach($dataas$key=>$value){$this->set($key,$value);}wfProfileOut(__METHOD__);}/** * Returns all values whose keys start with a given string * * @param string $prefix * @param bool $latest: Whether a replicated or distributed store should ensure that the data returned is latest * @return Iterator */publicabstractfunctiongetByPrefix($prefix,$latest=false);/** * Deletes value with the specified key * * @param string $key */publicabstractfunctiondelete($key);/** * Deletes all values with keys matching the given key * * @param string $prefix */publicfinalfunctiondeleteByPrefix($prefix){if($prefix===''){thrownewMWException('Fool-proof against deletion of everything');}$this->deleteByPrefixInternal($prefix);}/** * Deletes all values with keys starting with a given prefix * @param $prefix */protectedabstractfunctiondeleteByPrefixInternal($prefix);/** * Generates a storage key from several parts * @return string */publicfunctionkey(/*...*/){$keys=func_get_args();$key=implode(':',$keys);if(strlen($key)>self::MAX_KEY_LENGTH){thrownewMWException("Key '$key' is too long");}return$key;}/** * Encodes data to be stored in a format suitable for current store. * Default implementation attempts to store primitive types in a non-serialized format. * * @param mixed $data: Data to encode * @return mixed */protectedfunctionencodeValue($data){if(is_array($data)||is_object($data)){returnserialize($data);}return$data;}};