Test Setup Failed
Push — master ( eaec61...fed08a )
by Ion
02:23
created

RedisObjectStorageAdapter::store()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 3
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Infrastructure\ObjectStorage;
6
7
use App\Infrastructure\Exception\ObjectNotFoundException;
8
use DateTime;
9
use Redis;
10
11
/**
12
 * This adapter stores values in Redis using following approach:
13
 *  - Stores following data in sorted set:
14
 *      key:   Key
15
 *      value: SHA512(Key):Timestamp
16
 *      score: Timestamp
17
 *  - Then stores the actual data as a key-value. The key is taken from value of the sorted set.
18
 * This is because sorted set requires uniqueness of the values which would break the history if someone changes values to:
19
 *  value1 -> value2 -> value1.
20
 */
21
class RedisObjectStorageAdapter implements ObjectStorageAdapter
22
{
23
    protected Redis $redis;
24
25 6
    public function __construct(Redis $redis)
26
    {
27 6
        $this->redis = $redis;
28 6
    }
29
30
    /**
31
     * {@inheritdoc}
32
     */
33 4
    public function store(string $key, $data, DateTime $timestamp): void
34
    {
35 4
        $storageKey = sprintf('%s:%s', hash('sha512', $key), $timestamp->getTimestamp());
36 4
        $this->redis->zAdd($key, ['CH'], $timestamp->getTimestamp(), $storageKey);
37 4
        $this->redis->set($storageKey, json_encode($data));
38 4
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43 5
    public function get(string $key, DateTime $timestamp)
44
    {
45 5
        $score = (string) $timestamp->getTimestamp();
46 5
        $result = $this->redis->zRevRangeByScore($key, $score, '-inf', ['limit' => [0, 1]]);
47
48 5
        if (!\count($result)) {
49 2
            throw new ObjectNotFoundException($key, $timestamp);
50
        }
51
52 4
        return json_decode($this->redis->get($result[0]));
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 3
    public function clear(): void
59
    {
60 3
        $this->redis->flushDB();
61 3
    }
62
}
63