]> source.dussan.org Git - nextcloud-server.git/commitdiff
feat(user-prefs): switching to NCU/
authorMaxence Lange <maxence@artificial-owl.com>
Tue, 12 Nov 2024 22:29:18 +0000 (21:29 -0100)
committerMaxence Lange <maxence@artificial-owl.com>
Mon, 18 Nov 2024 21:11:31 +0000 (20:11 -0100)
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
16 files changed:
lib/composer/composer/autoload_classmap.php
lib/composer/composer/autoload_static.php
lib/private/AllConfig.php
lib/private/Config/UserPreferences.php
lib/private/Server.php
lib/public/Config/Exceptions/IncorrectTypeException.php [deleted file]
lib/public/Config/Exceptions/TypeConflictException.php [deleted file]
lib/public/Config/Exceptions/UnknownKeyException.php [deleted file]
lib/public/Config/IUserPreferences.php [deleted file]
lib/public/Config/ValueType.php [deleted file]
lib/unstable/Config/Exceptions/IncorrectTypeException.php [new file with mode: 0644]
lib/unstable/Config/Exceptions/TypeConflictException.php [new file with mode: 0644]
lib/unstable/Config/Exceptions/UnknownKeyException.php [new file with mode: 0644]
lib/unstable/Config/IUserPreferences.php [new file with mode: 0644]
lib/unstable/Config/ValueType.php [new file with mode: 0644]
tests/lib/UserPreferencesTest.php

index c3abaefd56c55623e988ffafab9f48326ed2be4b..7ba1e0e4667b161501629287ce84aec6e90352af 100644 (file)
@@ -7,6 +7,11 @@ $baseDir = dirname(dirname($vendorDir));
 
 return array(
     'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+    'NCU\\Config\\Exceptions\\IncorrectTypeException' => $baseDir . '/lib/unstable/Config/Exceptions/IncorrectTypeException.php',
+    'NCU\\Config\\Exceptions\\TypeConflictException' => $baseDir . '/lib/unstable/Config/Exceptions/TypeConflictException.php',
+    'NCU\\Config\\Exceptions\\UnknownKeyException' => $baseDir . '/lib/unstable/Config/Exceptions/UnknownKeyException.php',
+    'NCU\\Config\\IUserPreferences' => $baseDir . '/lib/unstable/Config/IUserPreferences.php',
+    'NCU\\Config\\ValueType' => $baseDir . '/lib/unstable/Config/ValueType.php',
     'OCP\\Accounts\\IAccount' => $baseDir . '/lib/public/Accounts/IAccount.php',
     'OCP\\Accounts\\IAccountManager' => $baseDir . '/lib/public/Accounts/IAccountManager.php',
     'OCP\\Accounts\\IAccountProperty' => $baseDir . '/lib/public/Accounts/IAccountProperty.php',
@@ -223,11 +228,6 @@ return array(
     'OCP\\Common\\Exception\\NotFoundException' => $baseDir . '/lib/public/Common/Exception/NotFoundException.php',
     'OCP\\Config\\BeforePreferenceDeletedEvent' => $baseDir . '/lib/public/Config/BeforePreferenceDeletedEvent.php',
     'OCP\\Config\\BeforePreferenceSetEvent' => $baseDir . '/lib/public/Config/BeforePreferenceSetEvent.php',
-    'OCP\\Config\\Exceptions\\IncorrectTypeException' => $baseDir . '/lib/public/Config/Exceptions/IncorrectTypeException.php',
-    'OCP\\Config\\Exceptions\\TypeConflictException' => $baseDir . '/lib/public/Config/Exceptions/TypeConflictException.php',
-    'OCP\\Config\\Exceptions\\UnknownKeyException' => $baseDir . '/lib/public/Config/Exceptions/UnknownKeyException.php',
-    'OCP\\Config\\IUserPreferences' => $baseDir . '/lib/public/Config/IUserPreferences.php',
-    'OCP\\Config\\ValueType' => $baseDir . '/lib/public/Config/ValueType.php',
     'OCP\\Console\\ConsoleEvent' => $baseDir . '/lib/public/Console/ConsoleEvent.php',
     'OCP\\Console\\ReservedOptions' => $baseDir . '/lib/public/Console/ReservedOptions.php',
     'OCP\\Constants' => $baseDir . '/lib/public/Constants.php',
index cf821ddeba05823b6c52fcfa602fab0ddabfd045..cf1d395fd4378db08d33171f4cc1337b239e22cc 100644 (file)
@@ -48,6 +48,11 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
 
     public static $classMap = array (
         'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+        'NCU\\Config\\Exceptions\\IncorrectTypeException' => __DIR__ . '/../../..' . '/lib/unstable/Config/Exceptions/IncorrectTypeException.php',
+        'NCU\\Config\\Exceptions\\TypeConflictException' => __DIR__ . '/../../..' . '/lib/unstable/Config/Exceptions/TypeConflictException.php',
+        'NCU\\Config\\Exceptions\\UnknownKeyException' => __DIR__ . '/../../..' . '/lib/unstable/Config/Exceptions/UnknownKeyException.php',
+        'NCU\\Config\\IUserPreferences' => __DIR__ . '/../../..' . '/lib/unstable/Config/IUserPreferences.php',
+        'NCU\\Config\\ValueType' => __DIR__ . '/../../..' . '/lib/unstable/Config/ValueType.php',
         'OCP\\Accounts\\IAccount' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccount.php',
         'OCP\\Accounts\\IAccountManager' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccountManager.php',
         'OCP\\Accounts\\IAccountProperty' => __DIR__ . '/../../..' . '/lib/public/Accounts/IAccountProperty.php',
@@ -264,11 +269,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
         'OCP\\Common\\Exception\\NotFoundException' => __DIR__ . '/../../..' . '/lib/public/Common/Exception/NotFoundException.php',
         'OCP\\Config\\BeforePreferenceDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Config/BeforePreferenceDeletedEvent.php',
         'OCP\\Config\\BeforePreferenceSetEvent' => __DIR__ . '/../../..' . '/lib/public/Config/BeforePreferenceSetEvent.php',
-        'OCP\\Config\\Exceptions\\IncorrectTypeException' => __DIR__ . '/../../..' . '/lib/public/Config/Exceptions/IncorrectTypeException.php',
-        'OCP\\Config\\Exceptions\\TypeConflictException' => __DIR__ . '/../../..' . '/lib/public/Config/Exceptions/TypeConflictException.php',
-        'OCP\\Config\\Exceptions\\UnknownKeyException' => __DIR__ . '/../../..' . '/lib/public/Config/Exceptions/UnknownKeyException.php',
-        'OCP\\Config\\IUserPreferences' => __DIR__ . '/../../..' . '/lib/public/Config/IUserPreferences.php',
-        'OCP\\Config\\ValueType' => __DIR__ . '/../../..' . '/lib/public/Config/ValueType.php',
         'OCP\\Console\\ConsoleEvent' => __DIR__ . '/../../..' . '/lib/public/Console/ConsoleEvent.php',
         'OCP\\Console\\ReservedOptions' => __DIR__ . '/../../..' . '/lib/public/Console/ReservedOptions.php',
         'OCP\\Constants' => __DIR__ . '/../../..' . '/lib/public/Constants.php',
index 8f7e5359c967fb80830a72a6e724b8306c9b7513..dbea65fdc217228dc08ab92d4ee70d623daeb870 100644 (file)
@@ -6,11 +6,11 @@
  */
 namespace OC;
 
+use NCU\Config\Exceptions\TypeConflictException;
+use NCU\Config\IUserPreferences;
+use NCU\Config\ValueType;
 use OC\Config\UserPreferences;
 use OCP\Cache\CappedMemoryCache;
-use OCP\Config\Exceptions\TypeConflictException;
-use OCP\Config\IUserPreferences;
-use OCP\Config\ValueType;
 use OCP\IConfig;
 use OCP\IDBConnection;
 use OCP\PreConditionNotMetException;
index 6dd9c633836715d67b6063532b7679b86df26f85..d9fd5f6a0649929ec89ea258df9023a903b97612 100644 (file)
@@ -11,11 +11,11 @@ namespace OC\Config;
 use Generator;
 use InvalidArgumentException;
 use JsonException;
-use OCP\Config\Exceptions\IncorrectTypeException;
-use OCP\Config\Exceptions\TypeConflictException;
-use OCP\Config\Exceptions\UnknownKeyException;
-use OCP\Config\IUserPreferences;
-use OCP\Config\ValueType;
+use NCU\Config\Exceptions\IncorrectTypeException;
+use NCU\Config\Exceptions\TypeConflictException;
+use NCU\Config\Exceptions\UnknownKeyException;
+use NCU\Config\IUserPreferences;
+use NCU\Config\ValueType;
 use OCP\DB\Exception as DBException;
 use OCP\DB\IResult;
 use OCP\DB\QueryBuilder\IQueryBuilder;
index e109636f1fad4ec2a43fa9bae54ad36ba88750b5..dc4b3c4f7dc7a83e8c28c9c0274aec1ab51b89cb 100644 (file)
@@ -7,6 +7,7 @@
 namespace OC;
 
 use bantu\IniGetWrapper\IniGetWrapper;
+use NCU\Config\IUserPreferences;
 use OC\Accounts\AccountManager;
 use OC\App\AppManager;
 use OC\App\AppStore\Bundles\BundleFetcher;
@@ -138,7 +139,6 @@ use OCP\Collaboration\AutoComplete\IManager;
 use OCP\Collaboration\Reference\IReferenceManager;
 use OCP\Command\IBus;
 use OCP\Comments\ICommentsManager;
-use OCP\Config\IUserPreferences;
 use OCP\Contacts\ContactsMenu\IActionFactory;
 use OCP\Contacts\ContactsMenu\IContactsStore;
 use OCP\Defaults;
diff --git a/lib/public/Config/Exceptions/IncorrectTypeException.php b/lib/public/Config/Exceptions/IncorrectTypeException.php
deleted file mode 100644 (file)
index dafbbac..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-namespace OCP\Config\Exceptions;
-
-use Exception;
-
-/**
- * @since 31.0.0
- */
-class IncorrectTypeException extends Exception {
-}
diff --git a/lib/public/Config/Exceptions/TypeConflictException.php b/lib/public/Config/Exceptions/TypeConflictException.php
deleted file mode 100644 (file)
index 0b3c903..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-namespace OCP\Config\Exceptions;
-
-use Exception;
-
-/**
- * @since 31.0.0
- */
-class TypeConflictException extends Exception {
-}
diff --git a/lib/public/Config/Exceptions/UnknownKeyException.php b/lib/public/Config/Exceptions/UnknownKeyException.php
deleted file mode 100644 (file)
index 2150246..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-namespace OCP\Config\Exceptions;
-
-use Exception;
-
-/**
- * @since 31.0.0
- */
-class UnknownKeyException extends Exception {
-}
diff --git a/lib/public/Config/IUserPreferences.php b/lib/public/Config/IUserPreferences.php
deleted file mode 100644 (file)
index 18c7fdc..0000000
+++ /dev/null
@@ -1,694 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-namespace OCP\Config;
-
-use Generator;
-use OCP\Config\Exceptions\IncorrectTypeException;
-use OCP\Config\Exceptions\UnknownKeyException;
-
-/**
- * This class provides an easy way for apps to store user preferences in the
- * database.
- * Supports **lazy loading**
- *
- * ### What is lazy loading ?
- * In order to avoid loading useless user preferences into memory for each request,
- * only non-lazy values are now loaded.
- *
- * Once a value that is lazy is requested, all lazy values will be loaded.
- *
- * 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 31.0.0
- */
-
-interface IUserPreferences {
-       /** @since 31.0.0 */
-       public const FLAG_SENSITIVE = 1;   // value is sensitive
-       /** @since 31.0.0 */
-       public const FLAG_INDEXED = 2;    // value should be indexed
-
-       /**
-        * Get list of all userIds with preferences stored in database.
-        * If $appId is specified, will only limit the search to this value
-        *
-        * **WARNING:** ignore any cache and get data directly from database.
-        *
-        * @param string $appId optional id of app
-        *
-        * @return list<string> list of userIds
-        * @since 31.0.0
-        */
-       public function getUserIds(string $appId = ''): array;
-
-       /**
-        * Get list of all apps that have at least one preference
-        * value related to $userId stored in database
-        *
-        * **WARNING:** ignore lazy filtering, all user preferences are loaded from database
-        *
-        * @param string $userId id of the user
-        *
-        * @return list<string> list of app ids
-        * @since 31.0.0
-        */
-       public function getApps(string $userId): array;
-
-       /**
-        * Returns all keys stored in database, related to user+app.
-        * Please note that the values are not returned.
-        *
-        * **WARNING:** ignore lazy filtering, all user preferences are loaded from database
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        *
-        * @return list<string> list of stored preference keys
-        * @since 31.0.0
-        */
-       public function getKeys(string $userId, string $app): array;
-
-       /**
-        * Check if a key exists in the list of stored preference values.
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $lazy search within lazy loaded preferences
-        *
-        * @return bool TRUE if key exists
-        * @since 31.0.0
-        */
-       public function hasKey(string $userId, string $app, string $key, ?bool $lazy = false): bool;
-
-       /**
-        * best way to see if a value is set as sensitive (not displayed in report)
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool|null $lazy search within lazy loaded preferences
-        *
-        * @return bool TRUE if value is sensitive
-        * @throws UnknownKeyException if preference key is not known
-        * @since 31.0.0
-        */
-       public function isSensitive(string $userId, string $app, string $key, ?bool $lazy = false): bool;
-
-       /**
-        * best way to see if a value is set as indexed (so it can be search)
-        *
-        * @see self::searchUsersByValueString()
-        * @see self::searchUsersByValueInt()
-        * @see self::searchUsersByValueBool()
-        * @see self::searchUsersByValues()
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool|null $lazy search within lazy loaded preferences
-        *
-        * @return bool TRUE if value is sensitive
-        * @throws UnknownKeyException if preference key is not known
-        * @since 31.0.0
-        */
-       public function isIndexed(string $userId, string $app, string $key, ?bool $lazy = false): bool;
-
-       /**
-        * Returns if the preference key stored in database is lazy loaded
-        *
-        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        *
-        * @return bool TRUE if preference is lazy loaded
-        * @throws UnknownKeyException if preference key is not known
-        * @see IUserPreferences for details about lazy loading
-        * @since 31.0.0
-        */
-       public function isLazy(string $userId, string $app, string $key): bool;
-
-       /**
-        * List all preference values from an app with preference key starting with $key.
-        * Returns an array with preference key as key, stored value as value.
-        *
-        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $prefix preference keys prefix to search, can be empty.
-        * @param bool $filtered filter sensitive preference values
-        *
-        * @return array<string, string|int|float|bool|array> [key => value]
-        * @since 31.0.0
-        */
-       public function getValues(string $userId, string $app, string $prefix = '', bool $filtered = false): array;
-
-       /**
-        * List all preference values of a user.
-        * Returns an array with preference key as key, stored value as value.
-        *
-        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
-        *
-        * @param string $userId id of the user
-        * @param bool $filtered filter sensitive preference values
-        *
-        * @return array<string, string|int|float|bool|array> [key => value]
-        * @since 31.0.0
-        */
-       public function getAllValues(string $userId, bool $filtered = false): array;
-
-       /**
-        * List all apps storing a specific preference key and its stored value.
-        * Returns an array with appId as key, stored value as value.
-        *
-        * @param string $userId id of the user
-        * @param string $key preference key
-        * @param bool $lazy search within lazy loaded preferences
-        * @param ValueType|null $typedAs enforce type for the returned values
-        *
-        * @return array<string, string|int|float|bool|array> [appId => value]
-        * @since 31.0.0
-        */
-       public function getValuesByApps(string $userId, string $key, bool $lazy = false, ?ValueType $typedAs = null): array;
-
-       /**
-        * List all users storing a specific preference key and its stored value.
-        * Returns an array with userId as key, stored value as value.
-        *
-        * **WARNING:** no caching, generate a fresh request
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param ValueType|null $typedAs enforce type for the returned values
-        * @param array|null $userIds limit the search to a list of user ids
-        *
-        * @return array<string, string|int|float|bool|array> [userId => value]
-        * @since 31.0.0
-        */
-       public function getValuesByUsers(string $app, string $key, ?ValueType $typedAs = null, ?array $userIds = null): array;
-
-       /**
-        * List all users storing a specific preference key/value pair.
-        * Returns a list of user ids.
-        *
-        * **WARNING:** no caching, generate a fresh request
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param string $value preference value
-        * @param bool $caseInsensitive non-case-sensitive search, only works if $value is a string
-        *
-        * @return Generator<string>
-        * @since 31.0.0
-        */
-       public function searchUsersByValueString(string $app, string $key, string $value, bool $caseInsensitive = false): Generator;
-
-       /**
-        * List all users storing a specific preference key/value pair.
-        * Returns a list of user ids.
-        *
-        * **WARNING:** no caching, generate a fresh request
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param int $value preference value
-        *
-        * @return Generator<string>
-        * @since 31.0.0
-        */
-       public function searchUsersByValueInt(string $app, string $key, int $value): Generator;
-
-       /**
-        * List all users storing a specific preference key/value pair.
-        * Returns a list of user ids.
-        *
-        * **WARNING:** no caching, generate a fresh request
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param array $values list of possible preference values
-        *
-        * @return Generator<string>
-        * @since 31.0.0
-        */
-       public function searchUsersByValues(string $app, string $key, array $values): Generator;
-
-       /**
-        * List all users storing a specific preference key/value pair.
-        * Returns a list of user ids.
-        *
-        * **WARNING:** no caching, generate a fresh request
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $value preference value
-        *
-        * @return Generator<string>
-        * @since 31.0.0
-        */
-       public function searchUsersByValueBool(string $app, string $key, bool $value): Generator;
-
-       /**
-        * Get user preference assigned to a preference key.
-        * If preference key is not found in database, default value is returned.
-        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param string $default default value
-        * @param bool $lazy search within lazy loaded preferences
-        *
-        * @return string stored preference value or $default if not set in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see getValueInt()
-        * @see getValueFloat()
-        * @see getValueBool()
-        * @see getValueArray()
-        */
-       public function getValueString(string $userId, string $app, string $key, string $default = '', bool $lazy = false): string;
-
-       /**
-        * Get preference value assigned to a preference key.
-        * If preference key is not found in database, default value is returned.
-        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param int $default default value
-        * @param bool $lazy search within lazy loaded preferences
-        *
-        * @return int stored preference value or $default if not set in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see getValueString()
-        * @see getValueFloat()
-        * @see getValueBool()
-        * @see getValueArray()
-        */
-       public function getValueInt(string $userId, string $app, string $key, int $default = 0, bool $lazy = false): int;
-
-       /**
-        * Get preference value assigned to a preference key.
-        * If preference key is not found in database, default value is returned.
-        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param float $default default value
-        * @param bool $lazy search within lazy loaded preferences
-        *
-        * @return float stored preference value or $default if not set in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see getValueString()
-        * @see getValueInt()
-        * @see getValueBool()
-        * @see getValueArray()
-        */
-       public function getValueFloat(string $userId, string $app, string $key, float $default = 0, bool $lazy = false): float;
-
-       /**
-        * Get preference value assigned to a preference key.
-        * If preference key is not found in database, default value is returned.
-        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $default default value
-        * @param bool $lazy search within lazy loaded preferences
-        *
-        * @return bool stored preference value or $default if not set in database
-        * @since 31.0.0
-        * @see IUserPrefences for explanation about lazy loading
-        * @see getValueString()
-        * @see getValueInt()
-        * @see getValueFloat()
-        * @see getValueArray()
-        */
-       public function getValueBool(string $userId, string $app, string $key, bool $default = false, bool $lazy = false): bool;
-
-       /**
-        * Get preference value assigned to a preference key.
-        * If preference key is not found in database, default value is returned.
-        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param array $default default value`
-        * @param bool $lazy search within lazy loaded preferences
-        *
-        * @return array stored preference value or $default if not set in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see getValueString()
-        * @see getValueInt()
-        * @see getValueFloat()
-        * @see getValueBool()
-        */
-       public function getValueArray(string $userId, string $app, string $key, array $default = [], bool $lazy = false): array;
-
-       /**
-        * returns the type of preference value
-        *
-        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
-        *              unless lazy is set to false
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool|null $lazy
-        *
-        * @return ValueType type of the value
-        * @throws UnknownKeyException if preference key is not known
-        * @throws IncorrectTypeException if preferences value type is not known
-        * @since 31.0.0
-        */
-       public function getValueType(string $userId, string $app, string $key, ?bool $lazy = null): ValueType;
-
-       /**
-        * returns a bitflag related to preference value
-        *
-        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
-        *              unless lazy is set to false
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $lazy lazy loading
-        *
-        * @return int a bitflag in relation to the preference value
-        * @throws UnknownKeyException if preference key is not known
-        * @throws IncorrectTypeException if preferences value type is not known
-        * @since 31.0.0
-        */
-       public function getValueFlags(string $userId, string $app, string $key, bool $lazy = false): int;
-
-       /**
-        * Store a preference key and its value in database
-        *
-        * If preference key is already known with the exact same preference value, the database is not updated.
-        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
-        *
-        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param string $value preference value
-        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
-        * @param bool $lazy set preference as lazy loaded
-        *
-        * @return bool TRUE if value was different, therefor updated in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see setValueInt()
-        * @see setValueFloat()
-        * @see setValueBool()
-        * @see setValueArray()
-        */
-       public function setValueString(string $userId, string $app, string $key, string $value, bool $lazy = false, int $flags = 0): bool;
-
-       /**
-        * Store a preference key and its value in database
-        *
-        * 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.
-        *
-        * When using huge numbers, it is advised to use {@see \OCP\Util::numericToNumber()} and {@see setValueString()}
-        *
-        * If preference key is already known with the exact same preference value, the database is not updated.
-        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
-        *
-        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param int $value preference value
-        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
-        * @param bool $lazy set preference as lazy loaded
-        *
-        * @return bool TRUE if value was different, therefor updated in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see setValueString()
-        * @see setValueFloat()
-        * @see setValueBool()
-        * @see setValueArray()
-        */
-       public function setValueInt(string $userId, string $app, string $key, int $value, bool $lazy = false, int $flags = 0): bool;
-
-       /**
-        * Store a preference key and its value in database.
-        *
-        * If preference key is already known with the exact same preference value, the database is not updated.
-        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
-        *
-        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param float $value preference value
-        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
-        * @param bool $lazy set preference as lazy loaded
-        *
-        * @return bool TRUE if value was different, therefor updated in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see setValueString()
-        * @see setValueInt()
-        * @see setValueBool()
-        * @see setValueArray()
-        */
-       public function setValueFloat(string $userId, string $app, string $key, float $value, bool $lazy = false, int $flags = 0): bool;
-
-       /**
-        * Store a preference key and its value in database
-        *
-        * If preference key is already known with the exact same preference value, the database is not updated.
-        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
-        *
-        * If preference value was previously stored as lazy loaded, status cannot be altered without using {@see deleteKey()} first
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $value preference value
-        * @param bool $lazy set preference as lazy loaded
-        *
-        * @return bool TRUE if value was different, therefor updated in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see setValueString()
-        * @see setValueInt()
-        * @see setValueFloat()
-        * @see setValueArray()
-        */
-       public function setValueBool(string $userId, string $app, string $key, bool $value, bool $lazy = false): bool;
-
-       /**
-        * Store a preference key and its value in database
-        *
-        * If preference key is already known with the exact same preference value, the database is not updated.
-        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
-        *
-        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param array $value preference value
-        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
-        * @param bool $lazy set preference as lazy loaded
-        *
-        * @return bool TRUE if value was different, therefor updated in database
-        * @since 31.0.0
-        * @see IUserPreferences for explanation about lazy loading
-        * @see setValueString()
-        * @see setValueInt()
-        * @see setValueFloat()
-        * @see setValueBool()
-        */
-       public function setValueArray(string $userId, string $app, string $key, array $value, bool $lazy = false, int $flags = 0): bool;
-
-       /**
-        * switch sensitive status of a preference value
-        *
-        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $sensitive TRUE to set as sensitive, FALSE to unset
-        *
-        * @return bool TRUE if database update were necessary
-        * @since 31.0.0
-        */
-       public function updateSensitive(string $userId, string $app, string $key, bool $sensitive): bool;
-
-       /**
-        * switch sensitive loading status of a preference key for all users
-        *
-        * **Warning:** heavy on resources, MUST only be used on occ command or migrations
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $sensitive TRUE to set as sensitive, FALSE to unset
-        *
-        * @since 31.0.0
-        */
-       public function updateGlobalSensitive(string $app, string $key, bool $sensitive): void;
-
-
-       /**
-        * switch indexed status of a preference value
-        *
-        *  **WARNING:** ignore lazy filtering, all preference values are loaded from database
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $indexed TRUE to set as indexed, FALSE to unset
-        *
-        * @return bool TRUE if database update were necessary
-        * @since 31.0.0
-        */
-       public function updateIndexed(string $userId, string $app, string $key, bool $indexed): bool;
-
-       /**
-        * switch sensitive loading status of a preference key for all users
-        *
-        * **Warning:** heavy on resources, MUST only be used on occ command or migrations
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $indexed TRUE to set as indexed, FALSE to unset
-        * @since 31.0.0
-        */
-       public function updateGlobalIndexed(string $app, string $key, bool $indexed): void;
-
-       /**
-        * switch lazy loading status of a preference value
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $lazy TRUE to set as lazy loaded, FALSE to unset
-        *
-        * @return bool TRUE if database update was necessary
-        * @since 31.0.0
-        */
-       public function updateLazy(string $userId, string $app, string $key, bool $lazy): bool;
-
-       /**
-        * switch lazy loading status of a preference key for all users
-        *
-        * **Warning:** heavy on resources, MUST only be used on occ command or migrations
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        * @param bool $lazy TRUE to set as lazy loaded, FALSE to unset
-        * @since 31.0.0
-        */
-       public function updateGlobalLazy(string $app, string $key, bool $lazy): void;
-
-       /**
-        * returns an array contains details about a preference value
-        *
-        * ```
-        * [
-        *   "app" => "myapp",
-        *   "key" => "mykey",
-        *   "value" => "its_value",
-        *   "lazy" => false,
-        *   "type" => 4,
-        *   "typeString" => "string",
-        *   'sensitive' => true
-        * ]
-        * ```
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        *
-        * @return array
-        * @throws UnknownKeyException if preference key is not known in database
-        * @since 31.0.0
-        */
-       public function getDetails(string $userId, string $app, string $key): array;
-
-       /**
-        * Delete single preference key from database.
-        *
-        * @param string $userId id of the user
-        * @param string $app id of the app
-        * @param string $key preference key
-        *
-        * @since 31.0.0
-        */
-       public function deletePreference(string $userId, string $app, string $key): void;
-
-       /**
-        * Delete preference values from all users linked to a specific preference keys
-        *
-        * @param string $app id of the app
-        * @param string $key preference key
-        *
-        * @since 31.0.0
-        */
-       public function deleteKey(string $app, string $key): void;
-
-       /**
-        * delete all preference keys linked to an app
-        *
-        * @param string $app id of the app
-        * @since 31.0.0
-        */
-       public function deleteApp(string $app): void;
-
-       /**
-        * delete all preference keys linked to a user
-        *
-        * @param string $userId id of the user
-        * @since 31.0.0
-        */
-       public function deleteAllPreferences(string $userId): void;
-
-       /**
-        * Clear the cache for a single user
-        *
-        * The cache will be rebuilt only the next time a user preference is requested.
-        *
-        * @param string $userId id of the user
-        * @param bool $reload set to TRUE to refill cache instantly after clearing it
-        *
-        * @since 31.0.0
-        */
-       public function clearCache(string $userId, bool $reload = false): void;
-
-       /**
-        * Clear the cache for all users.
-        * The cache will be rebuilt only the next time a user preference is requested.
-        *
-        * @since 31.0.0
-        */
-       public function clearCacheAll(): void;
-}
diff --git a/lib/public/Config/ValueType.php b/lib/public/Config/ValueType.php
deleted file mode 100644 (file)
index caf5100..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-namespace OCP\Config;
-
-use OCP\Config\Exceptions\IncorrectTypeException;
-use UnhandledMatchError;
-
-/**
- * Listing of available value type for typed config value
- *
- * @since 31.0.0
- */
-enum ValueType: int {
-       /** @since 31.0.0 */
-       case MIXED = 0;
-       /** @since 31.0.0 */
-       case STRING = 1;
-       /** @since 31.0.0 */
-       case INT = 2;
-       /** @since 31.0.0 */
-       case FLOAT = 3;
-       /** @since 31.0.0 */
-       case BOOL = 4;
-       /** @since 31.0.0 */
-       case ARRAY = 5;
-
-       /**
-        * get ValueType from string
-        *
-        * @param string $definition
-        *
-        * @return self
-        * @throws IncorrectTypeException
-        * @since 31.0.0
-        */
-       public static function fromStringDefinition(string $definition): self {
-               try {
-                       return match ($definition) {
-                               'mixed' => self::MIXED,
-                               'string' => self::STRING,
-                               'int' => self::INT,
-                               'float' => self::FLOAT,
-                               'bool' => self::BOOL,
-                               'array' => self::ARRAY
-                       };
-               } catch (\UnhandledMatchError) {
-                       throw new IncorrectTypeException('unknown string definition');
-               }
-       }
-
-       /**
-        * get string definition for current enum value
-        *
-        * @return string
-        * @throws IncorrectTypeException
-        * @since 31.0.0
-        */
-       public function getDefinition(): string {
-               try {
-                       return match ($this) {
-                               self::MIXED => 'mixed',
-                               self::STRING => 'string',
-                               self::INT => 'int',
-                               self::FLOAT => 'float',
-                               self::BOOL => 'bool',
-                               self::ARRAY => 'array',
-                       };
-               } catch (UnhandledMatchError) {
-                       throw new IncorrectTypeException('unknown type definition ' . $this->value);
-               }
-       }
-}
diff --git a/lib/unstable/Config/Exceptions/IncorrectTypeException.php b/lib/unstable/Config/Exceptions/IncorrectTypeException.php
new file mode 100644 (file)
index 0000000..b3eedde
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace NCU\Config\Exceptions;
+
+use Exception;
+
+/**
+ * @since 31.0.0
+ */
+class IncorrectTypeException extends Exception {
+}
diff --git a/lib/unstable/Config/Exceptions/TypeConflictException.php b/lib/unstable/Config/Exceptions/TypeConflictException.php
new file mode 100644 (file)
index 0000000..042991f
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace NCU\Config\Exceptions;
+
+use Exception;
+
+/**
+ * @since 31.0.0
+ */
+class TypeConflictException extends Exception {
+}
diff --git a/lib/unstable/Config/Exceptions/UnknownKeyException.php b/lib/unstable/Config/Exceptions/UnknownKeyException.php
new file mode 100644 (file)
index 0000000..80626c6
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace NCU\Config\Exceptions;
+
+use Exception;
+
+/**
+ * @since 31.0.0
+ */
+class UnknownKeyException extends Exception {
+}
diff --git a/lib/unstable/Config/IUserPreferences.php b/lib/unstable/Config/IUserPreferences.php
new file mode 100644 (file)
index 0000000..a2695a0
--- /dev/null
@@ -0,0 +1,694 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace NCU\Config;
+
+use Generator;
+use NCU\Config\Exceptions\IncorrectTypeException;
+use NCU\Config\Exceptions\UnknownKeyException;
+
+/**
+ * This class provides an easy way for apps to store user preferences in the
+ * database.
+ * Supports **lazy loading**
+ *
+ * ### What is lazy loading ?
+ * In order to avoid loading useless user preferences into memory for each request,
+ * only non-lazy values are now loaded.
+ *
+ * Once a value that is lazy is requested, all lazy values will be loaded.
+ *
+ * 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 31.0.0
+ */
+
+interface IUserPreferences {
+       /** @since 31.0.0 */
+       public const FLAG_SENSITIVE = 1;   // value is sensitive
+       /** @since 31.0.0 */
+       public const FLAG_INDEXED = 2;    // value should be indexed
+
+       /**
+        * Get list of all userIds with preferences stored in database.
+        * If $appId is specified, will only limit the search to this value
+        *
+        * **WARNING:** ignore any cache and get data directly from database.
+        *
+        * @param string $appId optional id of app
+        *
+        * @return list<string> list of userIds
+        * @since 31.0.0
+        */
+       public function getUserIds(string $appId = ''): array;
+
+       /**
+        * Get list of all apps that have at least one preference
+        * value related to $userId stored in database
+        *
+        * **WARNING:** ignore lazy filtering, all user preferences are loaded from database
+        *
+        * @param string $userId id of the user
+        *
+        * @return list<string> list of app ids
+        * @since 31.0.0
+        */
+       public function getApps(string $userId): array;
+
+       /**
+        * Returns all keys stored in database, related to user+app.
+        * Please note that the values are not returned.
+        *
+        * **WARNING:** ignore lazy filtering, all user preferences are loaded from database
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        *
+        * @return list<string> list of stored preference keys
+        * @since 31.0.0
+        */
+       public function getKeys(string $userId, string $app): array;
+
+       /**
+        * Check if a key exists in the list of stored preference values.
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $lazy search within lazy loaded preferences
+        *
+        * @return bool TRUE if key exists
+        * @since 31.0.0
+        */
+       public function hasKey(string $userId, string $app, string $key, ?bool $lazy = false): bool;
+
+       /**
+        * best way to see if a value is set as sensitive (not displayed in report)
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool|null $lazy search within lazy loaded preferences
+        *
+        * @return bool TRUE if value is sensitive
+        * @throws UnknownKeyException if preference key is not known
+        * @since 31.0.0
+        */
+       public function isSensitive(string $userId, string $app, string $key, ?bool $lazy = false): bool;
+
+       /**
+        * best way to see if a value is set as indexed (so it can be search)
+        *
+        * @see self::searchUsersByValueString()
+        * @see self::searchUsersByValueInt()
+        * @see self::searchUsersByValueBool()
+        * @see self::searchUsersByValues()
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool|null $lazy search within lazy loaded preferences
+        *
+        * @return bool TRUE if value is sensitive
+        * @throws UnknownKeyException if preference key is not known
+        * @since 31.0.0
+        */
+       public function isIndexed(string $userId, string $app, string $key, ?bool $lazy = false): bool;
+
+       /**
+        * Returns if the preference key stored in database is lazy loaded
+        *
+        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        *
+        * @return bool TRUE if preference is lazy loaded
+        * @throws UnknownKeyException if preference key is not known
+        * @see IUserPreferences for details about lazy loading
+        * @since 31.0.0
+        */
+       public function isLazy(string $userId, string $app, string $key): bool;
+
+       /**
+        * List all preference values from an app with preference key starting with $key.
+        * Returns an array with preference key as key, stored value as value.
+        *
+        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $prefix preference keys prefix to search, can be empty.
+        * @param bool $filtered filter sensitive preference values
+        *
+        * @return array<string, string|int|float|bool|array> [key => value]
+        * @since 31.0.0
+        */
+       public function getValues(string $userId, string $app, string $prefix = '', bool $filtered = false): array;
+
+       /**
+        * List all preference values of a user.
+        * Returns an array with preference key as key, stored value as value.
+        *
+        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
+        *
+        * @param string $userId id of the user
+        * @param bool $filtered filter sensitive preference values
+        *
+        * @return array<string, string|int|float|bool|array> [key => value]
+        * @since 31.0.0
+        */
+       public function getAllValues(string $userId, bool $filtered = false): array;
+
+       /**
+        * List all apps storing a specific preference key and its stored value.
+        * Returns an array with appId as key, stored value as value.
+        *
+        * @param string $userId id of the user
+        * @param string $key preference key
+        * @param bool $lazy search within lazy loaded preferences
+        * @param ValueType|null $typedAs enforce type for the returned values
+        *
+        * @return array<string, string|int|float|bool|array> [appId => value]
+        * @since 31.0.0
+        */
+       public function getValuesByApps(string $userId, string $key, bool $lazy = false, ?ValueType $typedAs = null): array;
+
+       /**
+        * List all users storing a specific preference key and its stored value.
+        * Returns an array with userId as key, stored value as value.
+        *
+        * **WARNING:** no caching, generate a fresh request
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param ValueType|null $typedAs enforce type for the returned values
+        * @param array|null $userIds limit the search to a list of user ids
+        *
+        * @return array<string, string|int|float|bool|array> [userId => value]
+        * @since 31.0.0
+        */
+       public function getValuesByUsers(string $app, string $key, ?ValueType $typedAs = null, ?array $userIds = null): array;
+
+       /**
+        * List all users storing a specific preference key/value pair.
+        * Returns a list of user ids.
+        *
+        * **WARNING:** no caching, generate a fresh request
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param string $value preference value
+        * @param bool $caseInsensitive non-case-sensitive search, only works if $value is a string
+        *
+        * @return Generator<string>
+        * @since 31.0.0
+        */
+       public function searchUsersByValueString(string $app, string $key, string $value, bool $caseInsensitive = false): Generator;
+
+       /**
+        * List all users storing a specific preference key/value pair.
+        * Returns a list of user ids.
+        *
+        * **WARNING:** no caching, generate a fresh request
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param int $value preference value
+        *
+        * @return Generator<string>
+        * @since 31.0.0
+        */
+       public function searchUsersByValueInt(string $app, string $key, int $value): Generator;
+
+       /**
+        * List all users storing a specific preference key/value pair.
+        * Returns a list of user ids.
+        *
+        * **WARNING:** no caching, generate a fresh request
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param array $values list of possible preference values
+        *
+        * @return Generator<string>
+        * @since 31.0.0
+        */
+       public function searchUsersByValues(string $app, string $key, array $values): Generator;
+
+       /**
+        * List all users storing a specific preference key/value pair.
+        * Returns a list of user ids.
+        *
+        * **WARNING:** no caching, generate a fresh request
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $value preference value
+        *
+        * @return Generator<string>
+        * @since 31.0.0
+        */
+       public function searchUsersByValueBool(string $app, string $key, bool $value): Generator;
+
+       /**
+        * Get user preference assigned to a preference key.
+        * If preference key is not found in database, default value is returned.
+        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param string $default default value
+        * @param bool $lazy search within lazy loaded preferences
+        *
+        * @return string stored preference value or $default if not set in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see getValueInt()
+        * @see getValueFloat()
+        * @see getValueBool()
+        * @see getValueArray()
+        */
+       public function getValueString(string $userId, string $app, string $key, string $default = '', bool $lazy = false): string;
+
+       /**
+        * Get preference value assigned to a preference key.
+        * If preference key is not found in database, default value is returned.
+        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param int $default default value
+        * @param bool $lazy search within lazy loaded preferences
+        *
+        * @return int stored preference value or $default if not set in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see getValueString()
+        * @see getValueFloat()
+        * @see getValueBool()
+        * @see getValueArray()
+        */
+       public function getValueInt(string $userId, string $app, string $key, int $default = 0, bool $lazy = false): int;
+
+       /**
+        * Get preference value assigned to a preference key.
+        * If preference key is not found in database, default value is returned.
+        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param float $default default value
+        * @param bool $lazy search within lazy loaded preferences
+        *
+        * @return float stored preference value or $default if not set in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see getValueString()
+        * @see getValueInt()
+        * @see getValueBool()
+        * @see getValueArray()
+        */
+       public function getValueFloat(string $userId, string $app, string $key, float $default = 0, bool $lazy = false): float;
+
+       /**
+        * Get preference value assigned to a preference key.
+        * If preference key is not found in database, default value is returned.
+        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $default default value
+        * @param bool $lazy search within lazy loaded preferences
+        *
+        * @return bool stored preference value or $default if not set in database
+        * @since 31.0.0
+        * @see IUserPrefences for explanation about lazy loading
+        * @see getValueString()
+        * @see getValueInt()
+        * @see getValueFloat()
+        * @see getValueArray()
+        */
+       public function getValueBool(string $userId, string $app, string $key, bool $default = false, bool $lazy = false): bool;
+
+       /**
+        * Get preference value assigned to a preference key.
+        * If preference key is not found in database, default value is returned.
+        * If preference key is set as lazy loaded, the $lazy argument needs to be set to TRUE.
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param array $default default value`
+        * @param bool $lazy search within lazy loaded preferences
+        *
+        * @return array stored preference value or $default if not set in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see getValueString()
+        * @see getValueInt()
+        * @see getValueFloat()
+        * @see getValueBool()
+        */
+       public function getValueArray(string $userId, string $app, string $key, array $default = [], bool $lazy = false): array;
+
+       /**
+        * returns the type of preference value
+        *
+        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
+        *              unless lazy is set to false
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool|null $lazy
+        *
+        * @return ValueType type of the value
+        * @throws UnknownKeyException if preference key is not known
+        * @throws IncorrectTypeException if preferences value type is not known
+        * @since 31.0.0
+        */
+       public function getValueType(string $userId, string $app, string $key, ?bool $lazy = null): ValueType;
+
+       /**
+        * returns a bitflag related to preference value
+        *
+        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
+        *              unless lazy is set to false
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $lazy lazy loading
+        *
+        * @return int a bitflag in relation to the preference value
+        * @throws UnknownKeyException if preference key is not known
+        * @throws IncorrectTypeException if preferences value type is not known
+        * @since 31.0.0
+        */
+       public function getValueFlags(string $userId, string $app, string $key, bool $lazy = false): int;
+
+       /**
+        * Store a preference key and its value in database
+        *
+        * If preference key is already known with the exact same preference value, the database is not updated.
+        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
+        *
+        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param string $value preference value
+        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
+        * @param bool $lazy set preference as lazy loaded
+        *
+        * @return bool TRUE if value was different, therefor updated in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see setValueInt()
+        * @see setValueFloat()
+        * @see setValueBool()
+        * @see setValueArray()
+        */
+       public function setValueString(string $userId, string $app, string $key, string $value, bool $lazy = false, int $flags = 0): bool;
+
+       /**
+        * Store a preference key and its value in database
+        *
+        * 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.
+        *
+        * When using huge numbers, it is advised to use {@see \OCP\Util::numericToNumber()} and {@see setValueString()}
+        *
+        * If preference key is already known with the exact same preference value, the database is not updated.
+        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
+        *
+        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param int $value preference value
+        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
+        * @param bool $lazy set preference as lazy loaded
+        *
+        * @return bool TRUE if value was different, therefor updated in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see setValueString()
+        * @see setValueFloat()
+        * @see setValueBool()
+        * @see setValueArray()
+        */
+       public function setValueInt(string $userId, string $app, string $key, int $value, bool $lazy = false, int $flags = 0): bool;
+
+       /**
+        * Store a preference key and its value in database.
+        *
+        * If preference key is already known with the exact same preference value, the database is not updated.
+        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
+        *
+        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param float $value preference value
+        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
+        * @param bool $lazy set preference as lazy loaded
+        *
+        * @return bool TRUE if value was different, therefor updated in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see setValueString()
+        * @see setValueInt()
+        * @see setValueBool()
+        * @see setValueArray()
+        */
+       public function setValueFloat(string $userId, string $app, string $key, float $value, bool $lazy = false, int $flags = 0): bool;
+
+       /**
+        * Store a preference key and its value in database
+        *
+        * If preference key is already known with the exact same preference value, the database is not updated.
+        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
+        *
+        * If preference value was previously stored as lazy loaded, status cannot be altered without using {@see deleteKey()} first
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $value preference value
+        * @param bool $lazy set preference as lazy loaded
+        *
+        * @return bool TRUE if value was different, therefor updated in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see setValueString()
+        * @see setValueInt()
+        * @see setValueFloat()
+        * @see setValueArray()
+        */
+       public function setValueBool(string $userId, string $app, string $key, bool $value, bool $lazy = false): bool;
+
+       /**
+        * Store a preference key and its value in database
+        *
+        * If preference key is already known with the exact same preference value, the database is not updated.
+        * If preference key is not supposed to be read during the boot of the cloud, it is advised to set it as lazy loaded.
+        *
+        * If preference value was previously stored as sensitive or lazy loaded, status cannot be altered without using {@see deleteKey()} first
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param array $value preference value
+        * @param bool $sensitive if TRUE value will be hidden when listing preference values.
+        * @param bool $lazy set preference as lazy loaded
+        *
+        * @return bool TRUE if value was different, therefor updated in database
+        * @since 31.0.0
+        * @see IUserPreferences for explanation about lazy loading
+        * @see setValueString()
+        * @see setValueInt()
+        * @see setValueFloat()
+        * @see setValueBool()
+        */
+       public function setValueArray(string $userId, string $app, string $key, array $value, bool $lazy = false, int $flags = 0): bool;
+
+       /**
+        * switch sensitive status of a preference value
+        *
+        * **WARNING:** ignore lazy filtering, all preference values are loaded from database
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $sensitive TRUE to set as sensitive, FALSE to unset
+        *
+        * @return bool TRUE if database update were necessary
+        * @since 31.0.0
+        */
+       public function updateSensitive(string $userId, string $app, string $key, bool $sensitive): bool;
+
+       /**
+        * switch sensitive loading status of a preference key for all users
+        *
+        * **Warning:** heavy on resources, MUST only be used on occ command or migrations
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $sensitive TRUE to set as sensitive, FALSE to unset
+        *
+        * @since 31.0.0
+        */
+       public function updateGlobalSensitive(string $app, string $key, bool $sensitive): void;
+
+
+       /**
+        * switch indexed status of a preference value
+        *
+        *  **WARNING:** ignore lazy filtering, all preference values are loaded from database
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $indexed TRUE to set as indexed, FALSE to unset
+        *
+        * @return bool TRUE if database update were necessary
+        * @since 31.0.0
+        */
+       public function updateIndexed(string $userId, string $app, string $key, bool $indexed): bool;
+
+       /**
+        * switch sensitive loading status of a preference key for all users
+        *
+        * **Warning:** heavy on resources, MUST only be used on occ command or migrations
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $indexed TRUE to set as indexed, FALSE to unset
+        * @since 31.0.0
+        */
+       public function updateGlobalIndexed(string $app, string $key, bool $indexed): void;
+
+       /**
+        * switch lazy loading status of a preference value
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $lazy TRUE to set as lazy loaded, FALSE to unset
+        *
+        * @return bool TRUE if database update was necessary
+        * @since 31.0.0
+        */
+       public function updateLazy(string $userId, string $app, string $key, bool $lazy): bool;
+
+       /**
+        * switch lazy loading status of a preference key for all users
+        *
+        * **Warning:** heavy on resources, MUST only be used on occ command or migrations
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        * @param bool $lazy TRUE to set as lazy loaded, FALSE to unset
+        * @since 31.0.0
+        */
+       public function updateGlobalLazy(string $app, string $key, bool $lazy): void;
+
+       /**
+        * returns an array contains details about a preference value
+        *
+        * ```
+        * [
+        *   "app" => "myapp",
+        *   "key" => "mykey",
+        *   "value" => "its_value",
+        *   "lazy" => false,
+        *   "type" => 4,
+        *   "typeString" => "string",
+        *   'sensitive' => true
+        * ]
+        * ```
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        *
+        * @return array
+        * @throws UnknownKeyException if preference key is not known in database
+        * @since 31.0.0
+        */
+       public function getDetails(string $userId, string $app, string $key): array;
+
+       /**
+        * Delete single preference key from database.
+        *
+        * @param string $userId id of the user
+        * @param string $app id of the app
+        * @param string $key preference key
+        *
+        * @since 31.0.0
+        */
+       public function deletePreference(string $userId, string $app, string $key): void;
+
+       /**
+        * Delete preference values from all users linked to a specific preference keys
+        *
+        * @param string $app id of the app
+        * @param string $key preference key
+        *
+        * @since 31.0.0
+        */
+       public function deleteKey(string $app, string $key): void;
+
+       /**
+        * delete all preference keys linked to an app
+        *
+        * @param string $app id of the app
+        * @since 31.0.0
+        */
+       public function deleteApp(string $app): void;
+
+       /**
+        * delete all preference keys linked to a user
+        *
+        * @param string $userId id of the user
+        * @since 31.0.0
+        */
+       public function deleteAllPreferences(string $userId): void;
+
+       /**
+        * Clear the cache for a single user
+        *
+        * The cache will be rebuilt only the next time a user preference is requested.
+        *
+        * @param string $userId id of the user
+        * @param bool $reload set to TRUE to refill cache instantly after clearing it
+        *
+        * @since 31.0.0
+        */
+       public function clearCache(string $userId, bool $reload = false): void;
+
+       /**
+        * Clear the cache for all users.
+        * The cache will be rebuilt only the next time a user preference is requested.
+        *
+        * @since 31.0.0
+        */
+       public function clearCacheAll(): void;
+}
diff --git a/lib/unstable/Config/ValueType.php b/lib/unstable/Config/ValueType.php
new file mode 100644 (file)
index 0000000..2c3c585
--- /dev/null
@@ -0,0 +1,78 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace NCU\Config;
+
+use NCU\Config\Exceptions\IncorrectTypeException;
+use UnhandledMatchError;
+
+/**
+ * Listing of available value type for typed config value
+ *
+ * @since 31.0.0
+ */
+enum ValueType: int {
+       /** @since 31.0.0 */
+       case MIXED = 0;
+       /** @since 31.0.0 */
+       case STRING = 1;
+       /** @since 31.0.0 */
+       case INT = 2;
+       /** @since 31.0.0 */
+       case FLOAT = 3;
+       /** @since 31.0.0 */
+       case BOOL = 4;
+       /** @since 31.0.0 */
+       case ARRAY = 5;
+
+       /**
+        * get ValueType from string
+        *
+        * @param string $definition
+        *
+        * @return self
+        * @throws IncorrectTypeException
+        * @since 31.0.0
+        */
+       public static function fromStringDefinition(string $definition): self {
+               try {
+                       return match ($definition) {
+                               'mixed' => self::MIXED,
+                               'string' => self::STRING,
+                               'int' => self::INT,
+                               'float' => self::FLOAT,
+                               'bool' => self::BOOL,
+                               'array' => self::ARRAY
+                       };
+               } catch (\UnhandledMatchError) {
+                       throw new IncorrectTypeException('unknown string definition');
+               }
+       }
+
+       /**
+        * get string definition for current enum value
+        *
+        * @return string
+        * @throws IncorrectTypeException
+        * @since 31.0.0
+        */
+       public function getDefinition(): string {
+               try {
+                       return match ($this) {
+                               self::MIXED => 'mixed',
+                               self::STRING => 'string',
+                               self::INT => 'int',
+                               self::FLOAT => 'float',
+                               self::BOOL => 'bool',
+                               self::ARRAY => 'array',
+                       };
+               } catch (UnhandledMatchError) {
+                       throw new IncorrectTypeException('unknown type definition ' . $this->value);
+               }
+       }
+}
index 19e6d6161bfc82a67aee861a695787f886a40d10..c149af002d3559d20be3ae61c9b953d6949c3717 100644 (file)
@@ -7,11 +7,11 @@ declare(strict_types=1);
  */
 namespace lib;
 
+use NCU\Config\Exceptions\TypeConflictException;
+use NCU\Config\Exceptions\UnknownKeyException;
+use NCU\Config\IUserPreferences;
+use NCU\Config\ValueType;
 use OC\Config\UserPreferences;
-use OCP\Config\Exceptions\TypeConflictException;
-use OCP\Config\Exceptions\UnknownKeyException;
-use OCP\Config\IUserPreferences;
-use OCP\Config\ValueType;
 use OCP\IDBConnection;
 use OCP\Security\ICrypto;
 use Psr\Log\LoggerInterface;