diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2025-03-03 14:46:07 -0100 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2025-03-03 14:46:41 -0100 |
commit | 1fac9cfa14ed3387fdec1478da765044267ceb76 (patch) | |
tree | d529be0e023e63b5a0ba03d85f6dece7d6689f30 | |
parent | 0a1a63cd37478bd739c9c05665a4de19e6b4bc7c (diff) | |
download | nextcloud-server-1fac9cfa14ed3387fdec1478da765044267ceb76.tar.gz nextcloud-server-1fac9cfa14ed3387fdec1478da765044267ceb76.zip |
fix(userconfig): simpler db request before 31 upgradefix/51022/simpler-request-pre-upgrade
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
-rw-r--r-- | lib/private/Config/UserConfig.php | 148 |
1 files changed, 99 insertions, 49 deletions
diff --git a/lib/private/Config/UserConfig.php b/lib/private/Config/UserConfig.php index 77a86a5e1c7..178b156bb7c 100644 --- a/lib/private/Config/UserConfig.php +++ b/lib/private/Config/UserConfig.php @@ -64,6 +64,7 @@ class UserConfig implements IUserConfig { private array $lazyLoaded = []; /** @var array<array-key, array{entries: array<array-key, ConfigLexiconEntry>, strictness: ConfigLexiconStrictness}> ['app_id' => ['strictness' => ConfigLexiconStrictness, 'entries' => ['config_key' => ConfigLexiconEntry[]]] */ private array $configLexiconDetails = []; + private bool $upgradedTo31 = false; public function __construct( protected IDBConnection $connection, @@ -351,8 +352,12 @@ class UserConfig implements IUserConfig { $this->assertParams('', $app, $key, allowEmptyUser: true); $qb = $this->connection->getQueryBuilder(); - $qb->select('userid', 'configvalue', 'type') - ->from('preferences') + if ($this->isUpgradedTo31()) { + $qb->select('userid', 'configvalue', 'type'); + } else { + $qb->select('userid', 'configvalue'); + } + $qb->from('preferences') ->where($qb->expr()->eq('appid', $qb->createNamedParameter($app))) ->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key))); @@ -363,7 +368,7 @@ class UserConfig implements IUserConfig { 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'] ?? 0))); } catch (IncorrectTypeException) { } $values[$row['userid']] = $value; @@ -471,34 +476,42 @@ class UserConfig implements IUserConfig { $qb->where($qb->expr()->eq('appid', $qb->createNamedParameter($app))); $qb->andWhere($qb->expr()->eq('configkey', $qb->createNamedParameter($key))); - // 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->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)) - ) - ); - } else { - if ($caseInsensitive) { + if ($this->isUpgradedTo31()) { + // 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 + if (is_array($value)) { $where = $qb->expr()->orX( - $qb->expr()->eq($qb->func()->lower('indexed'), $qb->createNamedParameter(strtolower($value))), + $qb->expr()->in('indexed', $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY)), $qb->expr()->andX( $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))) + $qb->expr()->in($configValueColumn, $qb->createNamedParameter($value, IQueryBuilder::PARAM_STR_ARRAY)) ) ); } else { - $where = $qb->expr()->orX( - $qb->expr()->eq('indexed', $qb->createNamedParameter($value)), - $qb->expr()->andX( - $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)) - ) - ); + if ($caseInsensitive) { + $where = $qb->expr()->orX( + $qb->expr()->eq($qb->func()->lower('indexed'), $qb->createNamedParameter(strtolower($value))), + $qb->expr()->andX( + $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))) + ) + ); + } else { + $where = $qb->expr()->orX( + $qb->expr()->eq('indexed', $qb->createNamedParameter($value)), + $qb->expr()->andX( + $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)) + ) + ); + } + } + } else { + if ($caseInsensitive) { + $where = $qb->expr()->eq($qb->func()->lower($configValueColumn), $qb->createNamedParameter(strtolower($value))); + } else { + $where = $qb->expr()->eq($configValueColumn, $qb->createNamedParameter($value)); } } @@ -1088,15 +1101,23 @@ class UserConfig implements IUserConfig { */ try { $insert = $this->connection->getQueryBuilder(); - $insert->insert('preferences') - ->setValue('userid', $insert->createNamedParameter($userId)) - ->setValue('appid', $insert->createNamedParameter($app)) - ->setValue('lazy', $insert->createNamedParameter(($lazy) ? 1 : 0, IQueryBuilder::PARAM_INT)) - ->setValue('type', $insert->createNamedParameter($type->value, IQueryBuilder::PARAM_INT)) - ->setValue('flags', $insert->createNamedParameter($flags, IQueryBuilder::PARAM_INT)) - ->setValue('indexed', $insert->createNamedParameter($indexed)) - ->setValue('configkey', $insert->createNamedParameter($key)) - ->setValue('configvalue', $insert->createNamedParameter($value)); + if ($this->isUpgradedTo31()) { + $insert->insert('preferences') + ->setValue('userid', $insert->createNamedParameter($userId)) + ->setValue('appid', $insert->createNamedParameter($app)) + ->setValue('lazy', $insert->createNamedParameter(($lazy) ? 1 : 0, IQueryBuilder::PARAM_INT)) + ->setValue('type', $insert->createNamedParameter($type->value, IQueryBuilder::PARAM_INT)) + ->setValue('flags', $insert->createNamedParameter($flags, IQueryBuilder::PARAM_INT)) + ->setValue('indexed', $insert->createNamedParameter($indexed)) + ->setValue('configkey', $insert->createNamedParameter($key)) + ->setValue('configvalue', $insert->createNamedParameter($value)); + } else { + $insert->insert('preferences') + ->setValue('userid', $insert->createNamedParameter($userId)) + ->setValue('appid', $insert->createNamedParameter($app)) + ->setValue('configkey', $insert->createNamedParameter($key)) + ->setValue('configvalue', $insert->createNamedParameter($value)); + } $insert->executeStatement(); $inserted = true; } catch (DBException $e) { @@ -1146,16 +1167,23 @@ class UserConfig implements IUserConfig { } $update = $this->connection->getQueryBuilder(); - $update->update('preferences') - ->set('configvalue', $update->createNamedParameter($value)) - ->set('lazy', $update->createNamedParameter(($lazy) ? 1 : 0, IQueryBuilder::PARAM_INT)) - ->set('type', $update->createNamedParameter($type->value, IQueryBuilder::PARAM_INT)) - ->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))); - + if ($this->isUpgradedTo31()) { + $update->update('preferences') + ->set('configvalue', $update->createNamedParameter($value)) + ->set('lazy', $update->createNamedParameter(($lazy) ? 1 : 0, IQueryBuilder::PARAM_INT)) + ->set('type', $update->createNamedParameter($type->value, IQueryBuilder::PARAM_INT)) + ->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))); + } else { + $update->update('preferences') + ->set('configvalue', $update->createNamedParameter($value)) + ->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(); } @@ -1668,14 +1696,20 @@ class UserConfig implements IUserConfig { $qb = $this->connection->getQueryBuilder(); $qb->from('preferences'); - $qb->select('appid', 'configkey', 'configvalue', 'type', 'flags'); + if ($this->isUpgradedTo31()) { + $qb->select('appid', 'configkey', 'configvalue', 'type', 'flags'); + } else { + $qb->select('appid', 'configkey', 'configvalue'); + } $qb->where($qb->expr()->eq('userid', $qb->createNamedParameter($userId))); - // we only need value from lazy when loadConfig does not specify it - if ($lazy !== null) { - $qb->andWhere($qb->expr()->eq('lazy', $qb->createNamedParameter($lazy ? 1 : 0, IQueryBuilder::PARAM_INT))); - } else { - $qb->addSelect('lazy'); + if ($this->isUpgradedTo31()) { + // we only need value from lazy when loadConfig does not specify it + if ($lazy !== null) { + $qb->andWhere($qb->expr()->eq('lazy', $qb->createNamedParameter($lazy ? 1 : 0, IQueryBuilder::PARAM_INT))); + } else { + $qb->addSelect('lazy'); + } } $result = $qb->executeQuery(); @@ -1954,4 +1988,20 @@ class UserConfig implements IUserConfig { return $this->configLexiconDetails[$appId]; } + + /** + * This is a temporary method that MUST be removed on NC32/NC32+ + * It seems that some apps might want to check user preferences before initiating + * the upgrade process resulting in locking instance. + * + * @return bool + */ + private function isUpgradedTo31(): bool { + if (!$this->upgradedTo31) { + $this->upgradedTo31 = (str_starts_with($this->config->getSystemValue('version'), '31.') + || str_starts_with($this->config->getSystemValue('version'), '32.')); + } + + return $this->upgradedTo31; + } } |