class KeyValueStore in MongoDB 8.2
Class KeyValueStore provides a KeyValueStore as a MongoDB collection.
Hierarchy
- class \Drupal\Core\KeyValueStore\StorageBase implements KeyValueStoreInterface
- class \Drupal\mongodb_storage\KeyValueStore implements KeyValueStoreInterface
Expanded class hierarchy of KeyValueStore
1 file declares its use of KeyValueStore
- KeyValueFactoryTest.php in modules/
mongodb_storage/ tests/ src/ Kernel/ KeyValueFactoryTest.php
File
- modules/
mongodb_storage/ src/ KeyValueStore.php, line 15
Namespace
Drupal\mongodb_storageView source
class KeyValueStore extends StorageBase implements KeyValueStoreInterface {
const LEGACY_TYPE_MAP = [
'typeMap' => [
'array' => 'array',
'document' => 'array',
'root' => 'array',
],
];
const PROJECTION_ID = [
'projection' => [
'_id' => 1,
],
];
/**
* The MongoDB collection name, like "kv[ep]_foo" for KV collection "foo".
*
* @var string
*/
protected $collectionName;
/**
* The collection making up the store.
*
* The parent class already defines $collection as the KV collection name.
*
* @var \MongoDb\Collection
*/
protected $mongoDbCollection;
/**
* KeyValueStore constructor.
*
* @param string $collection
* The KV collection name.
* @param \MongoDB\Collection|null $storeCollection
* The eponymous MongoDB collection.
*/
public function __construct($collection, Collection $storeCollection = NULL) {
parent::__construct($collection);
$this->collectionName = $storeCollection
->getCollectionName();
$this->mongoDbCollection = $storeCollection;
}
/**
* {@inheritdoc}
*/
public function __sleep() {
return [
'collectionName',
];
}
/**
* {@inheritdoc}
*
* The __wakeup() method cannot use the container, because its constructor is
* never invoked, and the container itself must not be serialized.
*/
public function __wakeup() {
/** @var \Drupal\mongodb\DatabaseFactory $databaseFactory */
$dbFactory = \Drupal::service(MongoDb::SERVICE_DB_FACTORY);
/** @var \MongoDB\Database $database */
$database = $dbFactory
->get(KeyValueFactory::DB_KEYVALUE);
$this->collection = $database
->selectCollection($this->collectionName);
}
/**
* Deletes all items from the key/value store.
*/
public function deleteAll() {
$this->mongoDbCollection
->drop();
}
/**
* Deletes multiple items from the key/value store.
*
* @param array $keys
* A list of item names to delete.
*/
public function deleteMultiple(array $keys) {
$stringKeys = array_map([
$this,
'stringifyKey',
], $keys);
$selector = [
'_id' => [
'$in' => $stringKeys,
],
];
$this->mongoDbCollection
->deleteMany($selector);
}
/**
* Returns all stored key/value pairs in the collection.
*
* @return array
* An associative array containing all stored items in the collection.
*/
public function getAll() {
$cursor = $this->mongoDbCollection
->find([], static::LEGACY_TYPE_MAP);
$result = [];
foreach ($cursor as $doc) {
$result[$doc['_id']] = unserialize($doc['value']);
}
return $result;
}
/**
* Returns the stored key/value pairs for a given set of keys.
*
* @param array $keys
* A list of keys to retrieve.
*
* @return array
* An associative array of items successfully returned, indexed by key. Core
* until 8.5 does not specify what to return for non-existing keys, so this
* implementation chooses not to include the non-existing keys in the result
* set.
*
* @see KeyValueStoreInterface::getMultiple()
*/
public function getMultiple(array $keys) {
$stringKeys = array_map([
$this,
'stringifyKey',
], $keys);
$selector = [
'_id' => [
'$in' => $stringKeys,
],
];
$cursor = $this->mongoDbCollection
->find($selector, static::LEGACY_TYPE_MAP);
$docs = [];
foreach ($cursor as $doc) {
$id = $doc['_id'];
$docs[$id] = unserialize($doc['value']);
}
return $docs;
}
/**
* Returns whether a given key exists in the store.
*
* @param string $key
* The key to check.
*
* @return bool
* TRUE if the key exists, FALSE otherwise.
*/
public function has($key) {
$selector = [
'_id' => $this
->stringifyKey($key),
];
$doc = $this->mongoDbCollection
->findOne($selector, static::PROJECTION_ID);
$res = isset($doc);
return $res;
}
/**
* Renames a key.
*
* WARNING: non-transactional beyond the trivial key === new_key case.
*
* @param string $key
* The key to rename.
* @param string $newKey
* The new key name.
*/
public function rename($key, $newKey) {
$stringKey = $this
->stringifyKey($key);
$stringNew = $this
->stringifyKey($newKey);
if ($stringKey === $stringNew) {
return;
}
$value = $this
->get($stringKey);
$this
->setIfNotExists($stringNew, $value);
$this
->delete($stringKey);
}
/**
* Saves a value for a given key.
*
* @param string $key
* The key of the data to store.
* @param mixed $value
* The data to store.
*/
public function set($key, $value) {
$selector = [
'_id' => $this
->stringifyKey($key),
];
$replacement = $selector + [
'value' => serialize($value),
];
$options = [
'upsert' => TRUE,
];
$this->mongoDbCollection
->replaceOne($selector, $replacement, $options);
}
/**
* Saves a value for a given key if it does not exist yet.
*
* @param string $key
* The key of the data to store.
* @param mixed $value
* The data to store.
*
* @return bool
* TRUE if the data was set, FALSE if it already existed.
*/
public function setIfNotExists($key, $value) {
$selector = [
'_id' => $this
->stringifyKey($key),
];
$replacement = $selector + [
'value' => serialize($value),
];
$options = [
'upsert' => FALSE,
];
$updateResult = $this->mongoDbCollection
->replaceOne($selector, $replacement, $options);
$result = $updateResult
->getModifiedCount() ? TRUE : FALSE;
return $result;
}
/**
* Represents any value as a string. May incur data loss.
*
* This loss is acceptable because keys should be string anyway, and any non-
* string uses as a key may be an injection attempt.
*
* @param mixed $key
* Is expected to be a key or behave as such.
*
* @return string
* The string version of the key.
*/
protected function stringifyKey($key) {
return "{$key}";
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
KeyValueStore:: |
protected | property | The MongoDB collection name, like "kv[ep]_foo" for KV collection "foo". | |
KeyValueStore:: |
protected | property | The collection making up the store. | |
KeyValueStore:: |
public | function |
Deletes all items from the key/value store. Overrides KeyValueStoreInterface:: |
1 |
KeyValueStore:: |
public | function |
Deletes multiple items from the key/value store. Overrides KeyValueStoreInterface:: |
|
KeyValueStore:: |
public | function |
Returns all stored key/value pairs in the collection. Overrides KeyValueStoreInterface:: |
|
KeyValueStore:: |
public | function |
Returns the stored key/value pairs for a given set of keys. Overrides KeyValueStoreInterface:: |
|
KeyValueStore:: |
public | function |
Returns whether a given key exists in the store. Overrides KeyValueStoreInterface:: |
|
KeyValueStore:: |
constant | |||
KeyValueStore:: |
constant | |||
KeyValueStore:: |
public | function |
Renames a key. Overrides KeyValueStoreInterface:: |
|
KeyValueStore:: |
public | function |
Saves a value for a given key. Overrides KeyValueStoreInterface:: |
|
KeyValueStore:: |
public | function |
Saves a value for a given key if it does not exist yet. Overrides KeyValueStoreInterface:: |
|
KeyValueStore:: |
protected | function | Represents any value as a string. May incur data loss. | |
KeyValueStore:: |
public | function |
KeyValueStore constructor. Overrides StorageBase:: |
1 |
KeyValueStore:: |
public | function | ||
KeyValueStore:: |
public | function | The __wakeup() method cannot use the container, because its constructor is never invoked, and the container itself must not be serialized. | |
StorageBase:: |
protected | property | The name of the collection holding key and value pairs. | |
StorageBase:: |
public | function |
Deletes an item from the key/value store. Overrides KeyValueStoreInterface:: |
1 |
StorageBase:: |
public | function |
Returns the stored value for a given key. Overrides KeyValueStoreInterface:: |
1 |
StorageBase:: |
public | function |
Returns the name of this collection. Overrides KeyValueStoreInterface:: |
|
StorageBase:: |
public | function |
Saves key/value pairs. Overrides KeyValueStoreInterface:: |
1 |