Completed
Push — master ( 4a0e0f...599b4f )
by Carlos
02:50
created

AerospikeAdapter::removeBin()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 8.8571
cc 5
eloc 4
nc 2
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Linio\Component\Cache\Adapter;
5
6
use Linio\Component\Cache\Exception\KeyNotFoundException;
7
8
class AerospikeAdapter extends AbstractAdapter implements AdapterInterface
9
{
10
    const BIN_KEY = 'v';
11
    const DEFAULT_SET = 'default';
12
13
    /**
14
     * @var \Aerospike
15
     */
16
    protected $db;
17
18
    /**
19
     * @var int
20
     */
21
    protected $ttl;
22
23
    public function __construct(array $config)
24
    {
25
        $aerospikeConfig = [];
26
27
        if (!isset($config['hosts'])) {
28
            throw new InvalidConfigurationException('Missing configuration parameter: hosts');
29
        }
30
31
        // default options
32
        $persistent = true;
33
        $options = [];
34
        $this->ttl = 0;
35
36
        if (isset($config['persistent'])) {
37
            $persistent = (bool) $config['persistent'];
38
        }
39
40
        if (isset($config['options'])) {
41
            $options = $config['options'];
42
        }
43
44
        if (isset($config['ttl'])) {
45
            $this->ttl = $config['ttl'];
46
        }
47
48
        if (isset($config['cache_not_found_keys'])) {
49
            $this->cacheNotFoundKeys = (bool) $config['cache_not_found_keys'];
50
        }
51
52
        $aerospikeConfig['hosts'] = $config['hosts'];
53
54
        $this->db = new \Aerospike($aerospikeConfig, $persistent, $options);
55
        if (!$this->db->isConnected()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->db->isConnected() of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
56
            throw new \RuntimeException("Failed to connect to Aerospike Server [{$this->db->errorno()}]: {$this->db->error()}\n");
57
        }
58
    }
59
60
    public function get(string $key)
61
    {
62
        $namespacedKey = $this->getNamespacedKey($key);
63
        $status = $this->db->get($namespacedKey, $metadata);
0 ignored issues
show
Bug introduced by
It seems like $namespacedKey defined by $this->getNamespacedKey($key) on line 62 can also be of type null; however, Aerospike::get() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
64
65
        if ($status != \Aerospike::OK) {
66
            throw new KeyNotFoundException();
67
        }
68
69
        return $this->removeBin($metadata);
70
    }
71
72
    public function getMulti(array $keys): array
73
    {
74
        $namespacedKeys = [];
75
        foreach ($keys as $key) {
76
            $namespacedKeys[] = $this->getNamespacedKey($key);
77
        }
78
79
        $status = $this->db->getMany($namespacedKeys, $result);
80
        if ($status != \Aerospike::OK) {
81
            return [];
82
        }
83
84
        $values = [];
85
        foreach ($result as $entry) {
86
            $key = $entry['key']['key'];
87
            $value = $this->removeBin($entry);
88
89
            if ($value === null) {
90
                continue;
91
            }
92
93
            $values[$key] = $value;
94
        }
95
96
        return $values;
97
    }
98
99
    public function set(string $key, $value): bool
100
    {
101
        $status = $this->db->put($this->getNamespacedKey($key), $this->createBin($value), $this->ttl);
0 ignored issues
show
Bug introduced by
It seems like $this->getNamespacedKey($key) targeting Linio\Component\Cache\Ad...ter::getNamespacedKey() can also be of type null; however, Aerospike::put() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
102
103
        return ($status == \Aerospike::OK);
104
    }
105
106
    public function setMulti(array $data): bool
107
    {
108
        $success = true;
109
        foreach ($data as $key => $value) {
110
            $success = $success && $this->set($key, $value);
111
        }
112
113
        return $success;
114
    }
115
116
    public function contains(string $key): bool
117
    {
118
        $status = $this->db->exists($this->getNamespacedKey($key), $metadata);
0 ignored issues
show
Bug introduced by
It seems like $this->getNamespacedKey($key) targeting Linio\Component\Cache\Ad...ter::getNamespacedKey() can also be of type null; however, Aerospike::exists() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
119
120
        return ($status == \Aerospike::OK);
121
    }
122
123
    public function delete(string $key): bool
124
    {
125
        $namespacedKey = $this->getNamespacedKey($key);
126
127
        $this->db->remove($namespacedKey);
0 ignored issues
show
Bug introduced by
It seems like $namespacedKey defined by $this->getNamespacedKey($key) on line 125 can also be of type null; however, Aerospike::remove() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
128
129
        return true;
130
    }
131
132
    public function deleteMulti(array $keys): bool
133
    {
134
        foreach ($keys as $key) {
135
            $this->delete($key);
136
        }
137
138
        return true;
139
    }
140
141
    public function flush(): bool
142
    {
143
        $this->db->scan(
144
            $this->namespace,
145
            static::DEFAULT_SET,
146
            function ($record) {
147
                unset($record['key']['key']);
148
                $this->db->remove($record['key']);
149
            }
150
        );
151
152
        return true;
153
    }
154
155
    protected function getNamespacedKey(string $key)
156
    {
157
        return $this->db->initKey($this->namespace, static::DEFAULT_SET, $key);
158
    }
159
160
    protected function createBin($value): array
161
    {
162
        return [self::BIN_KEY => $value];
163
    }
164
165
    protected function removeBin($metadata)
166
    {
167
        if (!is_array($metadata) || !array_key_exists('bins', $metadata) || !is_array($metadata['bins']) || !array_key_exists(static::BIN_KEY, $metadata['bins'])) {
168
            return null;
169
        }
170
171
        return $metadata['bins'][static::BIN_KEY];
172
    }
173
}
174