Completed
Push — V6 ( 9b19e1...52abd1 )
by Georges
03:32
created

Driver   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 213
Duplicated Lines 4.69 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 35
c 0
b 0
f 0
lcom 1
cbo 9
dl 10
loc 213
rs 9

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 10 10 2
A driverCheck() 0 4 1
A driverWrite() 0 16 3
B driverRead() 0 16 5
A driverDelete() 0 16 3
A driverClear() 0 12 2
F driverConnect() 0 38 12
A getLatestDocumentRevision() 0 16 2
A getDatabaseName() 0 4 2
A createDatabase() 0 6 2
A getStats() 0 10 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\Couchdb;
16
17
use Doctrine\CouchDB\CouchDBClient as CouchdbClient;
18
use Doctrine\CouchDB\CouchDBException;
19
use phpFastCache\Core\Pool\DriverBaseTrait;
20
use phpFastCache\Core\Pool\ExtendedCacheItemPoolInterface;
21
use phpFastCache\Entities\driverStatistic;
22
use phpFastCache\Exceptions\phpFastCacheDriverCheckException;
23
use phpFastCache\Exceptions\phpFastCacheDriverException;
24
use phpFastCache\Exceptions\phpFastCacheInvalidArgumentException;
25
use Psr\Cache\CacheItemInterface;
26
27
/**
28
 * Class Driver
29
 * @package phpFastCache\Drivers
30
 * @property CouchdbClient $instance Instance of driver service
31
 */
32
class Driver implements ExtendedCacheItemPoolInterface
33
{
34
    use DriverBaseTrait;
35
36
    /**
37
     * Driver constructor.
38
     * @param array $config
39
     * @throws phpFastCacheDriverException
40
     */
41 View Code Duplication
    public function __construct(array $config = [])
42
    {
43
        $this->setup($config);
44
45
        if (!$this->driverCheck()) {
46
            throw new phpFastCacheDriverCheckException(sprintf(self::DRIVER_CHECK_FAILURE, $this->getDriverName()));
47
        } else {
48
            $this->driverConnect();
49
        }
50
    }
51
52
    /**
53
     * @return bool
54
     */
55
    public function driverCheck()
56
    {
57
        return class_exists('Doctrine\CouchDB\CouchDBClient');
58
    }
59
60
    /**
61
     * @param \Psr\Cache\CacheItemInterface $item
62
     * @return mixed
63
     * @throws phpFastCacheDriverException
64
     * @throws phpFastCacheInvalidArgumentException
65
     */
66
    protected function driverWrite(CacheItemInterface $item)
67
    {
68
        /**
69
         * Check for Cross-Driver type confusion
70
         */
71
        if ($item instanceof Item) {
72
            try{
73
                $this->instance->putDocument(['data' => $this->encode($this->driverPreWrap($item))], $item->getEncodedKey(), $this->getLatestDocumentRevision($item->getEncodedKey()));
74
            }catch (CouchDBException $e){
75
                throw new phpFastCacheDriverException('Got error while trying to upsert a document: ' . $e->getMessage(), null, $e);
76
            }
77
            return true;
78
        } else {
79
            throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
80
        }
81
    }
82
83
    /**
84
     * @param \Psr\Cache\CacheItemInterface $item
85
     * @return mixed
86
     * @throws phpFastCacheDriverException
87
     */
88
    protected function driverRead(CacheItemInterface $item)
89
    {
90
        try{
91
            $response = $this->instance->findDocument($item->getEncodedKey());
92
        }catch (CouchDBException $e){
93
            throw new phpFastCacheDriverException('Got error while trying to get a document: ' . $e->getMessage(), null, $e);
94
        }
95
96
        if($response->status === 404 || empty($response->body['data'])){
97
            return null;
98
        }else if($response->status === 200){
99
            return $this->decode($response->body['data']);
100
        }else{
101
            throw new phpFastCacheDriverException('Got unexpected HTTP status: ' . $response->status);
102
        }
103
    }
104
105
    /**
106
     * @param \Psr\Cache\CacheItemInterface $item
107
     * @return bool
108
     * @throws phpFastCacheDriverException
109
     * @throws phpFastCacheInvalidArgumentException
110
     */
111
    protected function driverDelete(CacheItemInterface $item)
112
    {
113
        /**
114
         * Check for Cross-Driver type confusion
115
         */
116
        if ($item instanceof Item) {
117
            try{
118
                $this->instance->deleteDocument($item->getEncodedKey(), $this->getLatestDocumentRevision($item->getEncodedKey()));
119
            }catch (CouchDBException $e){
120
                throw new phpFastCacheDriverException('Got error while trying to delete a document: ' . $e->getMessage(), null, $e);
121
            }
122
            return true;
123
        } else {
124
            throw new phpFastCacheInvalidArgumentException('Cross-Driver type confusion detected');
125
        }
126
    }
127
128
    /**
129
     * @return bool
130
     * @throws phpFastCacheDriverException
131
     */
132
    protected function driverClear()
133
    {
134
        try{
135
            $this->instance->deleteDatabase($this->getDatabaseName());
136
            $this->createDatabase();
137
        }catch (CouchDBException $e){
138
            throw new phpFastCacheDriverException('Got error while trying to delete and recreate the database: ' . $e->getMessage(), null, $e);
139
        }
140
141
142
        return true;
143
    }
144
145
    /**
146
     * @return bool
147
     */
148
    protected function driverConnect()
149
    {
150
        if ($this->instance instanceof CouchdbClient) {
151
            throw new \LogicException('Already connected to Couchdb server');
152
        } else {
153
            $host = isset($this->config[ 'host' ]) ? $this->config[ 'host' ] : '127.0.0.1';
154
            $ssl = isset($this->config[ 'ssl' ]) ? $this->config[ 'ssl' ] : false;
155
            $port = isset($this->config[ 'port' ]) ? $this->config[ 'port' ] : 5984;
156
            $path = isset($this->config[ 'path' ]) ? $this->config[ 'path' ] : '/';
157
            $username = isset($this->config[ 'username' ]) ? $this->config[ 'username' ] : '';
158
            $password = isset($this->config[ 'password' ]) ? $this->config[ 'password' ] : '';
159
            $timeout = isset($this->config[ 'timeout' ]) ? $this->config[ 'timeout' ] : 10;
160
161
            $url = ($ssl ? 'https://' : 'http://');
162
            if($username)
163
            {
164
                $url .= "{$username}";
165
                if($password)
166
                {
167
                    $url .= ":{$password}";
168
                }
169
                $url .= '@';
170
            }
171
            $url .= $host;
172
            $url .= ":{$port}";
173
            $url .= $path;
174
175
            $this->instance = CouchDBClient::create([
176
              'dbname' => $this->getDatabaseName(),
177
              'url' => $url,
178
              'timeout' => $timeout
179
            ]);
180
181
            $this->createDatabase();
182
        }
183
184
        return true;
185
    }
186
187
    /**
188
     * @return string|null
189
     */
190
    protected function getLatestDocumentRevision($docId)
191
    {
192
        $path = '/' . $this->getDatabaseName() . '/' . urlencode($docId);
193
194
        $response = $this->instance->getHttpClient()->request(
195
          'GET',// At this moment HEAD requests are not working: https://github.com/doctrine/couchdb-client/issues/72
196
          $path,
197
          null,
198
          false
199
        );
200
        if(!empty($response->headers['etag'])){
201
            return trim($response->headers['etag'], " '\"\t\n\r\0\x0B");
202
        }else{
203
            return null;
204
        }
205
    }
206
207
    /**
208
     * @return string
209
     */
210
    protected function getDatabaseName()
211
    {
212
        return isset($this->config[ 'database' ]) ? $this->config[ 'database' ] : 'phpfastcache';
213
    }
214
215
    /**
216
     * @return void
217
     */
218
    protected function createDatabase()
219
    {
220
        if(!in_array($this->instance->getDatabase(), $this->instance->getAllDatabases(), true)){
221
            $this->instance->createDatabase($this->instance->getDatabase());
222
        }
223
    }
224
225
    /********************
226
     *
227
     * PSR-6 Extended Methods
228
     *
229
     *******************/
230
231
    /**
232
     * @return driverStatistic
233
     */
234
    public function getStats()
235
    {
236
        $info = $this->instance->getDatabaseInfo();
237
238
        return (new driverStatistic())
239
          ->setSize($info['sizes']['active'])
240
          ->setRawData($info)
241
          ->setData(implode(', ', array_keys($this->itemInstances)))
242
          ->setInfo('Couchdb version ' . $this->instance->getVersion() . "\n For more information see RawData.");
243
    }
244
}