Passed
Push — master ( 0fb6fd...5bf96e )
by Julius
15:41 queued 13s
created

Redis   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 54
c 1
b 0
f 0
dl 0
loc 153
rs 10
wmc 27

14 Methods

Rating   Name   Duplication   Size   Complexity  
A isAvailable() 0 2 1
A set() 0 5 2
A setTTL() 0 2 1
A getCache() 0 5 2
A __construct() 0 2 1
A get() 0 6 3
A remove() 0 5 2
A inc() 0 2 1
A cas() 0 13 3
A clear() 0 6 2
A dec() 0 5 2
A cad() 0 10 2
A hasKey() 0 2 1
A add() 0 12 4
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Christoph Wurst <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Jörn Friedrich Dreyer <[email protected]>
9
 * @author Morris Jobke <[email protected]>
10
 * @author Robin Appelman <[email protected]>
11
 * @author Robin McCorkell <[email protected]>
12
 * @author Roeland Jago Douma <[email protected]>
13
 * @author Stefan Weil <[email protected]>
14
 *
15
 * @license AGPL-3.0
16
 *
17
 * This code is free software: you can redistribute it and/or modify
18
 * it under the terms of the GNU Affero General Public License, version 3,
19
 * as published by the Free Software Foundation.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24
 * GNU Affero General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU Affero General Public License, version 3,
27
 * along with this program. If not, see <http://www.gnu.org/licenses/>
28
 *
29
 */
30
namespace OC\Memcache;
31
32
use OCP\IMemcacheTTL;
33
34
class Redis extends Cache implements IMemcacheTTL {
35
	/**
36
	 * @var \Redis|\RedisCluster $cache
37
	 */
38
	private static $cache = null;
39
40
	public function __construct($prefix = '', string $logFile = '') {
0 ignored issues
show
Unused Code introduced by
The parameter $logFile is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

40
	public function __construct($prefix = '', /** @scrutinizer ignore-unused */ string $logFile = '') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
41
		parent::__construct($prefix);
42
	}
43
44
	/**
45
	 * @return \Redis|\RedisCluster|null
46
	 * @throws \Exception
47
	 */
48
	public function getCache() {
49
		if (is_null(self::$cache)) {
50
			self::$cache = \OC::$server->getGetRedisFactory()->getInstance();
51
		}
52
		return self::$cache;
53
	}
54
55
	public function get($key) {
56
		$result = $this->getCache()->get($this->getPrefix() . $key);
57
		if ($result === false && !$this->getCache()->exists($this->getPrefix() . $key)) {
58
			return null;
59
		} else {
60
			return json_decode($result, true);
61
		}
62
	}
63
64
	public function set($key, $value, $ttl = 0) {
65
		if ($ttl > 0) {
66
			return $this->getCache()->setex($this->getPrefix() . $key, $ttl, json_encode($value));
67
		} else {
68
			return $this->getCache()->set($this->getPrefix() . $key, json_encode($value));
69
		}
70
	}
71
72
	public function hasKey($key) {
73
		return (bool)$this->getCache()->exists($this->getPrefix() . $key);
74
	}
75
76
	public function remove($key) {
77
		if ($this->getCache()->del($this->getPrefix() . $key)) {
78
			return true;
79
		} else {
80
			return false;
81
		}
82
	}
83
84
	public function clear($prefix = '') {
85
		$prefix = $this->getPrefix() . $prefix . '*';
86
		$keys = $this->getCache()->keys($prefix);
87
		$deleted = $this->getCache()->del($keys);
88
89
		return (is_array($keys) && (count($keys) === $deleted));
90
	}
91
92
	/**
93
	 * Set a value in the cache if it's not already stored
94
	 *
95
	 * @param string $key
96
	 * @param mixed $value
97
	 * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
98
	 * @return bool
99
	 */
100
	public function add($key, $value, $ttl = 0) {
101
		// don't encode ints for inc/dec
102
		if (!is_int($value)) {
103
			$value = json_encode($value);
104
		}
105
106
		$args = ['nx'];
107
		if ($ttl !== 0 && is_int($ttl)) {
108
			$args['ex'] = $ttl;
109
		}
110
111
		return $this->getCache()->set($this->getPrefix() . $key, (string)$value, $args);
112
	}
113
114
	/**
115
	 * Increase a stored number
116
	 *
117
	 * @param string $key
118
	 * @param int $step
119
	 * @return int | bool
120
	 */
121
	public function inc($key, $step = 1) {
122
		return $this->getCache()->incrBy($this->getPrefix() . $key, $step);
123
	}
124
125
	/**
126
	 * Decrease a stored number
127
	 *
128
	 * @param string $key
129
	 * @param int $step
130
	 * @return int | bool
131
	 */
132
	public function dec($key, $step = 1) {
133
		if (!$this->hasKey($key)) {
134
			return false;
135
		}
136
		return $this->getCache()->decrBy($this->getPrefix() . $key, $step);
137
	}
138
139
	/**
140
	 * Compare and set
141
	 *
142
	 * @param string $key
143
	 * @param mixed $old
144
	 * @param mixed $new
145
	 * @return bool
146
	 */
147
	public function cas($key, $old, $new) {
148
		if (!is_int($new)) {
149
			$new = json_encode($new);
150
		}
151
		$this->getCache()->watch($this->getPrefix() . $key);
152
		if ($this->get($key) === $old) {
153
			$result = $this->getCache()->multi()
154
				->set($this->getPrefix() . $key, $new)
155
				->exec();
156
			return $result !== false;
157
		}
158
		$this->getCache()->unwatch();
159
		return false;
160
	}
161
162
	/**
163
	 * Compare and delete
164
	 *
165
	 * @param string $key
166
	 * @param mixed $old
167
	 * @return bool
168
	 */
169
	public function cad($key, $old) {
170
		$this->getCache()->watch($this->getPrefix() . $key);
171
		if ($this->get($key) === $old) {
172
			$result = $this->getCache()->multi()
173
				->del($this->getPrefix() . $key)
174
				->exec();
0 ignored issues
show
Bug introduced by
The method exec() does not exist on integer. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

174
				->/** @scrutinizer ignore-call */ exec();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
175
			return $result !== false;
176
		}
177
		$this->getCache()->unwatch();
178
		return false;
179
	}
180
181
	public function setTTL($key, $ttl) {
182
		$this->getCache()->expire($this->getPrefix() . $key, $ttl);
183
	}
184
185
	public static function isAvailable(): bool {
186
		return \OC::$server->getGetRedisFactory()->isAvailable();
187
	}
188
}
189