mirror of
https://github.com/nextcloud/server.git
synced 2026-02-19 02:38:40 -05:00
feat(user-prefs): iterator instead of array on search
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
This commit is contained in:
parent
e73513bdd1
commit
7c04818c5c
14 changed files with 114 additions and 139 deletions
|
|
@ -38,7 +38,7 @@ class Version31000Date20240814184402 extends SimpleMigrationStep {
|
|||
$table->addColumn('lazy', Types::SMALLINT, ['notnull' => true, 'default' => 0, 'length' => 1, 'unsigned' => true]);
|
||||
$table->addColumn('type', Types::SMALLINT, ['notnull' => true, 'default' => 0, 'unsigned' => true]);
|
||||
$table->addColumn('flags', Types::INTEGER, ['notnull' => true, 'default' => 0, 'unsigned' => true]);
|
||||
$table->addColumn('indexed', Types::STRING, ['notnull' => true, 'default' => '', 'length' => 64]);
|
||||
$table->addColumn('indexed', Types::STRING, ['notnull' => false, 'default' => '', 'length' => 64]);
|
||||
|
||||
// removing this index from Version13000Date20170718121200
|
||||
// $table->addIndex(['appid', 'configkey'], 'preferences_app_key');
|
||||
|
|
|
|||
|
|
@ -223,6 +223,11 @@ 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',
|
||||
|
|
@ -839,13 +844,6 @@ return array(
|
|||
'OCP\\UserMigration\\ISizeEstimationMigrator' => $baseDir . '/lib/public/UserMigration/ISizeEstimationMigrator.php',
|
||||
'OCP\\UserMigration\\TMigratorBasicVersionHandling' => $baseDir . '/lib/public/UserMigration/TMigratorBasicVersionHandling.php',
|
||||
'OCP\\UserMigration\\UserMigrationException' => $baseDir . '/lib/public/UserMigration/UserMigrationException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\IncorrectTypeException' => $baseDir . '/lib/public/UserPreferences/Exceptions/IncorrectTypeException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\TypeConflictException' => $baseDir . '/lib/public/UserPreferences/Exceptions/TypeConflictException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\UnknownKeyException' => $baseDir . '/lib/public/UserPreferences/Exceptions/UnknownKeyException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\UserPreferencesException' => $baseDir . '/lib/public/UserPreferences/Exceptions/UserPreferencesException.php',
|
||||
'OCP\\UserPreferences\\IUserPreferences' => $baseDir . '/lib/public/UserPreferences/IUserPreferences.php',
|
||||
'OCP\\UserPreferences\\ValueType' => $baseDir . '/lib/public/UserPreferences/ValueType.php',
|
||||
'OCP\\UserPreferences\\ValueTypeDefinition' => $baseDir . '/lib/public/UserPreferences/ValueTypeDefinition.php',
|
||||
'OCP\\UserStatus\\IManager' => $baseDir . '/lib/public/UserStatus/IManager.php',
|
||||
'OCP\\UserStatus\\IProvider' => $baseDir . '/lib/public/UserStatus/IProvider.php',
|
||||
'OCP\\UserStatus\\IUserStatus' => $baseDir . '/lib/public/UserStatus/IUserStatus.php',
|
||||
|
|
@ -1125,6 +1123,7 @@ return array(
|
|||
'OC\\Comments\\Manager' => $baseDir . '/lib/private/Comments/Manager.php',
|
||||
'OC\\Comments\\ManagerFactory' => $baseDir . '/lib/private/Comments/ManagerFactory.php',
|
||||
'OC\\Config' => $baseDir . '/lib/private/Config.php',
|
||||
'OC\\Config\\UserPreferences' => $baseDir . '/lib/private/Config/UserPreferences.php',
|
||||
'OC\\Console\\Application' => $baseDir . '/lib/private/Console/Application.php',
|
||||
'OC\\Console\\TimestampFormatter' => $baseDir . '/lib/private/Console/TimestampFormatter.php',
|
||||
'OC\\ContactsManager' => $baseDir . '/lib/private/ContactsManager.php',
|
||||
|
|
@ -2005,7 +2004,6 @@ return array(
|
|||
'OC\\Updater\\Exceptions\\ReleaseMetadataException' => $baseDir . '/lib/private/Updater/Exceptions/ReleaseMetadataException.php',
|
||||
'OC\\Updater\\ReleaseMetadata' => $baseDir . '/lib/private/Updater/ReleaseMetadata.php',
|
||||
'OC\\Updater\\VersionCheck' => $baseDir . '/lib/private/Updater/VersionCheck.php',
|
||||
'OC\\UserPreferences' => $baseDir . '/lib/private/UserPreferences.php',
|
||||
'OC\\UserStatus\\ISettableProvider' => $baseDir . '/lib/private/UserStatus/ISettableProvider.php',
|
||||
'OC\\UserStatus\\Manager' => $baseDir . '/lib/private/UserStatus/Manager.php',
|
||||
'OC\\User\\AvailabilityCoordinator' => $baseDir . '/lib/private/User/AvailabilityCoordinator.php',
|
||||
|
|
|
|||
|
|
@ -264,6 +264,11 @@ 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',
|
||||
|
|
@ -880,13 +885,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\UserMigration\\ISizeEstimationMigrator' => __DIR__ . '/../../..' . '/lib/public/UserMigration/ISizeEstimationMigrator.php',
|
||||
'OCP\\UserMigration\\TMigratorBasicVersionHandling' => __DIR__ . '/../../..' . '/lib/public/UserMigration/TMigratorBasicVersionHandling.php',
|
||||
'OCP\\UserMigration\\UserMigrationException' => __DIR__ . '/../../..' . '/lib/public/UserMigration/UserMigrationException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\IncorrectTypeException' => __DIR__ . '/../../..' . '/lib/public/UserPreferences/Exceptions/IncorrectTypeException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\TypeConflictException' => __DIR__ . '/../../..' . '/lib/public/UserPreferences/Exceptions/TypeConflictException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\UnknownKeyException' => __DIR__ . '/../../..' . '/lib/public/UserPreferences/Exceptions/UnknownKeyException.php',
|
||||
'OCP\\UserPreferences\\Exceptions\\UserPreferencesException' => __DIR__ . '/../../..' . '/lib/public/UserPreferences/Exceptions/UserPreferencesException.php',
|
||||
'OCP\\UserPreferences\\IUserPreferences' => __DIR__ . '/../../..' . '/lib/public/UserPreferences/IUserPreferences.php',
|
||||
'OCP\\UserPreferences\\ValueType' => __DIR__ . '/../../..' . '/lib/public/UserPreferences/ValueType.php',
|
||||
'OCP\\UserPreferences\\ValueTypeDefinition' => __DIR__ . '/../../..' . '/lib/public/UserPreferences/ValueTypeDefinition.php',
|
||||
'OCP\\UserStatus\\IManager' => __DIR__ . '/../../..' . '/lib/public/UserStatus/IManager.php',
|
||||
'OCP\\UserStatus\\IProvider' => __DIR__ . '/../../..' . '/lib/public/UserStatus/IProvider.php',
|
||||
'OCP\\UserStatus\\IUserStatus' => __DIR__ . '/../../..' . '/lib/public/UserStatus/IUserStatus.php',
|
||||
|
|
@ -1166,6 +1164,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Comments\\Manager' => __DIR__ . '/../../..' . '/lib/private/Comments/Manager.php',
|
||||
'OC\\Comments\\ManagerFactory' => __DIR__ . '/../../..' . '/lib/private/Comments/ManagerFactory.php',
|
||||
'OC\\Config' => __DIR__ . '/../../..' . '/lib/private/Config.php',
|
||||
'OC\\Config\\UserPreferences' => __DIR__ . '/../../..' . '/lib/private/Config/UserPreferences.php',
|
||||
'OC\\Console\\Application' => __DIR__ . '/../../..' . '/lib/private/Console/Application.php',
|
||||
'OC\\Console\\TimestampFormatter' => __DIR__ . '/../../..' . '/lib/private/Console/TimestampFormatter.php',
|
||||
'OC\\ContactsManager' => __DIR__ . '/../../..' . '/lib/private/ContactsManager.php',
|
||||
|
|
@ -2046,7 +2045,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\Updater\\Exceptions\\ReleaseMetadataException' => __DIR__ . '/../../..' . '/lib/private/Updater/Exceptions/ReleaseMetadataException.php',
|
||||
'OC\\Updater\\ReleaseMetadata' => __DIR__ . '/../../..' . '/lib/private/Updater/ReleaseMetadata.php',
|
||||
'OC\\Updater\\VersionCheck' => __DIR__ . '/../../..' . '/lib/private/Updater/VersionCheck.php',
|
||||
'OC\\UserPreferences' => __DIR__ . '/../../..' . '/lib/private/UserPreferences.php',
|
||||
'OC\\UserStatus\\ISettableProvider' => __DIR__ . '/../../..' . '/lib/private/UserStatus/ISettableProvider.php',
|
||||
'OC\\UserStatus\\Manager' => __DIR__ . '/../../..' . '/lib/private/UserStatus/Manager.php',
|
||||
'OC\\User\\AvailabilityCoordinator' => __DIR__ . '/../../..' . '/lib/private/User/AvailabilityCoordinator.php',
|
||||
|
|
|
|||
|
|
@ -6,13 +6,14 @@
|
|||
*/
|
||||
namespace OC;
|
||||
|
||||
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;
|
||||
use OCP\UserPreferences\Exceptions\TypeConflictException;
|
||||
use OCP\UserPreferences\IUserPreferences;
|
||||
use OCP\UserPreferences\ValueType;
|
||||
|
||||
/**
|
||||
* Class to combine all the configuration options ownCloud offers
|
||||
|
|
@ -376,11 +377,11 @@ class AllConfig implements IConfig {
|
|||
* @param string $appName the app to get the user for
|
||||
* @param string $key the key to get the user for
|
||||
* @param string $value the value to get the user for
|
||||
* @return list<string> of user IDs
|
||||
* @return array<string> of user IDs
|
||||
* @deprecated 31.0.0 - use {@see IUserPreferences::searchUsersByValueString} directly
|
||||
*/
|
||||
public function getUsersForUserValue($appName, $key, $value) {
|
||||
return \OCP\Server::get(IUserPreferences::class)->searchUsersByValueDeprecated($appName, $key, $value);
|
||||
return iterator_to_array(\OCP\Server::get(IUserPreferences::class)->searchUsersByValueString($appName, $key, $value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -389,7 +390,7 @@ class AllConfig implements IConfig {
|
|||
* @param string $appName the app to get the user for
|
||||
* @param string $key the key to get the user for
|
||||
* @param string $value the value to get the user for
|
||||
* @return list<string> of user IDs
|
||||
* @return array<string> of user IDs
|
||||
* @deprecated 31.0.0 - use {@see IUserPreferences::searchUsersByValueString} directly
|
||||
*/
|
||||
public function getUsersForUserValueCaseInsensitive($appName, $key, $value) {
|
||||
|
|
@ -397,7 +398,7 @@ class AllConfig implements IConfig {
|
|||
return $this->getUsersForUserValue($appName, $key, strtolower($value));
|
||||
}
|
||||
|
||||
return \OCP\Server::get(IUserPreferences::class)->searchUsersByValueDeprecated($appName, $key, $value, true);
|
||||
return iterator_to_array(\OCP\Server::get(IUserPreferences::class)->searchUsersByValueString($appName, $key, $value, true));
|
||||
}
|
||||
|
||||
public function getSystemConfig() {
|
||||
|
|
|
|||
|
|
@ -6,21 +6,22 @@ declare(strict_types=1);
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC;
|
||||
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 OCP\DB\Exception as DBException;
|
||||
use OCP\DB\IResult;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Security\ICrypto;
|
||||
use OCP\UserPreferences\Exceptions\IncorrectTypeException;
|
||||
use OCP\UserPreferences\Exceptions\TypeConflictException;
|
||||
use OCP\UserPreferences\Exceptions\UnknownKeyException;
|
||||
use OCP\UserPreferences\IUserPreferences;
|
||||
use OCP\UserPreferences\ValueType;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
|
|
@ -52,7 +53,7 @@ class UserPreferences implements IUserPreferences {
|
|||
private array $fastCache = []; // cache for normal preference keys
|
||||
/** @var array<string, array<string, array<string, mixed>>> ['user_id' => ['app_id' => ['key' => 'value']]] */
|
||||
private array $lazyCache = []; // cache for lazy preference keys
|
||||
/** @var array<string, array<string, array<string, <'type', ValueType>|<'flags', int>> ['user_id' => ['app_id' => ['key' => ['type' => ValueType, 'flags' => bitflag]]] */
|
||||
/** @var array<string, array<string, array<string, array<string, mixed>>>> ['user_id' => ['app_id' => ['key' => ['type' => ValueType, 'flags' => bitflag]]]] */
|
||||
private array $valueDetails = []; // type for all preference values
|
||||
/** @var array<string, array<string, array<string, ValueType>>> ['user_id' => ['app_id' => ['key' => bitflag]]] */
|
||||
private array $valueTypes = []; // type for all preference values
|
||||
|
|
@ -358,7 +359,7 @@ class UserPreferences implements IUserPreferences {
|
|||
while ($row = $result->fetch()) {
|
||||
$value = $row['configvalue'];
|
||||
try {
|
||||
$value = $this->convertTypedValue($value, $typedAs ?? ValueType::from((int) $row['type']));
|
||||
$value = $this->convertTypedValue($value, $typedAs ?? ValueType::from((int)$row['type']));
|
||||
} catch (IncorrectTypeException) {
|
||||
}
|
||||
$values[$row['userid']] = $value;
|
||||
|
|
@ -393,29 +394,13 @@ class UserPreferences implements IUserPreferences {
|
|||
* @param string $value preference value
|
||||
* @param bool $caseInsensitive non-case-sensitive search, only works if $value is a string
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValueString(string $app, string $key, string $value, bool $caseInsensitive = false): array {
|
||||
public function searchUsersByValueString(string $app, string $key, string $value, bool $caseInsensitive = false): Generator {
|
||||
return $this->searchUsersByTypedValue($app, $key, $value, $caseInsensitive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @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
|
||||
* @internal
|
||||
* @deprecated since 31.0.0 - {@see }
|
||||
* @return list<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValueDeprecated(string $app, string $key, string $value, bool $caseInsensitive = false): array {
|
||||
return $this->searchUsersByTypedValue($app, $key, $value, $caseInsensitive, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
|
|
@ -423,10 +408,10 @@ class UserPreferences implements IUserPreferences {
|
|||
* @param string $key preference key
|
||||
* @param int $value preference value
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValueInt(string $app, string $key, int $value): array {
|
||||
public function searchUsersByValueInt(string $app, string $key, int $value): Generator {
|
||||
return $this->searchUsersByValueString($app, $key, (string)$value);
|
||||
}
|
||||
|
||||
|
|
@ -437,10 +422,10 @@ class UserPreferences implements IUserPreferences {
|
|||
* @param string $key preference key
|
||||
* @param array $values list of preference values
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValues(string $app, string $key, array $values): array {
|
||||
public function searchUsersByValues(string $app, string $key, array $values): Generator {
|
||||
return $this->searchUsersByTypedValue($app, $key, $values);
|
||||
}
|
||||
|
||||
|
|
@ -451,10 +436,10 @@ class UserPreferences implements IUserPreferences {
|
|||
* @param string $key preference key
|
||||
* @param bool $value preference value
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValueBool(string $app, string $key, bool $value): array {
|
||||
public function searchUsersByValueBool(string $app, string $key, bool $value): Generator {
|
||||
$values = ['0', 'off', 'false', 'no'];
|
||||
if ($value) {
|
||||
$values = ['1', 'on', 'true', 'yes'];
|
||||
|
|
@ -470,11 +455,10 @@ class UserPreferences implements IUserPreferences {
|
|||
* @param string $key
|
||||
* @param string|array $value
|
||||
* @param bool $caseInsensitive
|
||||
* @param bool $withinNotIndexedField DEPRECATED: should only be used to stay compatible with not-indexed/pre-31 preferences value
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
*/
|
||||
private function searchUsersByTypedValue(string $app, string $key, string|array $value, bool $caseInsensitive = false): array {
|
||||
private function searchUsersByTypedValue(string $app, string $key, string|array $value, bool $caseInsensitive = false): Generator {
|
||||
$this->assertParams('', $app, $key, allowEmptyUser: true);
|
||||
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
|
|
@ -483,14 +467,14 @@ class UserPreferences implements IUserPreferences {
|
|||
$qb->where($qb->expr()->eq('appid', $qb->createNamedParameter($app)));
|
||||
$qb->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key)));
|
||||
|
||||
// search within 'indexed' OR 'configvalue' (but if 'flags' is not set as indexed)
|
||||
// search within 'indexed' OR 'configvalue' only if 'flags' is set as not indexed
|
||||
// TODO: when implementing config lexicon remove the searches on 'configvalue' if value is set as indexed
|
||||
$configValueColumn = ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) ? $qb->expr()->castColumn('configvalue', IQueryBuilder::PARAM_STR) : 'configvalue';
|
||||
if (is_array($value)) {
|
||||
$where = $qb->expr()->orX(
|
||||
$qb->expr()->in('indexed', $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY)),
|
||||
$qb->expr()->andX(
|
||||
$qb->createFunction('NOT ' . $qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED)),
|
||||
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
||||
$qb->expr()->in($configValueColumn, $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY))
|
||||
)
|
||||
);
|
||||
|
|
@ -499,7 +483,7 @@ class UserPreferences implements IUserPreferences {
|
|||
$where = $qb->expr()->orX(
|
||||
$qb->expr()->eq($qb->func()->lower('indexed'), $qb->createNamedParameter(strtolower($value))),
|
||||
$qb->expr()->andX(
|
||||
$qb->createFunction('NOT ' . $qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED)),
|
||||
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
||||
$qb->expr()->eq($qb->func()->lower($configValueColumn), $qb->createNamedParameter(strtolower($value)))
|
||||
)
|
||||
);
|
||||
|
|
@ -507,7 +491,7 @@ class UserPreferences implements IUserPreferences {
|
|||
$where = $qb->expr()->orX(
|
||||
$qb->expr()->eq('indexed', $qb->createNamedParameter($value)),
|
||||
$qb->expr()->andX(
|
||||
$qb->createFunction('NOT ' . $qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED)),
|
||||
$qb->expr()->neq($qb->expr()->bitwiseAnd('flags', self::FLAG_INDEXED), $qb->createNamedParameter(self::FLAG_INDEXED, IQueryBuilder::PARAM_INT)),
|
||||
$qb->expr()->eq($configValueColumn, $qb->createNamedParameter($value))
|
||||
)
|
||||
);
|
||||
|
|
@ -515,15 +499,10 @@ class UserPreferences implements IUserPreferences {
|
|||
}
|
||||
|
||||
$qb->andWhere($where);
|
||||
|
||||
$userIds = [];
|
||||
$result = $qb->executeQuery();
|
||||
$rows = $result->fetchAll();
|
||||
foreach ($rows as $row) {
|
||||
$userIds[] = $row['userid'];
|
||||
while ($row = $result->fetch()) {
|
||||
yield $row['userid'];
|
||||
}
|
||||
|
||||
return $userIds;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -726,7 +705,7 @@ class UserPreferences implements IUserPreferences {
|
|||
bool $lazy,
|
||||
ValueType $type,
|
||||
): string {
|
||||
$this->assertParams($userId, $app, $key, valueType: $type);
|
||||
$this->assertParams($userId, $app, $key);
|
||||
$this->loadPreferences($userId, $lazy);
|
||||
|
||||
/**
|
||||
|
|
@ -793,7 +772,7 @@ class UserPreferences implements IUserPreferences {
|
|||
* @param string $key preference key
|
||||
* @param bool $lazy lazy loading
|
||||
*
|
||||
* @return ValueType type of the value
|
||||
* @return int flags applied to value
|
||||
* @throws UnknownKeyException if preference key is not known
|
||||
* @throws IncorrectTypeException if preferences value type is not known
|
||||
* @since 31.0.0
|
||||
|
|
@ -978,7 +957,7 @@ class UserPreferences implements IUserPreferences {
|
|||
string $key,
|
||||
bool $value,
|
||||
bool $lazy = false,
|
||||
int $flags = 0
|
||||
int $flags = 0,
|
||||
): bool {
|
||||
return $this->setTypedValue(
|
||||
$userId,
|
||||
|
|
@ -1058,7 +1037,7 @@ class UserPreferences implements IUserPreferences {
|
|||
int $flags,
|
||||
ValueType $type,
|
||||
): bool {
|
||||
$this->assertParams($userId, $app, $key, valueType: $type);
|
||||
$this->assertParams($userId, $app, $key);
|
||||
$this->loadPreferences($userId, $lazy);
|
||||
|
||||
$inserted = $refreshCache = false;
|
||||
|
|
@ -1074,7 +1053,7 @@ class UserPreferences implements IUserPreferences {
|
|||
if ($type !== ValueType::ARRAY && $this->isFlagged(self::FLAG_INDEXED, $flags)) {
|
||||
if ($this->isFlagged(self::FLAG_SENSITIVE, $flags)) {
|
||||
$this->logger->warning('sensitive value are not to be indexed');
|
||||
} else if (strlen($value) > self::USER_MAX_LENGTH) {
|
||||
} elseif (strlen($value) > self::USER_MAX_LENGTH) {
|
||||
$this->logger->warning('value is too lengthy to be indexed');
|
||||
} else {
|
||||
$indexed = $value;
|
||||
|
|
@ -1203,7 +1182,7 @@ class UserPreferences implements IUserPreferences {
|
|||
* @since 31.0.0
|
||||
*/
|
||||
public function updateType(string $userId, string $app, string $key, ValueType $type = ValueType::MIXED): bool {
|
||||
$this->assertParams($userId, $app, $key, valueType: $type);
|
||||
$this->assertParams($userId, $app, $key);
|
||||
$this->loadPreferencesAll($userId);
|
||||
$this->isLazy($userId, $app, $key); // confirm key exists
|
||||
|
||||
|
|
@ -1348,11 +1327,11 @@ class UserPreferences implements IUserPreferences {
|
|||
|
||||
$update = $this->connection->getQueryBuilder();
|
||||
$update->update('preferences')
|
||||
->set('flags', $update->createNamedParameter($flags, IQueryBuilder::PARAM_INT))
|
||||
->set('indexed', $update->createNamedParameter($indexed))
|
||||
->where($update->expr()->eq('userid', $update->createNamedParameter($userId)))
|
||||
->andWhere($update->expr()->eq('appid', $update->createNamedParameter($app)))
|
||||
->andWhere($update->expr()->eq('configkey', $update->createNamedParameter($key)));
|
||||
->set('flags', $update->createNamedParameter($flags, IQueryBuilder::PARAM_INT))
|
||||
->set('indexed', $update->createNamedParameter($indexed))
|
||||
->where($update->expr()->eq('userid', $update->createNamedParameter($userId)))
|
||||
->andWhere($update->expr()->eq('appid', $update->createNamedParameter($app)))
|
||||
->andWhere($update->expr()->eq('configkey', $update->createNamedParameter($key)));
|
||||
$update->executeStatement();
|
||||
|
||||
$this->valueDetails[$userId][$app][$key]['flags'] = $flags;
|
||||
|
|
@ -1634,7 +1613,6 @@ class UserPreferences implements IUserPreferences {
|
|||
string $prefKey = '',
|
||||
bool $allowEmptyUser = false,
|
||||
bool $allowEmptyApp = false,
|
||||
?ValueType $valueType = null,
|
||||
): void {
|
||||
if (!$allowEmptyUser && $userId === '') {
|
||||
throw new InvalidArgumentException('userId cannot be an empty string');
|
||||
|
|
@ -1651,12 +1629,6 @@ class UserPreferences implements IUserPreferences {
|
|||
if (strlen($prefKey) > self::KEY_MAX_LENGTH) {
|
||||
throw new InvalidArgumentException('Value (' . $prefKey . ') for key is too long (' . self::KEY_MAX_LENGTH . ')');
|
||||
}
|
||||
if ($valueType !== null) {
|
||||
// $valueFlag = $valueType->value;
|
||||
// if (ValueType::tryFrom($valueFlag) === null) {
|
||||
// throw new InvalidArgumentException('Unknown value type');
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
private function loadPreferencesAll(string $userId): void {
|
||||
|
|
@ -1697,7 +1669,7 @@ class UserPreferences implements IUserPreferences {
|
|||
} else {
|
||||
$this->fastCache[$userId][$row['appid']][$row['configkey']] = $row['configvalue'] ?? '';
|
||||
}
|
||||
$this->valueDetails[$userId][$row['appid']][$row['configkey']] = ['type' => ValueType::from((int)($row['type'] ?? 0)), 'flags' => (int) $row['flags']];
|
||||
$this->valueDetails[$userId][$row['appid']][$row['configkey']] = ['type' => ValueType::from((int)($row['type'] ?? 0)), 'flags' => (int)$row['flags']];
|
||||
}
|
||||
$result->closeCursor();
|
||||
$this->setAsLoaded($userId, $lazy);
|
||||
|
|
@ -138,6 +138,7 @@ 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;
|
||||
|
|
@ -237,7 +238,6 @@ use OCP\User\Events\UserLoggedInEvent;
|
|||
use OCP\User\Events\UserLoggedInWithCookieEvent;
|
||||
use OCP\User\Events\UserLoggedOutEvent;
|
||||
use OCP\User\IAvailabilityCoordinator;
|
||||
use OCP\UserPreferences\IUserPreferences;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
|
@ -568,7 +568,7 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
});
|
||||
|
||||
$this->registerAlias(IAppConfig::class, \OC\AppConfig::class);
|
||||
$this->registerAlias(IUserPreferences::class, \OC\UserPreferences::class);
|
||||
$this->registerAlias(IUserPreferences::class, \OC\Config\UserPreferences::class);
|
||||
|
||||
$this->registerService(IFactory::class, function (Server $c) {
|
||||
return new \OC\L10N\Factory(
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ declare(strict_types=1);
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\UserPreferences\Exceptions;
|
||||
namespace OCP\Config\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @since 31.0.0
|
||||
*/
|
||||
class UserPreferencesException extends Exception {
|
||||
class IncorrectTypeException extends Exception {
|
||||
}
|
||||
|
|
@ -6,10 +6,12 @@ declare(strict_types=1);
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\UserPreferences\Exceptions;
|
||||
namespace OCP\Config\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @since 31.0.0
|
||||
*/
|
||||
class TypeConflictException extends UserPreferencesException {
|
||||
class TypeConflictException extends Exception {
|
||||
}
|
||||
|
|
@ -6,10 +6,12 @@ declare(strict_types=1);
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\UserPreferences\Exceptions;
|
||||
namespace OCP\Config\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @since 31.0.0
|
||||
*/
|
||||
class UnknownKeyException extends UserPreferencesException {
|
||||
class UnknownKeyException extends Exception {
|
||||
}
|
||||
|
|
@ -6,16 +6,34 @@ declare(strict_types=1);
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\UserPreferences;
|
||||
namespace OCP\Config;
|
||||
|
||||
use OCP\UserPreferences\Exceptions\IncorrectTypeException;
|
||||
use OCP\UserPreferences\Exceptions\UnknownKeyException;
|
||||
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
|
||||
|
||||
/**
|
||||
|
|
@ -191,10 +209,10 @@ interface IUserPreferences {
|
|||
* @param string $value preference value
|
||||
* @param bool $caseInsensitive non-case-sensitive search, only works if $value is a string
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValueString(string $app, string $key, string $value, bool $caseInsensitive = false): array;
|
||||
public function searchUsersByValueString(string $app, string $key, string $value, bool $caseInsensitive = false): Generator;
|
||||
|
||||
/**
|
||||
* List all users storing a specific preference key/value pair.
|
||||
|
|
@ -206,10 +224,10 @@ interface IUserPreferences {
|
|||
* @param string $key preference key
|
||||
* @param int $value preference value
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValueInt(string $app, string $key, int $value): array;
|
||||
public function searchUsersByValueInt(string $app, string $key, int $value): Generator;
|
||||
|
||||
/**
|
||||
* List all users storing a specific preference key/value pair.
|
||||
|
|
@ -221,10 +239,10 @@ interface IUserPreferences {
|
|||
* @param string $key preference key
|
||||
* @param array $values list of possible preference values
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValues(string $app, string $key, array $values): array;
|
||||
public function searchUsersByValues(string $app, string $key, array $values): Generator;
|
||||
|
||||
/**
|
||||
* List all users storing a specific preference key/value pair.
|
||||
|
|
@ -236,10 +254,10 @@ interface IUserPreferences {
|
|||
* @param string $key preference key
|
||||
* @param bool $value preference value
|
||||
*
|
||||
* @return list<string>
|
||||
* @return Generator<string>
|
||||
* @since 31.0.0
|
||||
*/
|
||||
public function searchUsersByValueBool(string $app, string $key, bool $value): array;
|
||||
public function searchUsersByValueBool(string $app, string $key, bool $value): Generator;
|
||||
|
||||
/**
|
||||
* Get user preference assigned to a preference key.
|
||||
|
|
@ -6,15 +6,14 @@ declare(strict_types=1);
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCP\UserPreferences;
|
||||
namespace OCP\Config;
|
||||
|
||||
use OCP\UserPreferences\Exceptions\IncorrectTypeException;
|
||||
use OCP\Config\Exceptions\IncorrectTypeException;
|
||||
use UnhandledMatchError;
|
||||
|
||||
/**
|
||||
* Listing of available value type for user preferences
|
||||
* Listing of available value type for typed config value
|
||||
*
|
||||
* @see IUserPreferences
|
||||
* @since 31.0.0
|
||||
*/
|
||||
enum ValueType: int {
|
||||
|
|
@ -50,7 +49,7 @@ enum ValueType: int {
|
|||
'bool' => self::BOOL,
|
||||
'array' => self::ARRAY
|
||||
};
|
||||
} catch (\UnhandledMatchError ) {
|
||||
} catch (\UnhandledMatchError) {
|
||||
throw new IncorrectTypeException('unknown string definition');
|
||||
}
|
||||
}
|
||||
|
|
@ -245,7 +245,7 @@ interface IConfig {
|
|||
* @param string $appName the app to get the user for
|
||||
* @param string $key the key to get the user for
|
||||
* @param string $value the value to get the user for
|
||||
* @return list<string> of user IDs
|
||||
* @return array<string> of user IDs
|
||||
* @since 31.0.0 return type of `list<string>`
|
||||
* @since 8.0.0
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,15 +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\UserPreferences\Exceptions;
|
||||
|
||||
/**
|
||||
* @since 31.0.0
|
||||
*/
|
||||
class IncorrectTypeException extends UserPreferencesException {
|
||||
}
|
||||
|
|
@ -7,13 +7,13 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace lib;
|
||||
|
||||
use OC\UserPreferences;
|
||||
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 OCP\UserPreferences\Exceptions\TypeConflictException;
|
||||
use OCP\UserPreferences\Exceptions\UnknownKeyException;
|
||||
use OCP\UserPreferences\IUserPreferences;
|
||||
use OCP\UserPreferences\ValueType;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ class UserPreferencesTest extends TestCase {
|
|||
* @return IUserPreferences
|
||||
*/
|
||||
private function generateUserPreferences(array $preLoading = []): IUserPreferences {
|
||||
$preferences = new \OC\UserPreferences(
|
||||
$preferences = new \OC\Config\UserPreferences(
|
||||
$this->connection,
|
||||
$this->logger,
|
||||
$this->crypto,
|
||||
|
|
@ -775,7 +775,7 @@ class UserPreferencesTest extends TestCase {
|
|||
array $result,
|
||||
): void {
|
||||
$preferences = $this->generateUserPreferences();
|
||||
$this->assertEqualsCanonicalizing($result, $preferences->searchUsersByValueString($app, $key, $value, $ci));
|
||||
$this->assertEqualsCanonicalizing($result, iterator_to_array($preferences->searchUsersByValueString($app, $key, $value, $ci)));
|
||||
}
|
||||
|
||||
public function providerSearchValuesByValueInt(): array {
|
||||
|
|
@ -796,7 +796,7 @@ class UserPreferencesTest extends TestCase {
|
|||
array $result,
|
||||
): void {
|
||||
$preferences = $this->generateUserPreferences();
|
||||
$this->assertEqualsCanonicalizing($result, $preferences->searchUsersByValueInt($app, $key, $value));
|
||||
$this->assertEqualsCanonicalizing($result, iterator_to_array($preferences->searchUsersByValueInt($app, $key, $value)));
|
||||
}
|
||||
|
||||
public function providerSearchValuesByValues(): array {
|
||||
|
|
@ -816,7 +816,7 @@ class UserPreferencesTest extends TestCase {
|
|||
array $result,
|
||||
): void {
|
||||
$preferences = $this->generateUserPreferences();
|
||||
$this->assertEqualsCanonicalizing($result, $preferences->searchUsersByValues($app, $key, $values));
|
||||
$this->assertEqualsCanonicalizing($result, iterator_to_array($preferences->searchUsersByValues($app, $key, $values)));
|
||||
}
|
||||
|
||||
public function providerSearchValuesByValueBool(): array {
|
||||
|
|
@ -836,7 +836,7 @@ class UserPreferencesTest extends TestCase {
|
|||
array $result,
|
||||
): void {
|
||||
$preferences = $this->generateUserPreferences();
|
||||
$this->assertEqualsCanonicalizing($result, $preferences->searchUsersByValueBool($app, $key, $value));
|
||||
$this->assertEqualsCanonicalizing($result, iterator_to_array($preferences->searchUsersByValueBool($app, $key, $value)));
|
||||
}
|
||||
|
||||
public function providerGetValueMixed(): array {
|
||||
|
|
|
|||
Loading…
Reference in a new issue