Test Setup Failed
Push — master ( 5cf724...b9960b )
by Roman
14:09
created

Connection   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 306
Duplicated Lines 10.46 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 39
lcom 1
cbo 4
dl 32
loc 306
rs 9.28
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 24 4
A table() 0 8 1
A getCassandraCluster() 0 4 1
A getCassandraSession() 0 4 1
A getKeyspace() 0 4 1
C createCluster() 6 41 15
A disconnect() 0 4 1
A getDriverName() 0 4 1
A select() 0 12 2
A insertBulk() 0 4 1
A batchStatement() 0 17 3
A statement() 12 12 2
A affectingStatement() 14 14 2
A getDefaultPostProcessor() 0 4 1
A getDefaultQueryGrammar() 0 4 1
A getDefaultSchemaGrammar() 0 4 1
A __call() 0 4 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
namespace fuitad\LaravelCassandra;
4
5
use Cassandra;
6
use Cassandra\BatchStatement;
7
8
class Connection extends \Illuminate\Database\Connection
9
{
10
    const DEFAULT_PAGE_SIZE = 5000;
11
    
12
    /**
13
     * The Cassandra keyspace
14
     *
15
     * @var string
16
     */
17
    protected $keyspace;
18
19
    /**
20
     * The Cassandra cluster
21
     *
22
     * @var \Cassandra\Cluster
23
     */
24
    protected $cluster;
25
26
    /**
27
     * The Cassandra connection handler.
28
     *
29
     * @var \Cassandra\Session
30
     */
31
    protected $session;
32
33
    /**
34
     * Create a new database connection instance.
35
     *
36
     * @param  array   $config
37
     */
38
    public function __construct(array $config)
39
    {
40
        $this->config = $config;
41
        if (empty($this->config['page_size'])) {
42
            $this->config['page_size'] = self::DEFAULT_PAGE_SIZE;
43
        }
44
        
45
        // You can pass options directly to the Cassandra constructor
46
        $options = array_get($config, 'options', []);
47
48
        // Create the connection
49
        $this->cluster = $this->createCluster(null, $config, $options);
50
51
        if (isset($options['database']) || isset($config['database'])) {
52
            $this->keyspace = $config['database'];
53
            $this->session = $this->cluster->connect($config['database']);
54
        }
55
56
        $this->useDefaultPostProcessor();
57
58
        $this->useDefaultSchemaGrammar();
59
60
        $this->setQueryGrammar($this->getDefaultQueryGrammar());
61
    }
62
63
    /**
64
     * Begin a fluent query against a database table.
65
     *
66
     * @param  string  $table
67
     * @return Query\Builder
68
     */
69
    public function table($table)
70
    {
71
        $processor = $this->getPostProcessor();
72
73
        $query = new Query\Builder($this, null, $processor);
0 ignored issues
show
Documentation introduced by
$processor is of type object<Illuminate\Databa...y\Processors\Processor>, but the function expects a null|object<fuitad\Larav...sandra\Query\Processor>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
74
75
        return $query->from($table);
76
    }
77
78
    /**
79
     * return Cassandra cluster.
80
     *
81
     * @return \Cassandra\Cluster
82
     */
83
    public function getCassandraCluster()
84
    {
85
        return $this->cluster;
86
    }
87
88
    /**
89
     * return Cassandra Session.
90
     *
91
     * @return \Cassandra\Session
92
     */
93
    public function getCassandraSession()
94
    {
95
        return $this->session;
96
    }
97
98
    /**
99
     * Return the Cassandra keyspace
100
     *
101
     * @return string
102
     */
103
    public function getKeyspace()
104
    {
105
        return $this->keyspace;
106
    }
107
108
    /**
109
     * Create a new Cassandra cluster object.
110
     *
111
     * @param  string  $dsn
112
     * @param  array   $config
113
     * @param  array   $options
114
     * @return \Cassandra\Cluster
115
     */
116
    protected function createCluster($dsn, array $config, array $options)
0 ignored issues
show
Unused Code introduced by
The parameter $dsn is not used and could be removed.

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

Loading history...
117
    {
118
        // By default driver options is an empty array.
119
        $driverOptions = [];
0 ignored issues
show
Unused Code introduced by
$driverOptions is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
120
121
        if (isset($config['driver_options']) && is_array($config['driver_options'])) {
122
            $driverOptions = $config['driver_options'];
0 ignored issues
show
Unused Code introduced by
$driverOptions is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
123
        }
124
125
        $cluster = Cassandra::cluster();
126
127
        // Check if the credentials are not already set in the options
128 View Code Duplication
        if (!isset($options['username']) && !empty($config['username'])) {
129
            $options['username'] = $config['username'];
130
        }
131 View Code Duplication
        if (!isset($options['password']) && !empty($config['password'])) {
132
            $options['password'] = $config['password'];
133
        }
134
135
        // Authentication
136
        if (isset($options['username']) && isset($options['password'])) {
137
            $cluster->withCredentials($options['username'], $options['password']);
138
        }
139
140
        // Contact Points/Host
141
        if (isset($options['contactpoints']) || (isset($config['host']) && !empty($config['host']))) {
142
            $contactPoints = $config['host'];
143
144
            if (isset($options['contactpoints'])) {
145
                $contactPoints = $options['contactpoints'];
146
            }
147
148
            call_user_func_array([$cluster, 'withContactPoints'], $contactPoints);
149
        }
150
151
        if (!isset($options['port']) && !empty($config['port'])) {
152
            $cluster->withPort((int) $config['port']);
153
        }
154
155
        return $cluster->build();
156
    }
157
158
    /**
159
     * Disconnect from the underlying Cassandra connection.
160
     */
161
    public function disconnect()
162
    {
163
        unset($this->connection);
164
    }
165
166
    /**
167
     * Get the PDO driver name.
168
     *
169
     * @return string
170
     */
171
    public function getDriverName()
172
    {
173
        return 'cassandra';
174
    }
175
176
    /**
177
     * Run a select statement against the database.
178
     *
179
     * @param  string  $query
180
     * @param  array  $bindings
181
     * @param  bool  $useReadPdo
182
     * @return array
183
     */
184
    public function select($query, $bindings = [], $useReadPdo = true)
185
    {
186
        return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) {
187
            if ($this->pretending()) {
188
                return [];
189
            }
190
191
            $preparedStatement = $this->session->prepare($query);
192
193
            return $this->session->execute($preparedStatement, ['arguments' => $bindings, 'page_size' => (int)$this->config['page_size']]);
194
        });
195
    }
196
197
    /**
198
     * Run an bulk insert statement against the database.
199
     *
200
     * @param  array  $queries
201
     * @param  array  $bindings
202
     * @return bool
203
     */
204
    public function insertBulk($queries = [], $bindings = [], $type = Cassandra::BATCH_LOGGED)
205
    {
206
        return $this->batchStatement($queries, $bindings, $type);
207
    }
208
209
    /**
210
     * Execute a group of queries inside a batch statement against the database.
211
     *
212
     * @param  array  $queries
213
     * @param  array  $bindings
214
     * @return bool
215
     */
216
    public function batchStatement($queries = [], $bindings = [], $type = Cassandra::BATCH_LOGGED)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed.

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

Loading history...
217
    {
218
        return $this->run($queries, $bindings, function ($queries, $bindings) {
0 ignored issues
show
Documentation introduced by
$queries is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
219
            if ($this->pretending()) {
220
                return [];
221
            }
222
223
            $batch = new BatchStatement(Cassandra::BATCH_LOGGED);
224
225
            foreach ($queries as $k => $query) {
226
                $preparedStatement = $this->session->prepare($query);
227
                $batch->add($preparedStatement, $bindings[$k]);
228
            }
229
230
            return $this->session->execute($batch);
231
        });
232
    }
233
234
    /**
235
     * Execute an SQL statement and return the boolean result.
236
     *
237
     * @param  string  $query
238
     * @param  array   $bindings
239
     * @return bool
240
     */
241 View Code Duplication
    public function statement($query, $bindings = [])
242
    {
243
        return $this->run($query, $bindings, function ($query, $bindings) {
244
            if ($this->pretending()) {
245
                return [];
246
            }
247
248
            $preparedStatement = $this->session->prepare($query);
249
250
            return $this->session->execute($preparedStatement, ['arguments' => $bindings]);
251
        });
252
    }
253
254
    /**
255
     * Because Cassandra is an eventually consistent database, it's not possible to obtain
256
     * the affected count for statements so we're just going to return 0, based on the idea
257
     * that if the query fails somehow, an exception will be thrown
258
     *
259
     * @param  string  $query
260
     * @param  array   $bindings
261
     * @return int
262
     */
263 View Code Duplication
    public function affectingStatement($query, $bindings = [])
264
    {
265
        return $this->run($query, $bindings, function ($query, $bindings) {
266
            if ($this->pretending()) {
267
                return 0;
268
            }
269
270
            $preparedStatement = $this->session->prepare($query);
271
272
            $this->session->execute($preparedStatement, ['arguments' => $bindings]);
273
274
            return 1;
275
        });
276
    }
277
278
    /**
279
     * @inheritdoc
280
     */
281
    protected function getDefaultPostProcessor()
282
    {
283
        return new Query\Processor();
284
    }
285
286
    /**
287
     * @inheritdoc
288
     */
289
    protected function getDefaultQueryGrammar()
290
    {
291
        return new Query\Grammar();
292
    }
293
294
    /**
295
     * @inheritdoc
296
     */
297
    protected function getDefaultSchemaGrammar()
298
    {
299
        //return new Schema\Grammar();
300
    }
301
302
    /**
303
     * Dynamically pass methods to the connection.
304
     *
305
     * @param  string  $method
306
     * @param  array   $parameters
307
     * @return mixed
308
     */
309
    public function __call($method, $parameters)
310
    {
311
        return call_user_func_array([$this->cluster, $method], $parameters);
312
    }
313
}
314