Completed
Push — V6 ( 8b729c...5d3acf )
by Georges
03:16
created

Driver   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 272
Duplicated Lines 3.68 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 7
dl 10
loc 272
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 10 10 2
A driverCheck() 0 4 2
A driverWrite() 0 47 3
B driverRead() 0 23 4
B driverDelete() 0 31 3
A driverClear() 0 13 2
C driverConnect() 0 60 10
A getHelp() 0 11 1
A getStats() 0 14 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 *
4
 * This file is part of phpFastCache.
5
 *
6
 * @license MIT License (MIT)
7
 *
8
 * For full copyright and license information, please see the docs/CREDITS.txt file.
9
 *
10
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 *
13
 */
14
15
namespace phpFastCache\Drivers\Cassandra;
16
17
use phpFastCache\Core\Pool\DriverBaseTrait;
18
use phpFastCache\Core\Pool\ExtendedCacheItemPoolInterface;
19
use phpFastCache\Entities\driverStatistic;
20
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
21
use phpFastCache\Exceptions\phpFastCacheDriverException;
22
use phpFastCache\Exceptions\phpFastCacheInvalidArgumentException;
23
use phpFastCache\Exceptions\phpFastCacheLogicException;
24
use Psr\Cache\CacheItemInterface;
25
use Cassandra;
26
use Cassandra\Session as CassandraSession;
27
28
/**
29
 * Class Driver
30
 * @package phpFastCache\Drivers
31
 * @property CassandraSession $instance Instance of driver service
32
 */
33
class Driver implements ExtendedCacheItemPoolInterface
34
{
35
    const CASSANDRA_KEY_SPACE = 'phpfastcache';
36
    const CASSANDRA_TABLE = 'cacheItems';
37
38
    use DriverBaseTrait;
39
40
    /**
41
     * Driver constructor.
42
     * @param array $config
43
     * @throws phpFastCacheDriverException
44
     */
45 View Code Duplication
    public function __construct(array $config = [])
46
    {
47
        $this->setup($config);
48
49
        if (!$this->driverCheck()) {
50
            throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
51
        } else {
52
            $this->driverConnect();
53
        }
54
    }
55
56
    /**
57
     * @return bool
58
     */
59
    public function driverCheck()
60
    {
61
        return extension_loaded('Cassandra') && class_exists(\Cassandra::class);
62
    }
63
64
    /**
65
     * @param \Psr\Cache\CacheItemInterface $item
66
     * @return mixed
67
     * @throws phpFastCacheInvalidArgumentException
68
     */
69
    protected function driverWrite(CacheItemInterface $item)
70
    {
71
        /**
72
         * Check for Cross-Driver type confusion
73
         */
74
        if ($item instanceof Item) {
75
            try{
76
                $cacheData = $this->encode($this->driverPreWrap($item));
77
                $options = new Cassandra\ExecutionOptions([
78
                  'arguments' => [
79
                    'cache_uuid' => new Cassandra\Uuid(),
80
                    'cache_id' => $item->getKey(),
81
                    'cache_data' => $cacheData,
82
                    'cache_creation_date' => new Cassandra\Timestamp((new \DateTime())->getTimestamp()),
83
                    'cache_expiration_date' => new Cassandra\Timestamp($item->getExpirationDate()->getTimestamp()),
84
                    'cache_length' => strlen($cacheData)
85
                  ],
86
                  'consistency' => Cassandra::CONSISTENCY_ALL,
87
                  'serial_consistency' => Cassandra::CONSISTENCY_SERIAL
88
                ]);
89
90
                $query = sprintf('INSERT INTO %s.%s
91
                    (
92
                      cache_uuid, 
93
                      cache_id, 
94
                      cache_data, 
95
                      cache_creation_date, 
96
                      cache_expiration_date,
97
                      cache_length
98
                    )
99
                  VALUES (:cache_uuid, :cache_id, :cache_data, :cache_creation_date, :cache_expiration_date, :cache_length);
100
            ', self::CASSANDRA_KEY_SPACE, self::CASSANDRA_TABLE);
101
102
                $result = $this->instance->execute(new Cassandra\SimpleStatement($query), $options);
103
                /**
104
                 * There's no real way atm
105
                 * to know if the item has
106
                 * been really upserted
107
                 */
108
                return $result instanceof Cassandra\Rows;
1 ignored issue
show
Bug introduced by
The class Cassandra\Rows does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
109
            }catch(\Cassandra\Exception\InvalidArgumentException $e){
1 ignored issue
show
Bug introduced by
The class Cassandra\Exception\InvalidArgumentException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
110
                throw new phpFastCacheInvalidArgumentException($e, 0, $e);
111
            }
112
        } else {
113
            throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
114
        }
115
    }
116
117
    /**
118
     * @param \Psr\Cache\CacheItemInterface $item
119
     * @return mixed
120
     */
121
    protected function driverRead(CacheItemInterface $item)
122
    {
123
        try {
124
            $options = new Cassandra\ExecutionOptions([
125
              'arguments' => ['cache_id' => $item->getKey()],
126
              'page_size' => 1
127
            ]);
128
            $query = sprintf(
129
              'SELECT cache_data FROM %s.%s WHERE cache_id = :cache_id;',
130
              self::CASSANDRA_KEY_SPACE,
131
              self::CASSANDRA_TABLE
132
            );
133
            $results = $this->instance->execute(new Cassandra\SimpleStatement($query), $options);
134
135
            if($results instanceof Cassandra\Rows && $results->count() === 1){
1 ignored issue
show
Bug introduced by
The class Cassandra\Rows does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
136
                return $this->decode($results->first()['cache_data']);
137
            }else{
138
                return null;
139
            }
140
        } catch (Cassandra\Exception $e) {
1 ignored issue
show
Bug introduced by
The class Cassandra\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
141
            return null;
142
        }
143
    }
144
145
    /**
146
     * @param \Psr\Cache\CacheItemInterface $item
147
     * @return bool
148
     * @throws phpFastCacheInvalidArgumentException
149
     */
150
    protected function driverDelete(CacheItemInterface $item)
151
    {
152
        /**
153
         * Check for Cross-Driver type confusion
154
         */
155
        if ($item instanceof Item) {
156
            try {
157
                $options = new Cassandra\ExecutionOptions([
158
                  'arguments' => [
159
                    'cache_id' => $item->getKey(),
160
                  ],
161
                ]);
162
                $result = $this->instance->execute(new Cassandra\SimpleStatement(sprintf(
163
                  'DELETE FROM %s.%s WHERE cache_id = :cache_id;',
164
                  self::CASSANDRA_KEY_SPACE,
165
                  self::CASSANDRA_TABLE
166
                )), $options);
167
168
                /**
169
                 * There's no real way atm
170
                 * to know if the item has
171
                 * been really deleted
172
                 */
173
                return $result instanceof Cassandra\Rows;
1 ignored issue
show
Bug introduced by
The class Cassandra\Rows does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
174
            } catch (Cassandra\Exception $e) {
1 ignored issue
show
Bug introduced by
The class Cassandra\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
175
                return false;
176
            }
177
        } else {
178
            throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
179
        }
180
    }
181
182
    /**
183
     * @return bool
184
     */
185
    protected function driverClear()
186
    {
187
        try {
188
            $this->instance->execute(new Cassandra\SimpleStatement(sprintf(
189
              'TRUNCATE %s.%s;',
190
              self::CASSANDRA_KEY_SPACE, self::CASSANDRA_TABLE
191
            )));
192
193
            return true;
194
        } catch (Cassandra\Exception $e) {
1 ignored issue
show
Bug introduced by
The class Cassandra\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
195
            return false;
196
        }
197
    }
198
199
    /**
200
     * @return bool
201
     * @throws phpFastCacheLogicException
202
     * @throws \Cassandra\Exception
203
     */
204
    protected function driverConnect()
205
    {
206
        if ($this->instance instanceof CassandraSession) {
1 ignored issue
show
Bug introduced by
The class Cassandra\Session does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
207
            throw new phpFastCacheLogicException('Already connected to Couchbase server');
208
        } else {
209
            $host = isset($this->config[ 'host' ]) ? $this->config[ 'host' ] : '127.0.0.1';
210
            $port = isset($this->config[ 'port' ]) ? $this->config[ 'port' ] : 9042;
211
            $timeout = isset($this->config[ 'timeout' ]) ? $this->config[ 'timeout' ] : 2;
212
            $password = isset($this->config[ 'password' ]) ? $this->config[ 'password' ] : '';
213
            $username = isset($this->config[ 'username' ]) ? $this->config[ 'username' ] : '';
214
215
            $clusterBuilder = Cassandra::cluster()
216
              ->withContactPoints($host)
217
              ->withPort($port);
218
219
            if(!empty($this->config['ssl']['enabled'])){
220
                if(!empty($this->config['ssl']['verify'])){
221
                    $sslBuilder = Cassandra::ssl()->withVerifyFlags(Cassandra::VERIFY_PEER_CERT);
222
                }else{
223
                    $sslBuilder = Cassandra::ssl()->withVerifyFlags(Cassandra::VERIFY_NONE);
224
                }
225
226
                $clusterBuilder->withSSL($sslBuilder->build());
227
            }
228
229
            $clusterBuilder->withConnectTimeout($timeout);
230
231
            if($username){
232
                $clusterBuilder->withCredentials($username, $password);
233
            }
234
235
            $this->instance = $clusterBuilder->build()->connect();
236
237
            /**
238
             * In case of emergency:
239
             * $this->instance->execute(
240
             *      new Cassandra\SimpleStatement(sprintf("DROP KEYSPACE %s;", self::CASSANDRA_KEY_SPACE))
241
             * );
242
             */
243
244
            $this->instance->execute(new Cassandra\SimpleStatement(sprintf(
245
              "CREATE KEYSPACE IF NOT EXISTS %s WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };",
246
              self::CASSANDRA_KEY_SPACE
247
            )));
248
            $this->instance->execute(new Cassandra\SimpleStatement(sprintf('USE %s;', self::CASSANDRA_KEY_SPACE)));
249
            $this->instance->execute(new Cassandra\SimpleStatement(sprintf('
250
                CREATE TABLE IF NOT EXISTS %s (
251
                    cache_uuid uuid,
252
                    cache_id varchar,
253
                    cache_data text,
254
                    cache_creation_date timestamp,
255
                    cache_expiration_date timestamp,
256
                    cache_length int,
257
                    PRIMARY KEY (cache_id)
258
                );', self::CASSANDRA_TABLE
259
            )));
260
        }
261
262
        return true;
263
    }
264
265
    /********************
266
     *
267
     * PSR-6 Extended Methods
268
     *
269
     *******************/
270
271
    /**
272
     * @return string
273
     */
274
    public function getHelp()
275
    {
276
        return <<<HELP
277
<p>
278
To install the php Cassandra extension via Pecl:
279
<code>sudo pecl install cassandra</code>
280
More information on: https://github.com/datastax/php-driver
281
Please not that this repository only provide php stubs and C/C++ sources, it does NOT provide php client.
282
</p>
283
HELP;
284
    }
285
286
    /**
287
     * @return driverStatistic
288
     * @throws \Cassandra\Exception
289
     */
290
    public function getStats()
291
    {
292
        $result = $this->instance->execute(new Cassandra\SimpleStatement(sprintf(
293
          'SELECT SUM(cache_length) as cache_size FROM %s.%s',
294
          self::CASSANDRA_KEY_SPACE,
295
          self::CASSANDRA_TABLE
296
        )));
297
298
        return (new driverStatistic())
299
          ->setSize($result->first()[ 'cache_size' ])
300
          ->setRawData([])
301
          ->setData(implode(', ', array_keys($this->itemInstances)))
302
          ->setInfo('The cache size represents only the cache data itself without counting data structures associated to the cache entries.');
303
    }
304
}