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 | |
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')
-rw-r--r-- | lib/private/allconfig.php | 204 | ||||
-rw-r--r-- | lib/private/legacy/preferences.php | 62 | ||||
-rw-r--r-- | lib/private/preferences.php | 233 | ||||
-rw-r--r-- | lib/private/server.php | 3 |
4 files changed, 239 insertions, 263 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; } } diff --git a/lib/private/legacy/preferences.php b/lib/private/legacy/preferences.php index 4b68b0e69aa..28af124db32 100644 --- a/lib/private/legacy/preferences.php +++ b/lib/private/legacy/preferences.php @@ -21,47 +21,23 @@ * */ -OC_Preferences::$object = new \OC\Preferences(OC_DB::getConnection()); /** * This class provides an easy way for storing user preferences. - * @deprecated use \OC\Preferences instead + * @deprecated use \OCP\IConfig methods instead */ class OC_Preferences{ - public static $object; - /** - * Get all users using the preferences - * @return array an array of user ids - * - * This function returns a list of all users that have at least one entry - * in the preferences table. - */ - public static function getUsers() { - return self::$object->getUsers(); - } - - /** - * Get all apps of a user - * @param string $user user - * @return integer[] with app ids - * - * This function returns a list of all apps of the user that have at least - * one entry in the preferences table. - */ - public static function getApps( $user ) { - return self::$object->getApps( $user ); - } - /** * Get the available keys for an app * @param string $user user * @param string $app the app we are looking for * @return array an array of key names + * @deprecated use getUserKeys of \OCP\IConfig instead * * This function gets all keys of an app of an user. Please note that the * values are not returned. */ public static function getKeys( $user, $app ) { - return self::$object->getKeys( $user, $app ); + return \OC::$server->getConfig()->getUserKeys($user, $app); } /** @@ -71,12 +47,13 @@ class OC_Preferences{ * @param string $key key * @param string $default = null, default value if the key does not exist * @return string the value or $default + * @deprecated use getUserValue of \OCP\IConfig instead * * This function gets a value from the preferences table. If the key does * not exist the default value will be returned */ public static function getValue( $user, $app, $key, $default = null ) { - return self::$object->getValue( $user, $app, $key, $default ); + return \OC::$server->getConfig()->getUserValue($user, $app, $key, $default); } /** @@ -87,12 +64,16 @@ class OC_Preferences{ * @param string $value value * @param string $preCondition only set value if the key had a specific value before * @return bool true if value was set, otherwise false + * @deprecated use setUserValue of \OCP\IConfig instead * * Adds a value to the preferences. If the key did not exist before, it * will be added automagically. */ public static function setValue( $user, $app, $key, $value, $preCondition = null ) { - return self::$object->setValue( $user, $app, $key, $value, $preCondition ); + return \OC::$server->getConfig()->setUserValue($user, $app, $key, $value); + + // TODO maybe catch exceptions and then return false + return true; } /** @@ -100,24 +81,13 @@ class OC_Preferences{ * @param string $user user * @param string $app app * @param string $key key + * @return bool true + * @deprecated use deleteUserValue of \OCP\IConfig instead * * Deletes a key. */ public static function deleteKey( $user, $app, $key ) { - self::$object->deleteKey( $user, $app, $key ); - return true; - } - - /** - * Remove app of user from preferences - * @param string $user user - * @param string $app app - * @return bool - * - * Removes all keys in preferences belonging to the app and the user. - */ - public static function deleteApp( $user, $app ) { - self::$object->deleteApp( $user, $app ); + \OC::$server->getConfig()->deleteUserValue($user, $app, $key); return true; } @@ -125,11 +95,12 @@ class OC_Preferences{ * Remove user from preferences * @param string $user user * @return bool + * @deprecated use deleteUser of \OCP\IConfig instead * * Removes all keys in preferences belonging to the user. */ public static function deleteUser( $user ) { - self::$object->deleteUser( $user ); + \OC::$server->getConfig()->deleteAllUserValues($user); return true; } @@ -137,11 +108,12 @@ class OC_Preferences{ * Remove app from all users * @param string $app app * @return bool + * @deprecated use deleteAppFromAllUsers of \OCP\IConfig instead * * Removes all keys in preferences belonging to the app. */ public static function deleteAppFromAllUsers( $app ) { - self::$object->deleteAppFromAllUsers( $app ); + \OC::$server->getConfig()->deleteAppFromAllUsers($app); return true; } } diff --git a/lib/private/preferences.php b/lib/private/preferences.php index cdaa207449d..9f33136aeb2 100644 --- a/lib/private/preferences.php +++ b/lib/private/preferences.php @@ -41,12 +41,9 @@ use OCP\IDBConnection; /** * This class provides an easy way for storing user preferences. + * @deprecated use \OCP\IConfig methods instead */ class Preferences { - /** - * @var \OC\DB\Connection - */ - protected $conn; /** * 3 dimensional array with the following structure: @@ -60,65 +57,14 @@ class Preferences { */ protected $cache = array(); + /** @var \OCP\IConfig */ + protected $config; + /** * @param \OCP\IDBConnection $conn */ public function __construct(IDBConnection $conn) { - $this->conn = $conn; - } - - /** - * Get all users using the preferences - * @return array an array of user ids - * - * This function returns a list of all users that have at least one entry - * in the preferences table. - */ - public function getUsers() { - $query = 'SELECT DISTINCT `userid` FROM `*PREFIX*preferences`'; - $result = $this->conn->executeQuery($query); - - $users = array(); - while ($userid = $result->fetchColumn()) { - $users[] = $userid; - } - - return $users; - } - - /** - * @param string $user - * @return array[] - */ - protected function getUserValues($user) { - if (isset($this->cache[$user])) { - return $this->cache[$user]; - } - $data = array(); - $query = 'SELECT `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?'; - $result = $this->conn->executeQuery($query, array($user)); - while ($row = $result->fetch()) { - $app = $row['appid']; - if (!isset($data[$app])) { - $data[$app] = array(); - } - $data[$app][$row['configkey']] = $row['configvalue']; - } - $this->cache[$user] = $data; - return $data; - } - - /** - * Get all apps of an user - * @param string $user user - * @return integer[] with app ids - * - * This function returns a list of all apps of the user that have at least - * one entry in the preferences table. - */ - public function getApps($user) { - $data = $this->getUserValues($user); - return array_keys($data); + $this->config = \OC::$server->getConfig(); } /** @@ -126,17 +72,13 @@ class Preferences { * @param string $user user * @param string $app the app we are looking for * @return array an array of key names + * @deprecated use getUserKeys of \OCP\IConfig instead * * This function gets all keys of an app of an user. Please note that the * values are not returned. */ public function getKeys($user, $app) { - $data = $this->getUserValues($user); - if (isset($data[$app])) { - return array_keys($data[$app]); - } else { - return array(); - } + return $this->config->getUserKeys($user, $app); } /** @@ -146,17 +88,13 @@ class Preferences { * @param string $key key * @param string $default = null, default value if the key does not exist * @return string the value or $default + * @deprecated use getUserValue of \OCP\IConfig instead * * This function gets a value from the preferences table. If the key does * not exist the default value will be returned */ public function getValue($user, $app, $key, $default = null) { - $data = $this->getUserValues($user); - if (isset($data[$app]) and isset($data[$app][$key])) { - return $data[$app][$key]; - } else { - return $default; - } + return $this->config->getUserValue($user, $app, $key, $default); } /** @@ -167,59 +105,16 @@ class Preferences { * @param string $value value * @param string $preCondition only set value if the key had a specific value before * @return bool true if value was set, otherwise false + * @deprecated use setUserValue of \OCP\IConfig instead * * Adds a value to the preferences. If the key did not exist before, it * will be added automagically. */ public function setValue($user, $app, $key, $value, $preCondition = null) { - // Check if the key does exist - $query = 'SELECT `configvalue` FROM `*PREFIX*preferences`' - . ' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; - $oldValue = $this->conn->fetchColumn($query, array($user, $app, $key)); - $exists = $oldValue !== false; - - if($oldValue === strval($value)) { - // no changes - return true; - } - - $affectedRows = 0; - - if (!$exists && $preCondition === null) { - $data = array( - 'userid' => $user, - 'appid' => $app, - 'configkey' => $key, - 'configvalue' => $value, - ); - $affectedRows = $this->conn->insert('*PREFIX*preferences', $data); - } elseif ($exists) { - $data = array($value, $user, $app, $key); - $sql = "UPDATE `*PREFIX*preferences` SET `configvalue` = ?" - . " WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?"; - - if ($preCondition !== null) { - if (\OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { - //oracle hack: need to explicitly cast CLOB to CHAR for comparison - $sql .= " AND to_char(`configvalue`) = ?"; - } else { - $sql .= " AND `configvalue` = ?"; - } - $data[] = $preCondition; - } - $affectedRows = $this->conn->executeUpdate($sql, $data); - } - - // only add to the cache if we already loaded data for the user - if ($affectedRows > 0 && isset($this->cache[$user])) { - if (!isset($this->cache[$user][$app])) { - $this->cache[$user][$app] = array(); - } - $this->cache[$user][$app][$key] = $value; - } - - return ($affectedRows > 0) ? true : false; + return $this->config->setUserValue($user, $app, $key, $value); + // TODO maybe catch exceptions and then return false + return true; } /** @@ -228,35 +123,10 @@ class Preferences { * @param string $key * @param array $users * @return array Mapped values: userid => value + * @deprecated use getUserValueForUsers of \OCP\IConfig instead */ public function getValueForUsers($app, $key, $users) { - if (empty($users) || !is_array($users)) { - return array(); - } - - $chunked_users = array_chunk($users, 50, true); - $placeholders_50 = implode(',', array_fill(0, 50, '?')); - - $userValues = array(); - foreach ($chunked_users as $chunk) { - $queryParams = $chunk; - array_unshift($queryParams, $key); - array_unshift($queryParams, $app); - - $placeholders = (sizeof($chunk) == 50) ? $placeholders_50 : implode(',', array_fill(0, sizeof($chunk), '?')); - - $query = 'SELECT `userid`, `configvalue` ' - . ' FROM `*PREFIX*preferences` ' - . ' WHERE `appid` = ? AND `configkey` = ?' - . ' AND `userid` IN (' . $placeholders . ')'; - $result = $this->conn->executeQuery($query, $queryParams); - - while ($row = $result->fetch()) { - $userValues[$row['userid']] = $row['configvalue']; - } - } - - return $userValues; + return $this->config->getUserValueForUsers($app, $key, $users); } /** @@ -265,28 +135,10 @@ class Preferences { * @param string $key * @param string $value * @return array + * @deprecated use getUsersForUserValue of \OCP\IConfig instead */ public function getUsersForValue($app, $key, $value) { - $users = array(); - - $query = 'SELECT `userid` ' - . ' FROM `*PREFIX*preferences` ' - . ' WHERE `appid` = ? AND `configkey` = ? AND '; - - if (\OC_Config::getValue( 'dbtype', 'sqlite' ) === 'oci') { - //FIXME oracle hack: need to explicitly cast CLOB to CHAR for comparison - $query .= ' to_char(`configvalue`)= ?'; - } else { - $query .= ' `configvalue` = ?'; - } - - $result = $this->conn->executeQuery($query, array($app, $key, $value)); - - while ($row = $result->fetch()) { - $users[] = $row['userid']; - } - - return $users; + return $this->config->getUsersForUserValue($app, $key, $value); } /** @@ -294,72 +146,33 @@ class Preferences { * @param string $user user * @param string $app app * @param string $key key + * @deprecated use deleteUserValue of \OCP\IConfig instead * * Deletes a key. */ public function deleteKey($user, $app, $key) { - $where = array( - 'userid' => $user, - 'appid' => $app, - 'configkey' => $key, - ); - $this->conn->delete('*PREFIX*preferences', $where); - - if (isset($this->cache[$user]) and isset($this->cache[$user][$app])) { - unset($this->cache[$user][$app][$key]); - } - } - - /** - * Remove app of user from preferences - * @param string $user user - * @param string $app app - * - * Removes all keys in preferences belonging to the app and the user. - */ - public function deleteApp($user, $app) { - $where = array( - 'userid' => $user, - 'appid' => $app, - ); - $this->conn->delete('*PREFIX*preferences', $where); - - if (isset($this->cache[$user])) { - unset($this->cache[$user][$app]); - } + $this->config->deleteUserValue($user, $app, $key); } /** * Remove user from preferences * @param string $user user + * @deprecated use deleteAllUserValues of \OCP\IConfig instead * * Removes all keys in preferences belonging to the user. */ public function deleteUser($user) { - $where = array( - 'userid' => $user, - ); - $this->conn->delete('*PREFIX*preferences', $where); - - unset($this->cache[$user]); + $this->config->deleteAllUserValues($user); } /** * Remove app from all users * @param string $app app + * @deprecated use deleteAppFromAllUsers of \OCP\IConfig instead * * Removes all keys in preferences belonging to the app. */ public function deleteAppFromAllUsers($app) { - $where = array( - 'appid' => $app, - ); - $this->conn->delete('*PREFIX*preferences', $where); - - foreach ($this->cache as &$userCache) { - unset($userCache[$app]); - } + $this->config->deleteAppFromAllUsers($app); } } - -require_once __DIR__ . '/legacy/' . basename(__FILE__); diff --git a/lib/private/server.php b/lib/private/server.php index 5a1e955bdd2..28406d87319 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -168,7 +168,8 @@ class Server extends SimpleContainer implements IServerContainer { }); $this->registerService('AllConfig', function (Server $c) { return new \OC\AllConfig( - $c->getSystemConfig() + $c->getSystemConfig(), + $c->getDatabaseConnection() ); }); $this->registerService('SystemConfig', function ($c) { |