Signed-off-by: Maxence Lange <maxence@artificial-owl.com> d Signed-off-by: Maxence Lange <maxence@artificial-owl.com>tags/v29.0.0beta1
@@ -25,11 +25,11 @@ | |||
*/ | |||
namespace OCA\Provisioning_API\Tests\Controller; | |||
use OC\AppConfig; | |||
use OCA\Provisioning_API\Controller\AppConfigController; | |||
use OCP\AppFramework\Http; | |||
use OCP\AppFramework\Http\DataResponse; | |||
use OCP\IAppConfig; | |||
use OCP\IConfig; | |||
use OCP\IGroupManager; | |||
use OCP\IL10N; | |||
use OCP\IRequest; | |||
@@ -45,8 +45,6 @@ use Test\TestCase; | |||
*/ | |||
class AppConfigControllerTest extends TestCase { | |||
/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $config; | |||
/** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */ | |||
private $appConfig; | |||
/** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ | |||
@@ -61,8 +59,7 @@ class AppConfigControllerTest extends TestCase { | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->config = $this->createMock(IConfig::class); | |||
$this->appConfig = $this->createMock(IAppConfig::class); | |||
$this->appConfig = $this->createMock(AppConfig::class); | |||
$this->userSession = $this->createMock(IUserSession::class); | |||
$this->l10n = $this->createMock(IL10N::class); | |||
$this->groupManager = $this->createMock(IGroupManager::class); | |||
@@ -80,7 +77,6 @@ class AppConfigControllerTest extends TestCase { | |||
return new AppConfigController( | |||
'provisioning_api', | |||
$request, | |||
$this->config, | |||
$this->appConfig, | |||
$this->userSession, | |||
$this->l10n, | |||
@@ -92,7 +88,6 @@ class AppConfigControllerTest extends TestCase { | |||
->setConstructorArgs([ | |||
'provisioning_api', | |||
$request, | |||
$this->config, | |||
$this->appConfig, | |||
$this->userSession, | |||
$this->l10n, | |||
@@ -183,16 +178,13 @@ class AppConfigControllerTest extends TestCase { | |||
->method('verifyAppId') | |||
->with($app) | |||
->willThrowException($throws); | |||
$this->config->expects($this->never()) | |||
->method('getAppValue'); | |||
} else { | |||
$api->expects($this->once()) | |||
->method('verifyAppId') | |||
->with($app); | |||
$this->config->expects($this->once()) | |||
->method('getAppValue') | |||
$this->appConfig->expects($this->once()) | |||
->method('getValueMixed') | |||
->with($app, $key, $default) | |||
->willReturn($return); | |||
} | |||
@@ -246,8 +238,8 @@ class AppConfigControllerTest extends TestCase { | |||
$api->expects($this->never()) | |||
->method('verifyConfigKey'); | |||
$this->config->expects($this->never()) | |||
->method('setAppValue'); | |||
$this->appConfig->expects($this->never()) | |||
->method('setValueMixed'); | |||
} elseif ($keyThrows instanceof \Exception) { | |||
$api->expects($this->once()) | |||
->method('verifyAppId') | |||
@@ -257,8 +249,8 @@ class AppConfigControllerTest extends TestCase { | |||
->with($app, $key) | |||
->willThrowException($keyThrows); | |||
$this->config->expects($this->never()) | |||
->method('setAppValue'); | |||
$this->appConfig->expects($this->never()) | |||
->method('setValueMixed'); | |||
} else { | |||
$api->expects($this->once()) | |||
->method('verifyAppId') | |||
@@ -267,8 +259,8 @@ class AppConfigControllerTest extends TestCase { | |||
->method('verifyConfigKey') | |||
->with($app, $key); | |||
$this->config->expects($this->once()) | |||
->method('setAppValue') | |||
$this->appConfig->expects($this->once()) | |||
->method('setValueMixed') | |||
->with($app, $key, $value); | |||
} | |||
@@ -310,8 +302,8 @@ class AppConfigControllerTest extends TestCase { | |||
$api->expects($this->never()) | |||
->method('verifyConfigKey'); | |||
$this->config->expects($this->never()) | |||
->method('deleteAppValue'); | |||
$this->appConfig->expects($this->never()) | |||
->method('deleteKey'); | |||
} elseif ($keyThrows instanceof \Exception) { | |||
$api->expects($this->once()) | |||
->method('verifyAppId') | |||
@@ -321,8 +313,8 @@ class AppConfigControllerTest extends TestCase { | |||
->with($app, $key) | |||
->willThrowException($keyThrows); | |||
$this->config->expects($this->never()) | |||
->method('deleteAppValue'); | |||
$this->appConfig->expects($this->never()) | |||
->method('deleteKey'); | |||
} else { | |||
$api->expects($this->once()) | |||
->method('verifyAppId') | |||
@@ -331,8 +323,8 @@ class AppConfigControllerTest extends TestCase { | |||
->method('verifyConfigKey') | |||
->with($app, $key); | |||
$this->config->expects($this->once()) | |||
->method('deleteAppValue') | |||
$this->appConfig->expects($this->once()) | |||
->method('deleteKey') | |||
->with($app, $key); | |||
} | |||
@@ -83,20 +83,9 @@ class GetConfig extends Base { | |||
if ($input->getOption('details')) { | |||
$details = $this->appConfig->getDetails($appName, $configName); | |||
$format = $input->getOption('output') ?? 'plain'; | |||
if ($format === 'json') { | |||
$output->writeln(json_encode($details)); | |||
} elseif ($format === 'json_pretty') { | |||
$output->writeln(json_encode($details, JSON_PRETTY_PRINT)); | |||
} else { | |||
$output->writeln('App: ' . $details['app'] ?? ''); | |||
$output->writeln('Config Key: ' . $details['key'] ?? ''); | |||
$output->writeln('Config Value: ' . $details['value'] ?? ''); | |||
$output->writeln('Value type: ' . $details['typeString'] ?? ''); | |||
$output->writeln('Lazy loaded: ' . (($details['lazy'] ?? false) ? 'Yes' : 'No')); | |||
$output->writeln('Sensitive: ' . (($details['sensitive'] ?? false) ? 'Yes' : 'No')); | |||
} | |||
$details['type'] = $details['typeString']; | |||
unset($details['typeString']); | |||
$this->writeArrayInOutputFormat($input, $output, $details); | |||
return 0; | |||
} | |||
@@ -35,9 +35,6 @@ use Symfony\Component\Console\Output\OutputInterface; | |||
use Symfony\Component\Console\Question\Question; | |||
class SetConfig extends Base { | |||
private InputInterface $input; | |||
private OutputInterface $output; | |||
public function __construct( | |||
protected IAppConfig $appConfig, | |||
) { | |||
@@ -97,8 +94,6 @@ class SetConfig extends Base { | |||
protected function execute(InputInterface $input, OutputInterface $output): int { | |||
$appName = $input->getArgument('app'); | |||
$configName = $input->getArgument('name'); | |||
$this->input = $input; | |||
$this->output = $output; | |||
if (!($this->appConfig instanceof AppConfig)) { | |||
throw new \Exception('Only compatible with OC\AppConfig as it uses internal methods'); | |||
@@ -126,19 +121,19 @@ class SetConfig extends Base { | |||
*/ | |||
$updated = false; | |||
if (!$input->hasParameterOption('--value')) { | |||
if (!$input->getOption('lazy') && $this->appConfig->isLazy($appName, $configName) && $this->ask('NOT LAZY')) { | |||
if (!$input->getOption('lazy') && $this->appConfig->isLazy($appName, $configName) && $this->ask($input, $output, 'NOT LAZY')) { | |||
$updated = $this->appConfig->updateLazy($appName, $configName, false); | |||
} | |||
if ($input->getOption('lazy') && !$this->appConfig->isLazy($appName, $configName) && $this->ask('LAZY')) { | |||
if ($input->getOption('lazy') && !$this->appConfig->isLazy($appName, $configName) && $this->ask($input, $output, 'LAZY')) { | |||
$updated = $this->appConfig->updateLazy($appName, $configName, true) || $updated; | |||
} | |||
if (!$input->getOption('sensitive') && $this->appConfig->isSensitive($appName, $configName) && $this->ask('NOT SENSITIVE')) { | |||
if (!$input->getOption('sensitive') && $this->appConfig->isSensitive($appName, $configName) && $this->ask($input, $output, 'NOT SENSITIVE')) { | |||
$updated = $this->appConfig->updateSensitive($appName, $configName, false) || $updated; | |||
} | |||
if ($input->getOption('sensitive') && !$this->appConfig->isSensitive($appName, $configName) && $this->ask('SENSITIVE')) { | |||
if ($input->getOption('sensitive') && !$this->appConfig->isSensitive($appName, $configName) && $this->ask($input, $output, 'SENSITIVE')) { | |||
$updated = $this->appConfig->updateSensitive($appName, $configName, true) || $updated; | |||
} | |||
if ($typeString !== null && $type !== $this->appConfig->getValueType($appName, $configName) && $this->ask($typeString)) { | |||
if ($type !== null && $type !== $this->appConfig->getValueType($appName, $configName) && $typeString !== null && $this->ask($input, $output, $typeString)) { | |||
$updated = $this->appConfig->updateType($appName, $configName, $type) || $updated; | |||
} | |||
} else { | |||
@@ -149,7 +144,7 @@ class SetConfig extends Base { | |||
*/ | |||
try { | |||
$currType = $this->appConfig->getValueType($appName, $configName); | |||
if ($type === null || $type === $currType || !$this->ask($typeString)) { | |||
if ($typeString === null || $type === $currType || !$this->ask($input, $output, $typeString)) { | |||
$type = $currType; | |||
} else { | |||
$updated = $this->appConfig->updateType($appName, $configName, $type); | |||
@@ -166,7 +161,7 @@ class SetConfig extends Base { | |||
$lazy = $input->getOption('lazy'); | |||
try { | |||
$currLazy = $this->appConfig->isLazy($appName, $configName); | |||
if ($lazy === null || $lazy === $currLazy || !$this->ask(($lazy) ? 'LAZY' : 'NOT LAZY')) { | |||
if ($lazy === null || $lazy === $currLazy || !$this->ask($input, $output, ($lazy) ? 'LAZY' : 'NOT LAZY')) { | |||
$lazy = $currLazy; | |||
} | |||
} catch (AppConfigUnknownKeyException) { | |||
@@ -179,7 +174,7 @@ class SetConfig extends Base { | |||
$sensitive = $input->getOption('sensitive'); | |||
try { | |||
$currSensitive = $this->appConfig->isLazy($appName, $configName); | |||
if ($sensitive === null || $sensitive === $currSensitive || !$this->ask(($sensitive) ? 'LAZY' : 'NOT LAZY')) { | |||
if ($sensitive === null || $sensitive === $currSensitive || !$this->ask($input, $output, ($sensitive) ? 'LAZY' : 'NOT LAZY')) { | |||
$sensitive = $currSensitive; | |||
} | |||
} catch (AppConfigUnknownKeyException) { | |||
@@ -249,26 +244,26 @@ class SetConfig extends Base { | |||
return 0; | |||
} | |||
private function ask(string $request): bool { | |||
private function ask(InputInterface $input, OutputInterface $output, string $request): bool { | |||
$helper = $this->getHelper('question'); | |||
if ($this->input->getOption('no-interaction')) { | |||
if ($input->getOption('no-interaction')) { | |||
return true; | |||
} | |||
$this->output->writeln(sprintf('You are about to set config value %s as <info>%s</info>', | |||
'<info>' . $this->input->getArgument('app') . '</info>/<info>' . $this->input->getArgument('name') . '</info>', | |||
$output->writeln(sprintf('You are about to set config value %s as <info>%s</info>', | |||
'<info>' . $input->getArgument('app') . '</info>/<info>' . $input->getArgument('name') . '</info>', | |||
strtoupper($request) | |||
)); | |||
$this->output->writeln(''); | |||
$this->output->writeln('<comment>This might break thing, affect performance on your instance or its security!</comment>'); | |||
$output->writeln(''); | |||
$output->writeln('<comment>This might break thing, affect performance on your instance or its security!</comment>'); | |||
$result = (strtolower((string)$helper->ask( | |||
$this->input, | |||
$this->output, | |||
$input, | |||
$output, | |||
new Question('<comment>Confirm this action by typing \'yes\'</comment>: '))) === 'yes'); | |||
$this->output->writeln(($result) ? 'done' : 'cancelled'); | |||
$this->output->writeln(''); | |||
$output->writeln(($result) ? 'done' : 'cancelled'); | |||
$output->writeln(''); | |||
return $result; | |||
} |
@@ -31,7 +31,9 @@ use OCP\DB\Types; | |||
use OCP\Migration\IOutput; | |||
use OCP\Migration\SimpleMigrationStep; | |||
// Create new field in appconfig for the new IAppConfig API, including lazy grouping. | |||
/** | |||
* Create new fields for type and lazy loading in appconfig for the new IAppConfig API. | |||
*/ | |||
class Version29000Date20231126110901 extends SimpleMigrationStep { | |||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { | |||
/** @var ISchemaWrapper $schema */ |
@@ -46,30 +46,26 @@ use OCP\Exceptions\AppConfigUnknownKeyException; | |||
use OCP\IAppConfig; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use OCP\Util; | |||
use Psr\Log\LoggerInterface; | |||
/** | |||
* This class provides an easy way for apps to store config values in the | |||
* database. | |||
* | |||
* **Note:** since 29.0.0, it supports **lazy grouping** | |||
* **Note:** since 29.0.0, it supports **lazy loading** | |||
* | |||
* ### What is lazy grouping ? | |||
* In order to avoid loading useless config values in memory for each request on | |||
* the cloud, it has been made possible to group your config keys. | |||
* Each group, called _lazy group_, is only loaded in memory when one its config | |||
* keys is retrieved. | |||
* ### What is lazy loading ? | |||
* In order to avoid loading useless config values into memory for each request, | |||
* only non-lazy values are now loaded. | |||
* | |||
* It is advised to only use the default lazy group, named '' (empty string), for | |||
* config keys used in the registered part of your code that is called even when | |||
* your app is not boot (as in event listeners, ...) | |||
* Once a value that is lazy is requested, all lazy values will be loaded. | |||
* | |||
* **WARNING:** some methods from this class are marked with a warning about ignoring | |||
* lazy grouping, use them wisely and only on part of code called during | |||
* specific request/action | |||
* Similarly, some methods from this class are marked with a warning about ignoring | |||
* lazy loading. Use them wisely and only on parts of the code that are called | |||
* during specific requests or actions to avoid loading the lazy values all the time. | |||
* | |||
* @since 7.0.0 | |||
* @since 29.0.0 - Supporting types and lazy loading | |||
*/ | |||
class AppConfig implements IAppConfig { | |||
private const APP_MAX_LENGTH = 32; | |||
@@ -149,12 +145,10 @@ class AppConfig implements IAppConfig { | |||
} | |||
if ($lazy) { | |||
$cache = &$this->lazyCache; | |||
} else { | |||
$cache = &$this->fastCache; | |||
return isset($this->lazyCache[$app][$key]); | |||
} | |||
return isset($cache[$app][$key]); | |||
return isset($this->fastCache[$app][$key]); | |||
} | |||
/** | |||
@@ -254,9 +248,9 @@ class AppConfig implements IAppConfig { | |||
/** @var array<array-key, array<array-key, mixed>> $cache */ | |||
if ($lazy) { | |||
$cache = &$this->lazyCache; | |||
$cache = $this->lazyCache; | |||
} else { | |||
$cache = &$this->fastCache; | |||
$cache = $this->fastCache; | |||
} | |||
foreach (array_keys($cache) as $app) { | |||
@@ -270,12 +264,12 @@ class AppConfig implements IAppConfig { | |||
/** | |||
* Get any config value, will be returned as string. | |||
* If value does not exist, will return $default | |||
* Get the config value as string. | |||
* If the value does not exist the given default will be returned. | |||
* | |||
* $lazy can be NULL to ignore lazy loading | |||
* Set lazy to `null` to ignore it and get the value from either source. | |||
* | |||
* **WARNING:** Method is internal and **MUST** not be used as it is best to set a real value type | |||
* **WARNING:** Method is internal and **SHOULD** not be used, as it is better to get the value with a type. | |||
* | |||
* @param string $app id of the app | |||
* @param string $key config key | |||
@@ -285,13 +279,12 @@ class AppConfig implements IAppConfig { | |||
* @return string the value or $default | |||
* @internal | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
* @see setValueArray() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueMixed( | |||
string $app, | |||
@@ -321,11 +314,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException in case of conflict with the value type set in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueString( | |||
string $app, | |||
@@ -349,11 +337,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException in case of conflict with the value type set in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueInt( | |||
string $app, | |||
@@ -364,34 +347,6 @@ class AppConfig implements IAppConfig { | |||
return (int)$this->getTypedValue($app, $key, (string)$default, $lazy, self::VALUE_INT); | |||
} | |||
/** | |||
* @inheritDoc | |||
* | |||
* @param string $app id of the app | |||
* @param string $key config key | |||
* @param int|float $default default value | |||
* @param bool $lazy search within lazy loaded config | |||
* | |||
* @return int|float stored config value or $default if not set in database | |||
* @throws InvalidArgumentException if one of the argument format is invalid | |||
* @throws AppConfigTypeConflictException in case of conflict with the value type set in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueBigInt( | |||
string $app, | |||
string $key, | |||
int|float $default = 0, | |||
bool $lazy = false | |||
): int|float { | |||
return Util::numericToNumber($this->getTypedValue($app, $key, (string)$default, $lazy, self::VALUE_INT)); | |||
} | |||
/** | |||
* @inheritDoc | |||
* | |||
@@ -405,11 +360,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException in case of conflict with the value type set in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueFloat(string $app, string $key, float $default = 0, bool $lazy = false): float { | |||
return (float)$this->getTypedValue($app, $key, (string)$default, $lazy, self::VALUE_FLOAT); | |||
@@ -428,11 +378,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException in case of conflict with the value type set in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueBool(string $app, string $key, bool $default = false, bool $lazy = false): bool { | |||
$b = strtolower($this->getTypedValue($app, $key, $default ? 'true' : 'false', $lazy, self::VALUE_BOOL)); | |||
@@ -452,11 +397,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException in case of conflict with the value type set in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
*/ | |||
public function getValueArray( | |||
string $app, | |||
@@ -510,12 +450,10 @@ class AppConfig implements IAppConfig { | |||
} | |||
if ($lazy) { | |||
$cache = &$this->lazyCache; | |||
} else { | |||
$cache = &$this->fastCache; | |||
return $this->lazyCache[$app][$key] ?? $default; | |||
} | |||
return $cache[$app][$key] ?? $default; | |||
return $this->fastCache[$app][$key] ?? $default; | |||
} | |||
/** | |||
@@ -537,7 +475,11 @@ class AppConfig implements IAppConfig { | |||
$this->assertParams($app, $key); | |||
$this->loadConfigAll(); | |||
$type = $this->valueTypes[$app][$key] ?? throw new AppConfigUnknownKeyException('unknown config key'); | |||
if (!isset($this->valueTypes[$app][$key])) { | |||
throw new AppConfigUnknownKeyException('unknown config key'); | |||
} | |||
$type = $this->valueTypes[$app][$key]; | |||
$type &= ~self::VALUE_SENSITIVE; | |||
return $type; | |||
} | |||
@@ -558,10 +500,9 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException if type from database is not VALUE_MIXED | |||
* @internal | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
@@ -596,11 +537,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException if type from database is not VALUE_MIXED and different from the requested one | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
*/ | |||
public function setValueString( | |||
string $app, | |||
@@ -631,11 +567,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException if type from database is not VALUE_MIXED and different from the requested one | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
*/ | |||
public function setValueInt( | |||
string $app, | |||
@@ -644,42 +575,10 @@ class AppConfig implements IAppConfig { | |||
bool $lazy = false, | |||
bool $sensitive = false | |||
): bool { | |||
return $this->setTypedValue( | |||
$app, | |||
$key, | |||
(string)$value, | |||
$lazy, | |||
self::VALUE_INT | ($sensitive ? self::VALUE_SENSITIVE : 0) | |||
); | |||
} | |||
if ($value > 2147400000) { | |||
$this->logger->debug('You are trying to store an integer value around/above 2,147,483,647. This is a reminder that reaching this theoretical limit on 32 bits system will result to an exception.'); | |||
} | |||
/** | |||
* @inheritDoc | |||
* | |||
* @param string $app id of the app | |||
* @param string $key config key | |||
* @param int|float $value config value | |||
* @param bool $lazy set config as lazy loaded | |||
* @param bool $sensitive if TRUE value will be hidden when listing config values. | |||
* | |||
* @return bool TRUE if value was different, therefor updated in database | |||
* @throws AppConfigTypeConflictException if type from database is not VALUE_MIXED and different from the requested one | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
*/ | |||
public function setValueBigInt( | |||
string $app, | |||
string $key, | |||
int|float $value, | |||
bool $lazy = false, | |||
bool $sensitive = false | |||
): bool { | |||
return $this->setTypedValue( | |||
$app, | |||
$key, | |||
@@ -689,7 +588,6 @@ class AppConfig implements IAppConfig { | |||
); | |||
} | |||
/** | |||
* @inheritDoc | |||
* | |||
@@ -703,11 +601,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException if type from database is not VALUE_MIXED and different from the requested one | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
*/ | |||
public function setValueFloat( | |||
string $app, | |||
@@ -737,11 +630,6 @@ class AppConfig implements IAppConfig { | |||
* @throws AppConfigTypeConflictException if type from database is not VALUE_MIXED and different from the requested one | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueArray() | |||
*/ | |||
public function setValueBool( | |||
string $app, | |||
@@ -772,11 +660,6 @@ class AppConfig implements IAppConfig { | |||
* @throws JsonException | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
*/ | |||
public function setValueArray( | |||
string $app, | |||
@@ -859,6 +742,15 @@ class AppConfig implements IAppConfig { | |||
$currType = $this->valueTypes[$app][$key] ?? 0; | |||
} | |||
/** | |||
* This should only happen during the upgrade process from 28 to 29. | |||
* We only log a warning and set it to VALUE_MIXED. | |||
*/ | |||
if ($currType === 0) { | |||
$this->logger->warning('Value type is set to zero (0) in database. This is fine only during the upgrade process from 28 to 29.', ['app' => $app, 'key' => $key]); | |||
$currType = self::VALUE_MIXED; | |||
} | |||
/** | |||
* we only accept a different type from the one stored in database | |||
* if the one stored in database is not-defined (VALUE_MIXED) | |||
@@ -869,6 +761,7 @@ class AppConfig implements IAppConfig { | |||
$currType = $this->convertTypeToString($currType); | |||
$type = $this->convertTypeToString($type); | |||
} catch (AppConfigIncorrectTypeException) { | |||
// can be ignored, this was just needed for a better exception message. | |||
} | |||
throw new AppConfigTypeConflictException('conflict between new type (' . $type . ') and old type (' . $currType . ')'); | |||
} | |||
@@ -1049,9 +942,9 @@ class AppConfig implements IAppConfig { | |||
$lazy = $this->isLazy($app, $key); | |||
if ($lazy) { | |||
$cache = &$this->lazyCache; | |||
$cache = $this->lazyCache; | |||
} else { | |||
$cache = &$this->fastCache; | |||
$cache = $this->fastCache; | |||
} | |||
$type = $this->getValueType($app, $key); | |||
@@ -1066,8 +959,8 @@ class AppConfig implements IAppConfig { | |||
'app' => $app, | |||
'key' => $key, | |||
'value' => $cache[$app][$key] ?? throw new AppConfigUnknownKeyException('unknown config key'), | |||
'lazy' => $lazy, | |||
'type' => $type, | |||
'lazy' => $lazy, | |||
'typeString' => $typeString, | |||
'sensitive' => $this->isSensitive($app, $key, null) | |||
]; | |||
@@ -1197,7 +1090,7 @@ class AppConfig implements IAppConfig { | |||
} | |||
/** | |||
* Confirm the string set for app, key and lazyGroup fit the database description | |||
* Confirm the string set for app and key fit the database description | |||
* | |||
* @param string $app assert $app fit in database | |||
* @param string $configKey assert config key fit in database |
@@ -38,31 +38,32 @@ use OCP\Exceptions\AppConfigUnknownKeyException; | |||
* **Note:** since 29.0.0, it supports **lazy loading** | |||
* | |||
* ### What is lazy loading ? | |||
* In order to avoid loading useless config values into memory for each request, | |||
* only non-lazy values are now loaded. | |||
* | |||
* By default, app config values are all loaded in memory; but in order to avoid | |||
* loading useless config values in memory on each request on the cloud, it has | |||
* been made possible to set your config keys as lazy. | |||
* When set as lazy, the values will only be loaded in memory when needed. | |||
* In fact, the cloud will load all config set as lazy loaded when a first one | |||
* is requested. | |||
* Once a value that is lazy is requested, all lazy values will be loaded. | |||
* | |||
* It is advised to set a config key as lazy when its value is only needed during | |||
* really specific request, in part of code that is not called frequently. | |||
* Similarly, some methods from this class are marked with a warning about ignoring | |||
* lazy loading. Use them wisely and only on parts of the code that are called | |||
* during specific requests or actions to avoid loading the lazy values all the time. | |||
* | |||
* **Note:** some methods from this class are marked with a warning about ignoring | |||
* lazy filtering, meaning it will load in memory all apps config values. use them | |||
* wisely and only in part of code called during specific request/action. | |||
* | |||
* @since 29.0.0 supports lazy loading | |||
* @since 7.0.0 | |||
* @since 29.0.0 - Supporting types and lazy loading | |||
*/ | |||
interface IAppConfig { | |||
/** @since 29.0.0 */ | |||
public const VALUE_SENSITIVE = 1; | |||
/** @since 29.0.0 */ | |||
public const VALUE_MIXED = 2; | |||
/** @since 29.0.0 */ | |||
public const VALUE_STRING = 4; | |||
/** @since 29.0.0 */ | |||
public const VALUE_INT = 8; | |||
/** @since 29.0.0 */ | |||
public const VALUE_FLOAT = 16; | |||
/** @since 29.0.0 */ | |||
public const VALUE_BOOL = 32; | |||
/** @since 29.0.0 */ | |||
public const VALUE_ARRAY = 64; | |||
/** | |||
@@ -170,7 +171,6 @@ interface IAppConfig { | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
@@ -191,34 +191,12 @@ interface IAppConfig { | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueInt(string $app, string $key, int $default = 0, bool $lazy = false): int; | |||
/** | |||
* Get config value assigned to a config key. | |||
* If config key is not found in database, default value is returned. | |||
* If config key is set as lazy loaded, the $lazy argument needs to be set to TRUE. | |||
* | |||
* @param string $app id of the app | |||
* @param string $key config key | |||
* @param int|float $default default value | |||
* @param bool $lazy search within lazy loaded config | |||
* | |||
* @return int|float stored config value or $default if not set in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
*/ | |||
public function getValueBigInt(string $app, string $key, int|float $default = 0, bool $lazy = false): int|float; | |||
/** | |||
* Get config value assigned to a config key. | |||
* If config key is not found in database, default value is returned. | |||
@@ -234,7 +212,6 @@ interface IAppConfig { | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueBool() | |||
* @see getValueArray() | |||
*/ | |||
@@ -255,7 +232,6 @@ interface IAppConfig { | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueArray() | |||
*/ | |||
@@ -276,7 +252,6 @@ interface IAppConfig { | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see getValueString() | |||
* @see getValueInt() | |||
* @see getValueBigInt() | |||
* @see getValueFloat() | |||
* @see getValueBool() | |||
*/ | |||
@@ -317,9 +292,8 @@ interface IAppConfig { | |||
* | |||
* @return bool TRUE if value was different, therefor updated in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
@@ -329,31 +303,10 @@ interface IAppConfig { | |||
/** | |||
* Store a config key and its value in database | |||
* | |||
* If config key is already known with the exact same config value, the database is not updated. | |||
* If config key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded. | |||
* When handling huge value around and/or above 2,147,483,647, a debug log will be generated | |||
* on 64bits system, as php int type reach its limit (and throw an exception) on 32bits when using huge numbers. | |||
* | |||
* If config value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first | |||
* | |||
* @param string $app id of the app | |||
* @param string $key config key | |||
* @param int $value config value | |||
* @param bool $sensitive if TRUE value will be hidden when listing config values. | |||
* @param bool $lazy set config as lazy loaded | |||
* | |||
* @return bool TRUE if value was different, therefor updated in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see setValueString() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
*/ | |||
public function setValueInt(string $app, string $key, int $value, bool $lazy = false, bool $sensitive = false): bool; | |||
/** | |||
* Store a config key and its value in database | |||
* When using huge numbers, it is advised to use {@see \OCP\Util::numericToNumber()} and {@see setValueString()} | |||
* | |||
* If config key is already known with the exact same config value, the database is not updated. | |||
* If config key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded. | |||
@@ -362,23 +315,22 @@ interface IAppConfig { | |||
* | |||
* @param string $app id of the app | |||
* @param string $key config key | |||
* @param int|float $value config value | |||
* @param int $value config value | |||
* @param bool $sensitive if TRUE value will be hidden when listing config values. | |||
* @param bool $lazy set config as lazy loaded | |||
* | |||
* @return bool TRUE if value was different, therefor updated in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
*/ | |||
public function setValueBigInt(string $app, string $key, int|float $value, bool $lazy = false, bool $sensitive = false): bool; | |||
public function setValueInt(string $app, string $key, int $value, bool $lazy = false, bool $sensitive = false): bool; | |||
/** | |||
* Store a config key and its value in database | |||
* Store a config key and its value in database. | |||
* | |||
* If config key is already known with the exact same config value, the database is not updated. | |||
* If config key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded. | |||
@@ -393,10 +345,9 @@ interface IAppConfig { | |||
* | |||
* @return bool TRUE if value was different, therefor updated in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueBool() | |||
* @see setValueArray() | |||
*/ | |||
@@ -417,10 +368,9 @@ interface IAppConfig { | |||
* | |||
* @return bool TRUE if value was different, therefor updated in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueArray() | |||
*/ | |||
@@ -442,10 +392,9 @@ interface IAppConfig { | |||
* | |||
* @return bool TRUE if value was different, therefor updated in database | |||
* @since 29.0.0 | |||
* @see IAppConfig for explanation about lazy grouping | |||
* @see IAppConfig for explanation about lazy loading | |||
* @see setValueString() | |||
* @see setValueInt() | |||
* @see setValueBigInt() | |||
* @see setValueFloat() | |||
* @see setValueBool() | |||
*/ |