diff options
author | Morris Jobke <hey@morrisjobke.de> | 2014-12-03 21:31:29 +0100 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2014-12-08 22:33:36 +0100 |
commit | af91ee97c981d32bcd531e71d31e16f1232c44ce (patch) | |
tree | a38253e8311aa0056f90af6adc89d9b791d1dc00 /lib/private/allconfig.php | |
parent | f0b10324caf1637d8ad5a9ed94dfed084f65407d (diff) | |
download | nextcloud-server-af91ee97c981d32bcd531e71d31e16f1232c44ce.tar.gz nextcloud-server-af91ee97c981d32bcd531e71d31e16f1232c44ce.zip |
introduce preCondition for setUserValue to provide atomic check-and-update
Diffstat (limited to 'lib/private/allconfig.php')
-rw-r--r-- | lib/private/allconfig.php | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php index 17872fd4f69..ed4378cfc44 100644 --- a/lib/private/allconfig.php +++ b/lib/private/allconfig.php @@ -9,6 +9,7 @@ namespace OC; use OCP\IDBConnection; +use OCP\PreConditionNotMetException; /** * Class to combine all the configuration options ownCloud offers @@ -140,8 +141,10 @@ class AllConfig implements \OCP\IConfig { * @param string $appName the appName that we want to store the value under * @param string $key the key under which the value is being stored * @param string $value the value that you want to store + * @param string $preCondition only update if the config value was previously the value passed as $preCondition + * @throws \OCP\PreConditionNotMetException if a precondition is specified and is not met */ - public function setUserValue($userId, $appName, $key, $value) { + public function setUserValue($userId, $appName, $key, $value, $preCondition = null) { // Check if the key does exist $sql = 'SELECT `configvalue` FROM `*PREFIX*preferences` '. 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; @@ -154,15 +157,24 @@ class AllConfig implements \OCP\IConfig { return; } - if (!$exists) { + $data = array($value, $userId, $appName, $key); + if (!$exists && $preCondition === null) { $sql = 'INSERT INTO `*PREFIX*preferences` (`configvalue`, `userid`, `appid`, `configkey`)'. 'VALUES (?, ?, ?, ?)'; - } else { + } elseif ($exists) { $sql = 'UPDATE `*PREFIX*preferences` SET `configvalue` = ? '. - 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?'; - + 'WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? '; + + if($preCondition !== null) { + 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` = ?'; + } + $data[] = $preCondition; + } } - $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 @@ -172,6 +184,10 @@ class AllConfig implements \OCP\IConfig { } $this->userCache[$userId][$appName][$key] = $value; } + + if ($preCondition !== null && $affectedRows === 0) { + throw new PreConditionNotMetException; + } } /** |