2022-12-29 16:52:04 +00:00
|
|
|
<?php
|
|
|
|
/**
|
2023-01-01 14:36:24 +00:00
|
|
|
* @copyright Copyright (C) 2010-2023, the Friendica project
|
2022-12-29 16:52:04 +00:00
|
|
|
*
|
|
|
|
* @license GNU AGPL version 3 or any later version
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Friendica\Core\KeyValueStorage\Type;
|
|
|
|
|
2023-01-01 20:10:37 +00:00
|
|
|
use Friendica\Core\PConfig\Util\ValueConversion;
|
2022-12-29 16:52:04 +00:00
|
|
|
use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException;
|
|
|
|
use Friendica\Database\Database;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A Key-Value storage provider with DB as persistence layer
|
|
|
|
*/
|
|
|
|
class DBKeyValueStorage extends AbstractKeyValueStorage
|
|
|
|
{
|
|
|
|
const DB_KEY_VALUE_TABLE = 'key-value';
|
|
|
|
|
|
|
|
/** @var Database */
|
|
|
|
protected $database;
|
|
|
|
|
|
|
|
public function __construct(Database $database)
|
|
|
|
{
|
|
|
|
$this->database = $database;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** {@inheritDoc} */
|
|
|
|
public function offsetExists($offset): bool
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return $this->database->exists(self::DB_KEY_VALUE_TABLE, ['k' => $offset]);
|
|
|
|
} catch (\Exception $exception) {
|
|
|
|
throw new KeyValueStoragePersistenceException(sprintf('Cannot check storage with key %s', $offset), $exception);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** {@inheritDoc} */
|
|
|
|
#[\ReturnTypeWillChange]
|
|
|
|
public function offsetGet($offset)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
$result = $this->database->selectFirst(self::DB_KEY_VALUE_TABLE, ['v'], ['k' => $offset]);
|
|
|
|
|
|
|
|
if ($this->database->isResult($result)) {
|
|
|
|
$value = ValueConversion::toConfigValue($result['v']);
|
|
|
|
|
|
|
|
// just return it in case it is set
|
|
|
|
if (isset($value)) {
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (\Exception $exception) {
|
|
|
|
throw new KeyValueStoragePersistenceException(sprintf('Cannot get value for key %s', $offset), $exception);
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** {@inheritDoc} */
|
|
|
|
#[\ReturnTypeWillChange]
|
|
|
|
public function offsetSet($offset, $value)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
// We store our setting values in a string variable.
|
|
|
|
// So we have to do the conversion here so that the compare below works.
|
|
|
|
// The exception are array values.
|
|
|
|
$compare_value = (!is_array($value) ? (string)$value : $value);
|
|
|
|
$stored_value = $this->get($offset);
|
|
|
|
|
|
|
|
if (isset($stored_value) && ($stored_value === $compare_value)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$dbValue = ValueConversion::toDbValue($value);
|
|
|
|
|
2022-12-29 21:36:08 +00:00
|
|
|
$return = $this->database->update(self::DB_KEY_VALUE_TABLE, [
|
2022-12-29 21:38:01 +00:00
|
|
|
'v' => $dbValue,
|
2022-12-29 21:36:08 +00:00
|
|
|
'updated_at' => time()
|
|
|
|
], ['k' => $offset], true);
|
2022-12-29 16:52:04 +00:00
|
|
|
|
|
|
|
if (!$return) {
|
|
|
|
throw new \Exception(sprintf('database update failed: %s', $this->database->errorMessage()));
|
|
|
|
}
|
|
|
|
} catch (\Exception $exception) {
|
|
|
|
throw new KeyValueStoragePersistenceException(sprintf('Cannot set value for %s for key %s', $value, $offset), $exception);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** {@inheritDoc} */
|
|
|
|
#[\ReturnTypeWillChange]
|
|
|
|
public function offsetUnset($offset)
|
|
|
|
{
|
|
|
|
try {
|
2022-12-29 21:12:02 +00:00
|
|
|
if (!$this->database->delete(self::DB_KEY_VALUE_TABLE, ['k' => $offset])) {
|
2022-12-29 16:52:04 +00:00
|
|
|
throw new \Exception(sprintf('database deletion failed: %s', $this->database->errorMessage()));
|
|
|
|
}
|
|
|
|
} catch (\Exception $exception) {
|
|
|
|
throw new KeyValueStoragePersistenceException(sprintf('Cannot delete value with key %s', $offset), $exception);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|