Test Setup Failed
Push — testing ( 88fcdf...a661a9 )
by Roman
03:39
created

Connection::getDefaultPostProcessor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace lroman242\LaravelCassandra;
4
5
use Cassandra;
6
use Cassandra\BatchStatement;
7
use Closure;
8
9
class Connection extends \Illuminate\Database\Connection
10
{
11
    const DEFAULT_PAGE_SIZE = 5000;
12
    
13
    /**
14
     * The Cassandra keyspace
15
     *
16
     * @var string
17
     */
18
    protected $keyspace;
19
20
    /**
21
     * The Cassandra cluster
22
     *
23
     * @var \Cassandra\Cluster
24
     */
25
    protected $cluster;
26
27
    /**
28
     * The Cassandra connection handler.
29
     *
30
     * @var \Cassandra\Session
31
     */
32
    protected $session;
33
34
    /**
35
     * The config
36
     *
37
     * @var array
38
     */
39
    protected $config;
40
41
    /**
42
     * Create a new database connection instance.
43
     *
44
     * @param  array   $config
45
     */
46
    public function __construct(array $config)
47
    {
48
        $this->config = $config;
49
        if (empty($this->config['page_size'])) {
50
            $this->config['page_size'] = self::DEFAULT_PAGE_SIZE;
51
        }
52
53
        // You can pass options directly to the Cassandra constructor
54
        $options = array_get($config, 'options', []);
55
56
        // Create the connection
57
        $this->cluster = $this->createCluster($config, $options);
58
59
        if (isset($options['database']) || isset($config['keyspace'])) {
60
            $keyspaceName = isset($options['database']) ? $options['database'] : $config['keyspace'];
61
62
            $this->keyspace = $keyspaceName;
63
            $this->session = $this->cluster->connect($keyspaceName);
64
        }
65
66
        $this->useDefaultPostProcessor();
67
68
        $this->useDefaultSchemaGrammar();
69
70
        $this->setQueryGrammar($this->getDefaultQueryGrammar());
71
    }
72
73
    /**
74
     * Begin a fluent query against a database table.
75
     *
76
     * @param  string  $table
77
     * @return Query\Builder
78
     */
79
    public function table($table)
80
    {
81
        $processor = $this->getPostProcessor();
82
83
        $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<lroman242\La...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...
84
85
        return $query->from($table);
86
    }
87
88
    /**
89
     * return Cassandra cluster.
90
     *
91
     * @return \Cassandra\Cluster
92
     */
93
    public function getCassandraCluster()
94
    {
95
        return $this->cluster;
96
    }
97
98
    /**
99
     * return Cassandra Session.
100
     *
101
     * @return \Cassandra\Session
102
     */
103
    public function getCassandraSession()
104
    {
105
        return $this->session;
106
    }
107
108
    /**
109
     * Return the Cassandra keyspace
110
     *
111
     * @return string
112
     */
113
    public function getKeyspace()
114
    {
115
        return $this->keyspace;
116
    }
117
118
    /**
119
     * Create a new Cassandra cluster object.
120
     *
121
     * @param  array   $config
122
     * @param  array   $options
123
     * @return \Cassandra\Cluster
124
     */
125
    protected function createCluster(array $config, array $options)
126
    {
127
        $cluster = Cassandra::cluster();
128
129
        // Check if the credentials are not already set in the options
130 View Code Duplication
        if (!isset($options['username']) && !empty($config['username'])) {
131
            $options['username'] = $config['username'];
132
        }
133 View Code Duplication
        if (!isset($options['password']) && !empty($config['password'])) {
134
            $options['password'] = $config['password'];
135
        }
136
137
        // Authentication
138
        if (isset($options['username']) && isset($options['password'])) {
139
            $cluster->withCredentials($options['username'], $options['password']);
140
        }
141
142
        // Contact Points/Host
143
        if (isset($options['contactpoints']) || (isset($config['host']) && !empty($config['host']))) {
144
            $contactPoints = $config['host'];
145
146
            if (isset($options['contactpoints'])) {
147
                $contactPoints = $options['contactpoints'];
148
            }
149
150
            if (is_array($contactPoints)) {
151
                $contactPoints = implode(',', $contactPoints);
152
            }
153
154
            $contactPoints = !empty($contactPoints) ? $contactPoints : '127.0.0.1';
155
156
            $cluster->withContactPoints($contactPoints);
157
        }
158
159
        if (!isset($options['port']) && !empty($config['port'])) {
160
            $cluster->withPort((int) $config['port']);
161
        }
162
163
        if (array_key_exists('page_size', $config) && !empty($config['page_size'])) {
164
            $cluster->withDefaultPageSize(intval($config['page_size'] ?? self::DEFAULT_PAGE_SIZE));
165
        }
166
167
        if (array_key_exists('consistency', $config) && in_array(strtoupper($config['consistency']), [
168
                Cassandra::CONSISTENCY_ANY, Cassandra::CONSISTENCY_ONE, Cassandra::CONSISTENCY_TWO,
169
                Cassandra::CONSISTENCY_THREE, Cassandra::CONSISTENCY_QUORUM, Cassandra::CONSISTENCY_ALL,
170
                Cassandra::CONSISTENCY_SERIAL, Cassandra::CONSISTENCY_QUORUM, Cassandra::CONSISTENCY_LOCAL_QUORUM,
171
                Cassandra::CONSISTENCY_EACH_QUORUM, Cassandra::CONSISTENCY_LOCAL_SERIAL, Cassandra::CONSISTENCY_LOCAL_ONE,
172
            ])) {
173
            $cluster->withDefaultConsistency($config['consistency']);
174
        }
175
176
        if (array_key_exists('timeout', $config) && !empty($config['timeout'])) {
177
            $cluster->withDefaultTimeout(intval($config['timeout']));
178
        }
179
180
        if (array_key_exists('connect_timeout', $config) && !empty($config['connect_timeout'])) {
181
            $cluster->withConnectTimeout(floatval($config['connect_timeout']));
182
        }
183
184
        if (array_key_exists('request_timeout', $config) && !empty($config['request_timeout'])) {
185
            $cluster->withRequestTimeout(floatval($config['request_timeout']));
186
        }
187
188
        return $cluster->build();
189
    }
190
191
    /**
192
     * Disconnect from the underlying Cassandra connection.
193
     */
194
    public function disconnect()
195
    {
196
        unset($this->connection);
197
    }
198
199
    /**
200
     * Get the PDO driver name.
201
     *
202
     * @return string
203
     */
204
    public function getDriverName()
205
    {
206
        return 'cassandra';
207
    }
208
209
    /**
210
     * Run a select statement against the database.
211
     *
212
     * @param  string  $query
213
     * @param  array  $bindings
214
     * @param  bool  $useReadPdo
215
     * @param  array  $customOptions
216
     *
217
     * @return array
218
     */
219
    public function select($query, $bindings = [], $useReadPdo = true, array $customOptions = [])
220
    {
221
        return $this->runStatement($query, $bindings, $customOptions);
222
    }
223
224
    /**
225
     * Run an bulk insert statement against the database.
226
     *
227
     * @param  array  $queries
228
     * @param  array  $bindings
229
     * @param  int  $type
230
     * @param  array  $customOptions
231
     *
232
     * @return bool
233
     */
234
    public function insertBulk($queries = [], $bindings = [], $type = Cassandra::BATCH_LOGGED, array $customOptions = [])
235
    {
236
        return $this->batchStatement($queries, $bindings, $type, $customOptions);
237
    }
238
239
    /**
240
     * Execute a group of queries inside a batch statement against the database.
241
     *
242
     * @param  array  $queries
243
     * @param  array  $bindings
244
     * @param  int  $type
245
     * @param  array  $customOptions
246
     *
247
     * @return bool
248
     */
249
    public function batchStatement($queries = [], $bindings = [], $type = Cassandra::BATCH_LOGGED, array $customOptions = [])
250
    {
251
        return $this->run($queries, $bindings, function ($queries, $bindings) use ($type, $customOptions) {
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...
252
            if ($this->pretending()) {
253
                return [];
254
            }
255
256
            $batch = new BatchStatement($type);
257
258
            foreach ($queries as $k => $query) {
259
                $preparedStatement = $this->session->prepare($query);
260
                $batch->add($preparedStatement, $bindings[$k]);
261
            }
262
263
            return $this->session->execute($batch, $customOptions);
264
        });
265
    }
266
267
    /**
268
     * Execute an CQL statement and return the boolean result.
269
     *
270
     * @param  string  $query
271
     * @param  array   $bindings
272
     * @param  array  $customOptions
273
     *
274
     * @return bool
275
     */
276
    public function statement($query, $bindings = [], array $customOptions = [])
277
    {
278
        return $this->runStatement($query, $bindings, $customOptions);
279
    }
280
281
    /**
282
     * Because Cassandra is an eventually consistent database, it's not possible to obtain
283
     * the affected count for statements so we're just going to return 0, based on the idea
284
     * that if the query fails somehow, an exception will be thrown
285
     *
286
     * @param  string  $query
287
     * @param  array   $bindings
288
     * @param  array  $customOptions
289
     *
290
     * @return int
291
     */
292
    public function affectingStatement($query, $bindings = [], array $customOptions = [])
293
    {
294
        return $this->runStatement($query, $bindings, $customOptions, 0, 1);
0 ignored issues
show
Documentation introduced by
0 is of type integer, but the function expects a array.

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...
295
    }
296
297
    /**
298
     * @inheritdoc
299
     */
300
    protected function getDefaultPostProcessor()
301
    {
302
        return new Query\Processor();
303
    }
304
305
    /**
306
     * @inheritdoc
307
     */
308
    protected function getDefaultQueryGrammar()
309
    {
310
        return new Query\Grammar();
311
    }
312
313
    /**
314
     * @inheritdoc
315
     */
316
    protected function getDefaultSchemaGrammar()
317
    {
318
        //return new Schema\Grammar();
319
    }
320
321
    /**
322
     * Reconnect to the database if connection is missing.
323
     *
324
     * @return void
325
     */
326
    protected function reconnectIfMissingConnection()
327
    {
328
        if (is_null($this->session)) {
329
            $this->session = $this->createCluster($this->config, [])->connect($this->keyspace);
330
        }
331
    }
332
333
    /**
334
     * Dynamically pass methods to the connection.
335
     *
336
     * @param  string  $method
337
     * @param  array   $parameters
338
     * @return mixed
339
     */
340
    public function __call($method, $parameters)
341
    {
342
        return call_user_func_array([$this->cluster, $method], $parameters);
343
    }
344
345
    /**
346
     * Execute an CQL statement and return the boolean result.
347
     *
348
     * @param $query
349
     * @param array $bindings
350
     * @param array $customOptions
351
     * @param array $defaultFailed
352
     * @param null $defaultSuccess
353
     *
354
     * @return mixed
355
     */
356
    protected function runStatement($query, $bindings = [], array $customOptions = [], $defaultFailed = [], $defaultSuccess = null)
357
    {
358
        return $this->run($query, $bindings, function ($query, $bindings) use ($defaultFailed, $customOptions, $defaultFailed, $defaultSuccess) {
359
            if ($this->pretending()) {
360
                return $defaultFailed;
361
            }
362
363
            $preparedStatement = $this->session->prepare($query);
364
365
            //Add bindings
366
            $customOptions['arguments'] = $bindings;
367
368
            $result = $this->session->execute($preparedStatement, $customOptions);
369
370
            return $defaultSuccess === null ? $result : $defaultSuccess;
371
        });
372
    }
373
}
374