diff options
author | Morris Jobke <hey@morrisjobke.de> | 2014-11-19 12:18:32 +0100 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2014-12-08 22:33:29 +0100 |
commit | f0b10324caf1637d8ad5a9ed94dfed084f65407d (patch) | |
tree | 8ec82ea934049d1552e5a0b0a095c508fbfffeb7 /lib/private/allconfig.php | |
parent | f164161f6925b5b52da6ad897463d91486b6fc4f (diff) | |
download | nextcloud-server-f0b10324caf1637d8ad5a9ed94dfed084f65407d.tar.gz nextcloud-server-f0b10324caf1637d8ad5a9ed94dfed084f65407d.zip |
Refactoring of OC_Preferences to AllConfig
* keep old static methods - mapped to new ones and deprecated
* removed deleteApp, getUsers, getApps because they are unused
* make AllConfig unit tests more robust against not cleaned up environments
Diffstat (limited to 'lib/private/allconfig.php')
-rw-r--r-- | lib/private/allconfig.php | 204 |
1 files changed, 197 insertions, 7 deletions
diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php index 173aac6ad65..17872fd4f69 100644 --- a/lib/private/allconfig.php +++ b/lib/private/allconfig.php @@ -8,6 +8,7 @@ */ namespace OC; +use OCP\IDBConnection; /** * Class to combine all the configuration options ownCloud offers @@ -16,11 +17,37 @@ class AllConfig implements \OCP\IConfig { /** @var SystemConfig */ private $systemConfig; + /** @var IDBConnection */ + private $connection; + + /** + * 3 dimensional array with the following structure: + * [ $userId => + * [ $appId => + * [ $key => $value ] + * ] + * ] + * + * database table: preferences + * + * methods that use this: + * - setUserValue + * - getUserValue + * - getUserKeys + * - deleteUserValue + * - deleteAllUserValues + * - deleteAppFromAllUsers + * + * @var array $userCache + */ + private $userCache = array(); + /** * @param SystemConfig $systemConfig */ - function __construct(SystemConfig $systemConfig) { + function __construct(SystemConfig $systemConfig, IDBConnection $connection) { $this->systemConfig = $systemConfig; + $this->connection = $connection; } /** @@ -115,11 +142,40 @@ class AllConfig implements \OCP\IConfig { * @param string $value the value that you want to store */ public function setUserValue($userId, $appName, $key, $value) { - \OC_Preferences::setValue($userId, $appName, $key, $value); + // Check if the key does exist + $sql = 'SELECT `configvalue` FROM `*PREFIX*preferences` '. + 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; + $result = $this->connection->executeQuery($sql, array($userId, $appName, $key)); + $oldValue = $result->fetchColumn(); + $exists = $oldValue !== false; + + if($oldValue === strval($value)) { + // no changes + return; + } + + if (!$exists) { + $sql = 'INSERT INTO `*PREFIX*preferences` (`configvalue`, `userid`, `appid`, `configkey`)'. + 'VALUES (?, ?, ?, ?)'; + } else { + $sql = 'UPDATE `*PREFIX*preferences` SET `configvalue` = ? '. + 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; + + } + $data = array($value, $userId, $appName, $key); + $affectedRows = $this->connection->executeUpdate($sql, $data); + + // only add to the cache if we already loaded data for the user + if ($affectedRows > 0 && isset($this->userCache[$userId])) { + if (!isset($this->userCache[$userId][$appName])) { + $this->userCache[$userId][$appName] = array(); + } + $this->userCache[$userId][$appName][$key] = $value; + } } /** - * Shortcut for getting a user defined value + * Getting a user defined value * * @param string $userId the userId of the user that we want to store the value under * @param string $appName the appName that we stored the value under @@ -128,7 +184,12 @@ class AllConfig implements \OCP\IConfig { * @return string */ public function getUserValue($userId, $appName, $key, $default = '') { - return \OC_Preferences::getValue($userId, $appName, $key, $default); + $data = $this->getUserValues($userId); + if (isset($data[$appName]) and isset($data[$appName][$key])) { + return $data[$appName][$key]; + } else { + return $default; + } } /** @@ -139,7 +200,12 @@ class AllConfig implements \OCP\IConfig { * @return string[] */ public function getUserKeys($userId, $appName) { - return \OC_Preferences::getKeys($userId, $appName); + $data = $this->getUserValues($userId); + if (isset($data[$appName])) { + return array_keys($data[$appName]); + } else { + return array(); + } } /** @@ -150,7 +216,13 @@ class AllConfig implements \OCP\IConfig { * @param string $key the key under which the value is being stored */ public function deleteUserValue($userId, $appName, $key) { - \OC_Preferences::deleteKey($userId, $appName, $key); + $sql = 'DELETE FROM `*PREFIX*preferences` '. + 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; + $this->connection->executeUpdate($sql, array($userId, $appName, $key)); + + if (isset($this->userCache[$userId]) and isset($this->userCache[$userId][$appName])) { + unset($this->userCache[$userId][$appName][$key]); + } } /** @@ -159,6 +231,124 @@ class AllConfig implements \OCP\IConfig { * @param string $userId the userId of the user that we want to remove all values from */ public function deleteAllUserValues($userId) { - \OC_Preferences::deleteUser($userId); + $sql = 'DELETE FROM `*PREFIX*preferences` '. + 'WHERE `userid` = ?'; + $this->connection->executeUpdate($sql, array($userId)); + + unset($this->userCache[$userId]); + } + + /** + * Delete all user related values of one app + * + * @param string $appName the appName of the app that we want to remove all values from + */ + public function deleteAppFromAllUsers($appName) { + $sql = 'DELETE FROM `*PREFIX*preferences` '. + 'WHERE `appid` = ?'; + $this->connection->executeUpdate($sql, array($appName)); + + foreach ($this->userCache as &$userCache) { + unset($userCache[$appName]); + } + } + + /** + * Returns all user configs sorted by app of one user + * + * @param string $userId the user ID to get the app configs from + * @return array[] - 2 dimensional array with the following structure: + * [ $appId => + * [ $key => $value ] + * ] + */ + private function getUserValues($userId) { + if (isset($this->userCache[$userId])) { + return $this->userCache[$userId]; + } + $data = array(); + $query = 'SELECT `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?'; + $result = $this->connection->executeQuery($query, array($userId)); + while ($row = $result->fetch()) { + $appId = $row['appid']; + if (!isset($data[$appId])) { + $data[$appId] = array(); + } + $data[$appId][$row['configkey']] = $row['configvalue']; + } + $this->userCache[$userId] = $data; + return $data; + } + + /** + * Fetches a mapped list of userId -> value, for a specified app and key and a list of user IDs. + * + * @param $appName app to get the value for + * @param $key the key to get the value for + * @param $userIds the user IDs to fetch the values for + * @return array Mapped values: userId => value + */ + public function getUserValueForUsers($appName, $key, $userIds) { + if (empty($userIds) || !is_array($userIds)) { + return array(); + } + + $chunkedUsers = array_chunk($userIds, 50, true); + $placeholders50 = implode(',', array_fill(0, 50, '?')); + + $userValues = array(); + foreach ($chunkedUsers as $chunk) { + $queryParams = $chunk; + // create [$app, $key, $chunkedUsers] + array_unshift($queryParams, $key); + array_unshift($queryParams, $appName); + + $placeholders = (sizeof($chunk) == 50) ? $placeholders50 : implode(',', array_fill(0, sizeof($chunk), '?')); + + $query = 'SELECT `userid`, `configvalue` ' . + 'FROM `*PREFIX*preferences` ' . + 'WHERE `appid` = ? AND `configkey` = ? ' . + 'AND `userid` IN (' . $placeholders . ')'; + $result = $this->connection->executeQuery($query, $queryParams); + + while ($row = $result->fetch()) { + $userValues[$row['userid']] = $row['configvalue']; + } + } + + return $userValues; + + } + + /** + * Determines the users that have the given value set for a specific app-key-pair + * + * @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 array of user IDs + */ + public function getUsersForUserValue($appName, $key, $value) { + // TODO - FIXME + $this->fixDIInit(); + + $sql = 'SELECT `userid` FROM `*PREFIX*preferences` ' . + 'WHERE `appid` = ? AND `configkey` = ? '; + + if($this->getSystemValue('dbtype', 'sqlite') === 'oci') { + //oracle hack: need to explicitly cast CLOB to CHAR for comparison + $sql .= 'AND to_char(`configvalue`) = ?'; + } else { + $sql .= 'AND `configvalue` = ?'; + } + + $result = $this->connection->executeQuery($sql, array($appName, $key, $value)); + + $userIDs = array(); + while ($row = $result->fetch()) { + $userIDs[] = $row['userid']; + } + + return $userIDs; } } |