aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Memcache/CADTrait.php
blob: 3bf94246338f74f6fdd94367008ae8811822254c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
/**
 * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
 * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
 * SPDX-License-Identifier: AGPL-3.0-only
 */
namespace OC\Memcache;

trait CADTrait {
	abstract public function get($key);

	abstract public function remove($key);

	abstract public function add($key, $value, $ttl = 0);

	/**
	 * Compare and delete
	 *
	 * @param string $key
	 * @param mixed $old
	 * @return bool
	 */
	public function cad($key, $old) {
		//no native cas, emulate with locking
		if ($this->add($key . '_lock', true)) {
			if ($this->get($key) === $old) {
				$this->remove($key);
				$this->remove($key . '_lock');
				return true;
			} else {
				$this->remove($key . '_lock');
				return false;
			}
		} else {
			return false;
		}
	}

	public function ncad(string $key, mixed $old): bool {
		//no native cad, emulate with locking
		if ($this->add($key . '_lock', true)) {
			$value = $this->get($key);
			if ($value !== null && $value !== $old) {
				$this->remove($key);
				$this->remove($key . '_lock');
				return true;
			} else {
				$this->remove($key . '_lock');
				return false;
			}
		} else {
			return false;
		}
	}
}
pace = strtolower(substr($appNamespace, strrpos($appNamespace, '\\') + 1)); $this->namespaces[$appNamespace] = $appName; } /** * @param string $appName * @param DIContainer $container */ public function registerAppContainer($appName, DIContainer $container) { $this->appContainers[strtolower(App::buildAppNamespace($appName, ''))] = $container; } /** * @param string $namespace * @param string $sensitiveNamespace * @return DIContainer * @throws QueryException */ protected function getAppContainer($namespace, $sensitiveNamespace) { if (isset($this->appContainers[$namespace])) { return $this->appContainers[$namespace]; } if (isset($this->namespaces[$namespace])) { if (!isset($this->hasNoAppContainer[$namespace])) { $applicationClassName = 'OCA\\' . $sensitiveNamespace . '\\AppInfo\\Application'; if (class_exists($applicationClassName)) { new $applicationClassName(); if (isset($this->appContainers[$namespace])) { return $this->appContainers[$namespace]; } } $this->hasNoAppContainer[$namespace] = true; } return new DIContainer($this->namespaces[$namespace]); } throw new QueryException(); } /** * @param string $name name of the service to query for * @return mixed registered service for the given $name * @throws QueryException if the query could not be resolved */ public function query($name) { $name = $this->sanitizeName($name); if (isset($this[$name])) { return $this[$name]; } // In case the service starts with OCA\ we try to find the service in // the apps container first. if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) { $segments = explode('\\', $name); try { $appContainer = $this->getAppContainer(strtolower($segments[1]), $segments[1]); return $appContainer->queryNoFallback($name); } catch (QueryException $e) { // Didn't find the service or the respective app container, // ignore it and fall back to the core container. } } else if (strpos($name, 'OC\\Settings\\') === 0 && substr_count($name, '\\') >= 3) { $segments = explode('\\', $name); try { $appContainer = $this->getAppContainer(strtolower($segments[1]), $segments[1]); return $appContainer->queryNoFallback($name); } catch (QueryException $e) { // Didn't find the service or the respective app container, // ignore it and fall back to the core container. } } return parent::query($name); } }