Passed
Pull Request — master (#129)
by
unknown
03:53
created

Client::insertBatchFiles()   B

Complexity

Conditions 11
Paths 24

Size

Total Lines 41
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 12.6332

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 11
eloc 21
c 2
b 1
f 0
nc 24
nop 4
dl 0
loc 41
ccs 16
cts 21
cp 0.7619
crap 12.6332
rs 7.3166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace ClickHouseDB;
6
7
use ClickHouseDB\Exception\QueryException;
8
use ClickHouseDB\Query\Degeneration;
9
use ClickHouseDB\Query\Degeneration\Bindings;
10
use ClickHouseDB\Query\Degeneration\Conditions;
11
use ClickHouseDB\Query\WhereInFile;
12
use ClickHouseDB\Query\WriteToFile;
13
use ClickHouseDB\Quote\FormatLine;
14
use ClickHouseDB\Transport\Http;
15
use ClickHouseDB\Transport\Stream;
16
use function array_flip;
0 ignored issues
show
introduced by
Type array_flip is not used in this file.
Loading history...
17
use function array_keys;
18
use function array_rand;
0 ignored issues
show
introduced by
Type array_rand is not used in this file.
Loading history...
19
use function array_values;
20
use function count;
21
use function date;
22
use function implode;
23
use function in_array;
24
use function is_array;
25
use function is_callable;
26
use function is_file;
27
use function is_readable;
28
use function is_string;
29
use function sprintf;
30
use function stripos;
31
use function strtotime;
32
use function trim;
33
34
/**
35
 * Class Client
36
 * @package ClickHouseDB
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
introduced by
Use of annotation @package is forbidden.
Loading history...
37
 */
38
class Client
39
{
40
    const SUPPORTED_FORMATS = ['TabSeparated', 'TabSeparatedWithNames', 'CSV', 'CSVWithNames', 'JSONEachRow'];
0 ignored issues
show
introduced by
Constant \ClickHouseDB\Client::SUPPORTED_FORMATS visibility missing.
Loading history...
41
42
    /** @var Http */
43
    private $transport;
44
45
    /** @var string */
46
    private $connectUsername;
47
48
    /** @var string */
49
    private $connectPassword;
50
51
    /** @var string */
52
    private $connectHost;
53
54
    /** @var string */
55
    private $connectPort;
56
57
    /** @var bool */
58
    private $connectUserReadonly = false;
59
60
    /**
61
     * @param mixed[] $connectParams
62
     * @param mixed[] $settings
63
     */
64 67
    public function __construct(array $connectParams, array $settings = [])
65
    {
66 67
        if (!isset($connectParams['username'])) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
67
            throw  new \InvalidArgumentException('not set username');
0 ignored issues
show
introduced by
Class \InvalidArgumentException should not be referenced via a fully qualified name, but via a use statement.
Loading history...
68
        }
69
70 67
        if (!isset($connectParams['password'])) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
71
            throw  new \InvalidArgumentException('not set password');
0 ignored issues
show
introduced by
Class \InvalidArgumentException should not be referenced via a fully qualified name, but via a use statement.
Loading history...
72
        }
73
74 67
        if (!isset($connectParams['port'])) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
75
            throw  new \InvalidArgumentException('not set port');
0 ignored issues
show
introduced by
Class \InvalidArgumentException should not be referenced via a fully qualified name, but via a use statement.
Loading history...
76
        }
77
78 67
        if (!isset($connectParams['host'])) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
79
            throw  new \InvalidArgumentException('not set host');
0 ignored issues
show
introduced by
Class \InvalidArgumentException should not be referenced via a fully qualified name, but via a use statement.
Loading history...
80
        }
81
82 67
        $this->connectUsername = $connectParams['username'];
83 67
        $this->connectPassword = $connectParams['password'];
84 67
        $this->connectPort = $connectParams['port'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
85 67
        $this->connectHost = $connectParams['host'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
86
87
        // init transport class
88 67
        $this->transport = new Http(
89 67
            $this->connectHost,
90 67
            $this->connectPort,
91 67
            $this->connectUsername,
92 67
            $this->connectPassword
93
        );
94
95 67
        $this->transport->addQueryDegeneration(new Bindings());
96
97
        // apply settings to transport class
98 67
        $this->settings()->database('default');
99 67
        if (!empty($settings)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
100 1
            $this->settings()->apply($settings);
101
        }
102
103 67
        if (isset($connectParams['readonly'])) {
104
            $this->setReadOnlyUser($connectParams['readonly']);
105
        }
106
107 67
        if (isset($connectParams['https'])) {
108
            $this->https($connectParams['https']);
109
        }
110
111 67
        if (isset($connectParams['sslCA'])) {
112
            $this->transport->setSslCA($connectParams['sslCA']);
113
        }
114
115 67
        $this->enableHttpCompression();
116 67
    }
117
118
    /**
119
     * if the user has only read in the config file
120
     */
121
    public function setReadOnlyUser(bool $flag)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::setReadOnlyUser() does not have void return type hint.
Loading history...
122
    {
123
        $this->connectUserReadonly = $flag;
124
        $this->settings()->setReadOnlyUser($this->connectUserReadonly);
125
    }
126
127
    /**
128
     * Clear Degeneration processing request [template ]
129
     *
130
     * @return bool
131
     */
132 1
    public function cleanQueryDegeneration()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::cleanQueryDegeneration() does not have return type hint for its return value but it should be possible to add it based on @return annotation "bool".
Loading history...
133
    {
134 1
        return $this->transport->cleanQueryDegeneration();
135
    }
136
137
    /**
138
     * add Degeneration processing
139
     *
140
     * @return bool
141
     */
142
    public function addQueryDegeneration(Degeneration $degeneration)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::addQueryDegeneration() does not have return type hint for its return value but it should be possible to add it based on @return annotation "bool".
Loading history...
143
    {
144
        return $this->transport->addQueryDegeneration($degeneration);
145
    }
146
147
    /**
148
     * add Conditions in query
149
     *
150
     * @return bool
151
     */
152 3
    public function enableQueryConditions()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::enableQueryConditions() does not have return type hint for its return value but it should be possible to add it based on @return annotation "bool".
Loading history...
153
    {
154 3
        return $this->transport->addQueryDegeneration(new Conditions());
155
    }
156
157
    /**
158
     * Set connection host
159
     *
160
     * @param string $host
161
     */
162
    public function setHost($host)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::setHost() does not have parameter type hint for its parameter $host but it should be possible to add it based on @param annotation "string".
Loading history...
introduced by
Method \ClickHouseDB\Client::setHost() does not have void return type hint.
Loading history...
163
    {
164
        $this->connectHost = $host;
165
        $this->transport()->setHost($host);
166
    }
167
168
    /**
169
     * @return Settings
170
     */
171 2
    public function setTimeout(float $timeout)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::setTimeout() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Settings".
Loading history...
172
    {
173 2
        return $this->settings()->max_execution_time($timeout);
174
    }
175
176
    /**
177
     * @return mixed
178
     */
179 1
    public function getTimeout()
180
    {
181 1
        return $this->settings()->getTimeOut();
182
    }
183
184
    /**
185
     * ConnectTimeOut in seconds ( support 1.5 = 1500ms )
186
     */
187 2
    public function setConnectTimeOut(int $connectTimeOut)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::setConnectTimeOut() does not have void return type hint.
Loading history...
188
    {
189 2
        $this->transport()->setConnectTimeOut($connectTimeOut);
190 2
    }
191
192
    /**
193
     * @return int
194
     */
195 1
    public function getConnectTimeOut()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getConnectTimeOut() does not have return type hint for its return value but it should be possible to add it based on @return annotation "int".
Loading history...
196
    {
197 1
        return $this->transport()->getConnectTimeOut();
198
    }
199
200
    /**
201
     * @return Http
202
     */
203 67
    public function transport()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::transport() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Http".
Loading history...
204
    {
205 67
        if (!$this->transport) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
206
            throw  new \InvalidArgumentException('Empty transport class');
0 ignored issues
show
introduced by
Class \InvalidArgumentException should not be referenced via a fully qualified name, but via a use statement.
Loading history...
207
        }
208
209 67
        return $this->transport;
210
    }
211
212
    /**
213
     * @return string
214
     */
215
    public function getConnectHost()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getConnectHost() does not have return type hint for its return value but it should be possible to add it based on @return annotation "string".
Loading history...
216
    {
217
        return $this->connectHost;
218
    }
219
220
    /**
221
     * @return string
222
     */
223
    public function getConnectPassword()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getConnectPassword() does not have return type hint for its return value but it should be possible to add it based on @return annotation "string".
Loading history...
224
    {
225
        return $this->connectPassword;
226
    }
227
228
    /**
229
     * @return string
230
     */
231
    public function getConnectPort()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getConnectPort() does not have return type hint for its return value but it should be possible to add it based on @return annotation "string".
Loading history...
232
    {
233
        return $this->connectPort;
234
    }
235
236
    /**
237
     * @return string
238
     */
239
    public function getConnectUsername()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getConnectUsername() does not have return type hint for its return value but it should be possible to add it based on @return annotation "string".
Loading history...
240
    {
241
        return $this->connectUsername;
242
    }
243
244
    /**
245
     * @return Http
246
     */
247
    public function getTransport()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getTransport() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Http".
Loading history...
248
    {
249
        return $this->transport;
250
    }
251
252
    /**
253
     * @return mixed
254
     */
255
    public function verbose()
256
    {
257
        return $this->transport()->verbose(true);
258
    }
259
260
    /**
261
     * @return Settings
262
     */
263 67
    public function settings()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::settings() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Settings".
Loading history...
264
    {
265 67
        return $this->transport()->settings();
266
    }
267
268
    /**
269
     * @param string|null $useSessionId
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
introduced by
Method \ClickHouseDB\Client::useSession() has useless @param annotation for parameter $useSessionId.
Loading history...
270
     * @return $this
271
     */
272 2
    public function useSession(string $useSessionId = null)
0 ignored issues
show
introduced by
Parameter $useSessionId has null default value, but is not marked as nullable.
Loading history...
273
    {
274 2
        if (!$this->settings()->getSessionId()) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
275 2
            if (!$useSessionId) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
276 2
                $this->settings()->makeSessionId();
277
            } else {
278
                $this->settings()->session_id($useSessionId);
279
            }
280
        }
281 2
        return $this;
282
    }
283
284
    /**
285
     * @return mixed
286
     */
287 2
    public function getSession()
288
    {
289 2
        return $this->settings()->getSessionId();
290
    }
291
292
    /**
293
     * Query CREATE/DROP
294
     *
295
     * @param mixed[] $bindings
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
296
     * @return Statement
297
     */
298 26
    public function write(string $sql, array $bindings = [], bool $exception = true)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::write() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
299
    {
300 26
        return $this->transport()->write($sql, $bindings, $exception);
301
    }
302
303
    /**
304
     * set db name
305
     * @return static
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
306
     */
307 67
    public function database(string $db)
308
    {
309 67
        $this->settings()->database($db);
310
311 67
        return $this;
312
    }
313
314
    /**
315
     * Write to system.query_log
316
     *
317
     * @return static
318
     */
319
    public function enableLogQueries(bool $flag = true)
320
    {
321
        $this->settings()->set('log_queries', (int)$flag);
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after cast statement; 0 found
Loading history...
322
323
        return $this;
324
    }
325
326
    /**
327
     * Compress the result if the HTTP client said that it understands data compressed with gzip or deflate
328
     *
329
     * @return static
330
     */
331 67
    public function enableHttpCompression(bool $flag = true)
332
    {
333 67
        $this->settings()->enableHttpCompression($flag);
334
335 67
        return $this;
336
    }
337
338
    /**
339
     * Enable / Disable HTTPS
340
     *
341
     * @return static
342
     */
343 1
    public function https(bool $flag = true)
344
    {
345 1
        $this->settings()->https($flag);
346
347 1
        return $this;
348
    }
349
350
    /**
351
     * Read extremes of the result columns. They can be output in JSON-formats.
352
     *
353
     * @return static
354
     */
355 2
    public function enableExtremes(bool $flag = true)
356
    {
357 2
        $this->settings()->set('extremes', (int)$flag);
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after cast statement; 0 found
Loading history...
358
359 2
        return $this;
360
    }
361
362
    /**
363
     * @param mixed[] $bindings
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
364
     * @return Statement
365
     */
366 31
    public function select(
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::select() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
367
        string $sql,
368
        array $bindings = [],
369
        WhereInFile $whereInFile = null,
0 ignored issues
show
introduced by
Parameter $whereInFile has null default value, but is not marked as nullable.
Loading history...
370
        WriteToFile $writeToFile = null
0 ignored issues
show
introduced by
Parameter $writeToFile has null default value, but is not marked as nullable.
Loading history...
371
    )
372
    {
0 ignored issues
show
Coding Style introduced by
The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
Loading history...
373 31
        return $this->transport()->select($sql, $bindings, $whereInFile, $writeToFile);
374
    }
375
376
    /**
377
     * @return bool
378
     */
379 10
    public function executeAsync()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::executeAsync() does not have return type hint for its return value but it should be possible to add it based on @return annotation "bool".
Loading history...
380
    {
381 10
        return $this->transport()->executeAsync();
382
    }
383
384
    public function maxTimeExecutionAllAsync()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::maxTimeExecutionAllAsync() does not have void return type hint.
Loading history...
385
    {
386
387
    }
0 ignored issues
show
Coding Style introduced by
Function closing brace must go on the next line following the body; found 1 blank lines before brace
Loading history...
388
389
    /**
390
     * set progressFunction
391
     */
392 1
    public function progressFunction(callable $callback)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::progressFunction() does not have void return type hint.
Loading history...
393
    {
394 1
        if (!is_callable($callback)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
395
            throw new \InvalidArgumentException('Not is_callable progressFunction');
0 ignored issues
show
introduced by
Class \InvalidArgumentException should not be referenced via a fully qualified name, but via a use statement.
Loading history...
396
        }
397
398 1
        if (!$this->settings()->is('send_progress_in_http_headers')) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
399 1
            $this->settings()->set('send_progress_in_http_headers', 1);
400
        }
401 1
        if (!$this->settings()->is('http_headers_progress_interval_ms')) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
402 1
            $this->settings()->set('http_headers_progress_interval_ms', 100);
403
        }
404
405 1
        $this->transport()->setProgressFunction($callback);
406 1
    }
407
408
    /**
409
     * prepare select
410
     *
411
     * @param mixed[] $bindings
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
412
     * @return Statement
413
     */
414 7
    public function selectAsync(
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::selectAsync() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
415
        string $sql,
416
        array $bindings = [],
417
        WhereInFile $whereInFile = null,
0 ignored issues
show
introduced by
Parameter $whereInFile has null default value, but is not marked as nullable.
Loading history...
418
        WriteToFile $writeToFile = null
0 ignored issues
show
introduced by
Parameter $writeToFile has null default value, but is not marked as nullable.
Loading history...
419
    )
420
    {
0 ignored issues
show
Coding Style introduced by
The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
Loading history...
421 7
        return $this->transport()->selectAsync($sql, $bindings, $whereInFile, $writeToFile);
422
    }
423
424
    /**
425
     * SHOW PROCESSLIST
426
     *
427
     * @return array
0 ignored issues
show
introduced by
@return annotation of method \ClickHouseDB\Client::showProcesslist() does not specify type hint for items of its traversable return value.
Loading history...
428
     */
429
    public function showProcesslist()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::showProcesslist() does not have return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
430
    {
431
        return $this->select('SHOW PROCESSLIST')->rows();
432
    }
433
434
    /**
435
     * show databases
436
     *
437
     * @return array
0 ignored issues
show
introduced by
@return annotation of method \ClickHouseDB\Client::showDatabases() does not specify type hint for items of its traversable return value.
Loading history...
438
     */
439
    public function showDatabases()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::showDatabases() does not have return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
440
    {
441
        return $this->select('show databases')->rows();
442
    }
443
444
    /**
445
     * statement = SHOW CREATE TABLE
446
     *
447
     * @return mixed
448
     */
449
    public function showCreateTable(string $table)
450
    {
451
        return $this->select('SHOW CREATE TABLE ' . $table)->fetchOne('statement');
452
    }
453
454
    /**
455
     * SHOW TABLES
456
     *
457
     * @return mixed[]
458
     */
459 1
    public function showTables()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::showTables() does not have return type hint for its return value but it should be possible to add it based on @return annotation "mixed[]".
Loading history...
460
    {
461 1
        return $this->select('SHOW TABLES')->rowsAsTree('name');
462
    }
463
464
    /**
465
     * Get the number of simultaneous/Pending requests
466
     *
467
     * @return int
468
     */
469 12
    public function getCountPendingQueue()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getCountPendingQueue() does not have return type hint for its return value but it should be possible to add it based on @return annotation "int".
Loading history...
470
    {
471 12
        return $this->transport()->getCountPendingQueue();
472
    }
473
474
    /**
475
     * @param mixed[][] $values
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
476
     * @param string[] $columns
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
477
     * @return Statement
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::insert() has useless @return annotation.
Loading history...
478
     * @throws Exception\TransportException
479
     */
480 9
    public function insert(string $table, array $values, array $columns = []): Statement
0 ignored issues
show
introduced by
There must be exactly 1 whitespace between closing parenthesis and return type colon.
Loading history...
481
    {
482 9
        if (empty($values)) {
483 1
            throw QueryException::cannotInsertEmptyValues();
484
        }
485
486 8
        if (stripos($table, '`') === false && stripos($table, '.') === false) {
487 5
            $table = '`' . $table . '`'; //quote table name for dot names
488
        }
489 8
        $sql = 'INSERT INTO ' . $table;
490
491 8
        if (count($columns) !== 0) {
492 7
            $sql .= ' (`' . implode('`,`', $columns) . '`) ';
493
        }
494
495 8
        $sql .= ' VALUES ';
496
497 8
        foreach ($values as $row) {
498 8
            $sql .= ' (' . FormatLine::Insert($row) . '), ';
499
        }
500 8
        $sql = trim($sql, ', ');
501
502 8
        return $this->transport()->write($sql);
503
    }
504
505
    /**
506
     *       * Prepares the values to insert from the associative array.
507
     *       * There may be one or more lines inserted, but then the keys inside the array list must match (including in the sequence)
508
     *       *
509
     *       * @param mixed[] $values - array column_name => value (if we insert one row) or array list column_name => value if we insert many lines
510
     *       * @return mixed[][] - list of arrays - 0 => fields, 1 => list of value arrays for insertion
511
     *       */
512 3
    public function prepareInsertAssocBulk(array $values)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::prepareInsertAssocBulk() does not have @param annotation for its traversable parameter $values.
Loading history...
introduced by
Method \ClickHouseDB\Client::prepareInsertAssocBulk() does not have return type hint nor @return annotation for its return value.
Loading history...
513
    {
514 3
        if (isset($values[0]) && is_array($values[0])) { //случай, когда много строк вставляется
515 2
            $preparedFields = array_keys($values[0]);
516 2
            $preparedValues = [];
517 2
            foreach ($values as $idx => $row) {
518 2
                $_fields = array_keys($row);
519 2
                if ($_fields !== $preparedFields) {
520 1
                    throw new QueryException(
521 1
                        sprintf(
522 1
                            'Fields not match: %s and %s on element %s',
523 1
                            implode(',', $_fields),
524 1
                            implode(',', $preparedFields),
525 1
                            $idx
526
                        )
527
                    );
528
                }
529 2
                $preparedValues[] = array_values($row);
530
            }
531
        } else {
532 1
            $preparedFields = array_keys($values);
533 1
            $preparedValues = [array_values($values)];
534
        }
535
536 2
        return [$preparedFields, $preparedValues];
537
    }
538
539
    /**
540
     * Inserts one or more rows from an associative array.
541
     * If there is a discrepancy between the keys of the value arrays (or their order) - throws an exception.
542
     *
543
     * @param mixed[] $values - array column_name => value (if we insert one row) or array list column_name => value if we insert many lines
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
544
     * @return Statement
545
     */
546
    public function insertAssocBulk(string $tableName, array $values)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::insertAssocBulk() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
547
    {
548
        list($columns, $vals) = $this->prepareInsertAssocBulk($values);
0 ignored issues
show
introduced by
list(...) is forbidden, use [...] instead.
Loading history...
549
550
        return $this->insert($tableName, $vals, $columns);
551
    }
552
553
    /**
554
     * insert TabSeparated files
555
     *
556
     * @param string|string[] $fileNames
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
557
     * @param string[] $columns
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
558
     * @return mixed
559
     */
560 1
    public function insertBatchTSVFiles(string $tableName, $fileNames, array $columns = [])
561
    {
562 1
        return $this->insertBatchFiles($tableName, $fileNames, $columns, 'TabSeparated');
563
    }
564
565
    /**
566
     * insert Batch Files
567
     *
568
     * @param string|string[] $fileNames
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
569
     * @param string[] $columns
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
570
     * @param string $format ['TabSeparated','TabSeparatedWithNames','CSV','CSVWithNames']
0 ignored issues
show
Coding Style introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
571
     * @return Statement[]
572
     * @throws Exception\TransportException
573
     */
574 8
    public function insertBatchFiles(string $tableName, $fileNames, array $columns = [], string $format = 'CSV')
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::insertBatchFiles() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement[]".
Loading history...
575
    {
576 8
        if (is_string($fileNames)) {
577
            $fileNames = [$fileNames];
578
        }
579 8
        if ($this->getCountPendingQueue() > 0) {
580
            throw new QueryException('Queue must be empty, before insertBatch, need executeAsync');
581
        }
582
583 8
        if (!in_array($format, self::SUPPORTED_FORMATS, true)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
584
            throw new QueryException('Format not support in insertBatchFiles');
585
        }
586
587 8
        $result = [];
588
589 8
        foreach ($fileNames as $fileName) {
590 8
            if (!is_file($fileName) || !is_readable($fileName)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
591
                throw  new QueryException('Cant read file: ' . $fileName . ' ' . (is_file($fileName) ? '' : ' is not file'));
592
            }
593
594 8
            if (empty($columns)) {
595
                $sql = 'INSERT INTO ' . $tableName . ' FORMAT ' . $format;
596
            } else {
597 8
                $sql = 'INSERT INTO ' . $tableName . ' ( ' . implode(',', $columns) . ' ) FORMAT ' . $format;
598
            }
599 8
            $result[$fileName] = $this->transport()->writeAsyncCSV($sql, $fileName);
600
        }
601
602
        // exec
603 8
        $this->executeAsync();
604
605
        // fetch resutl
606 8
        foreach ($fileNames as $fileName) {
607 8
            if (!$result[$fileName]->isError()) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
608 6
                continue;
609
            }
610
611 2
            $result[$fileName]->error();
612
        }
613
614 6
        return $result;
615
    }
616
617
    /**
618
     * insert Batch Stream
619
     *
620
     * @param string[] $columns
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
621
     * @param string $format ['TabSeparated','TabSeparatedWithNames','CSV','CSVWithNames']
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
622
     * @return Transport\CurlerRequest
623
     */
624 2
    public function insertBatchStream(string $tableName, array $columns = [], string $format = 'CSV')
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::insertBatchStream() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Transport\CurlerRequest".
Loading history...
625
    {
626 2
        if ($this->getCountPendingQueue() > 0) {
627
            throw new QueryException('Queue must be empty, before insertBatch, need executeAsync');
628
        }
629
630 2
        if (!in_array($format, self::SUPPORTED_FORMATS, true)) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
631
            throw new QueryException('Format not support in insertBatchFiles');
632
        }
633
634 2
        if (empty($columns)) {
635
            $sql = 'INSERT INTO ' . $tableName . ' FORMAT ' . $format;
636
        } else {
637 2
            $sql = 'INSERT INTO ' . $tableName . ' ( ' . implode(',', $columns) . ' ) FORMAT ' . $format;
638
        }
639
640 2
        return $this->transport()->writeStreamData($sql);
641
    }
642
643
    /**
644
     * stream Write
645
     *
646
     * @param string[] $bind
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
647
     * @return Statement
648
     * @throws Exception\TransportException
649
     */
650 1
    public function streamWrite(Stream $stream, string $sql, array $bind = [])
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::streamWrite() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
651
    {
652 1
        if ($this->getCountPendingQueue() > 0) {
653
            throw new QueryException('Queue must be empty, before streamWrite');
654
        }
655
656 1
        return $this->transport()->streamWrite($stream, $sql, $bind);
657
    }
658
659
    /**
660
     * stream Read
661
     *
662
     * @param string[] $bind
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
663
     * @return Statement
664
     */
665 1
    public function streamRead(Stream $streamRead, string $sql, array $bind = [])
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::streamRead() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
666
    {
667 1
        if ($this->getCountPendingQueue() > 0) {
668
            throw new QueryException('Queue must be empty, before streamWrite');
669
        }
670
671 1
        return $this->transport()->streamRead($streamRead, $sql, $bind);
672
    }
673
674
    /**
675
     * Size of database
676
     *
677
     * @return mixed|null
678
     */
679
    public function databaseSize()
680
    {
681
        $b = $this->settings()->getDatabase();
682
683
        return $this->select(
684
            '
685
            SELECT database,formatReadableSize(sum(bytes)) as size
686
            FROM system.parts
687
            WHERE active AND database=:database
688
            GROUP BY database
689
            ',
690
            ['database' => $b]
691
        )->fetchOne();
692
    }
693
694
    /**
695
     * Size of tables
696
     *
697
     * @return mixed
698
     */
699 1
    public function tableSize(string $tableName)
700
    {
701 1
        $tables = $this->tablesSize();
702
703 1
        if (isset($tables[$tableName])) {
704 1
            return $tables[$tableName];
705
        }
706
707
        return null;
708
    }
709
710
    /**
711
     * Ping server
712
     *
713
     * @return bool
714
     */
715 37
    public function ping()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::ping() does not have return type hint for its return value but it should be possible to add it based on @return annotation "bool".
Loading history...
716
    {
717 37
        return $this->transport()->ping();
718
    }
719
720
    /**
721
     * Tables sizes
722
     *
723
     * @param bool $flatList
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
724
     * @return mixed[][]
725
     */
726 1
    public function tablesSize($flatList = false)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::tablesSize() does not have parameter type hint for its parameter $flatList but it should be possible to add it based on @param annotation "bool".
Loading history...
introduced by
Method \ClickHouseDB\Client::tablesSize() does not have return type hint for its return value but it should be possible to add it based on @return annotation "mixed[][]".
Loading history...
727
    {
728 1
        $result = $this->select('
729
        SELECT name as table,database,
730
            max(sizebytes) as sizebytes,
731
            max(size) as size,
732
            min(min_date) as min_date,
733
            max(max_date) as max_date
734
            FROM system.tables
735
            ANY LEFT JOIN 
736
            (
737
            SELECT table,database,
738
                        formatReadableSize(sum(bytes)) as size,
739
                        sum(bytes) as sizebytes,
740
                        min(min_date) as min_date,
741
                        max(max_date) as max_date
742
                        FROM system.parts 
743
                        WHERE active AND database=:database
744
                        GROUP BY table,database
745
            ) USING ( table,database )
746
            WHERE database=:database
747
            GROUP BY table,database
748
        ',
749 1
            ['database' => $this->settings()->getDatabase()]);
750
751 1
        if ($flatList) {
752
            return $result->rows();
753
        }
754
755 1
        return $result->rowsAsTree('table');
756
    }
757
758
    /**
759
     * isExists
760
     *
761
     * @return array
0 ignored issues
show
introduced by
@return annotation of method \ClickHouseDB\Client::isExists() does not specify type hint for items of its traversable return value.
Loading history...
762
     */
763
    public function isExists(string $database, string $table)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::isExists() does not have return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
764
    {
765
        return $this->select(
766
            '
767
            SELECT *
768
            FROM system.tables 
769
            WHERE name=\'' . $table . '\' AND database=\'' . $database . '\''
770
        )->rowsAsTree('name');
771
    }
772
773
    /**
774
     * List of partitions
775
     *
776
     * @return mixed[][]
777
     */
778
    public function partitions(string $table, int $limit = null, bool $active = null)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::partitions() does not have return type hint for its return value but it should be possible to add it based on @return annotation "mixed[][]".
Loading history...
introduced by
Parameter $limit has null default value, but is not marked as nullable.
Loading history...
introduced by
Parameter $active has null default value, but is not marked as nullable.
Loading history...
779
    {
780
        $database = $this->settings()->getDatabase();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
781
        $whereActiveClause = $active === null ? '' : sprintf(' AND active = %s', (int)$active);
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after cast statement; 0 found
Loading history...
782
        $limitClause = $limit !== null ? ' LIMIT ' . $limit : '';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
783
784
        return $this->select(<<<CLICKHOUSE
785
SELECT *
786
FROM system.parts 
787
WHERE like(table,'%$table%') AND database='$database'$whereActiveClause
788
ORDER BY max_date $limitClause
789
CLICKHOUSE
790
        )->rowsAsTree('name');
791
    }
792
793
    /**
794
     * dropPartition
795
     * @return Statement
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
introduced by
Incorrect annotations group.
Loading history...
796
     * @deprecated
797
     */
798
    public function dropPartition(string $dataBaseTableName, string $partition_id)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::dropPartition() does not have return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
799
    {
0 ignored issues
show
Coding Style introduced by
Expected 0 blank lines after opening function brace; 1 found
Loading history...
800
801
        $partition_id = trim($partition_id, '\'');
802
        $this->settings()->set('replication_alter_partitions_sync', 2);
803
        $state = $this->write('ALTER TABLE {dataBaseTableName} DROP PARTITION :partion_id',
0 ignored issues
show
introduced by
Useless variable $state.
Loading history...
804
            [
805
                'dataBaseTableName' => $dataBaseTableName,
806
                'partion_id' => $partition_id,
807
            ]);
808
809
        return $state;
810
    }
811
812
    /**
813
     * Truncate ( drop all partitions )
814
     * @return array
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
introduced by
Incorrect annotations group.
Loading history...
introduced by
@return annotation of method \ClickHouseDB\Client::truncateTable() does not specify type hint for items of its traversable return value.
Loading history...
815
     * @deprecated
816
     */
817
    public function truncateTable(string $tableName)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::truncateTable() does not have return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
818
    {
819
        $partions = $this->partitions($tableName);
820
        $out = [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
821
        foreach ($partions as $part_key => $part) {
822
            $part_id = $part['partition'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
823
            $out[$part_id] = $this->dropPartition($tableName, $part_id);
0 ignored issues
show
Deprecated Code introduced by
The function ClickHouseDB\Client::dropPartition() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

823
            $out[$part_id] = /** @scrutinizer ignore-deprecated */ $this->dropPartition($tableName, $part_id);
Loading history...
824
        }
825
826
        return $out;
827
    }
828
829
    /**
830
     * Returns the server's uptime in seconds.
831
     *
832
     * @return int
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
833
     * @throws Exception\TransportException
834
     */
835 1
    public function getServerUptime()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getServerUptime() does not have return type hint for its return value but it should be possible to add it based on @return annotation "int".
Loading history...
836
    {
837 1
        return $this->select('SELECT uptime() as uptime')->fetchOne('uptime');
838
    }
839
840
    /**
841
     * Returns string with the server version.
842
     */
843 1
    public function getServerVersion(): string
0 ignored issues
show
introduced by
There must be exactly 1 whitespace between closing parenthesis and return type colon.
Loading history...
844
    {
845 1
        return (string)$this->select('SELECT version() as version')->fetchOne('version');
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after cast statement; 0 found
Loading history...
846
    }
847
848
    /**
849
     * Read system.settings table
850
     *
851
     * @return mixed[][]
852
     */
853 1
    public function getServerSystemSettings(string $like = '')
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getServerSystemSettings() does not have return type hint for its return value but it should be possible to add it based on @return annotation "mixed[][]".
Loading history...
854
    {
855 1
        $l = [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
856 1
        $list = $this->select('SELECT * FROM system.settings' . ($like ? ' WHERE name LIKE :like' : ''),
857 1
            ['like' => '%' . $like . '%'])->rows();
858 1
        foreach ($list as $row) {
859 1
            if (isset($row['name'])) {
0 ignored issues
show
introduced by
Use early exit to reduce code nesting.
Loading history...
860 1
                $n = $row['name'];
861 1
                unset($row['name']);
862 1
                $l[$n] = $row;
863
            }
864
        }
865
866 1
        return $l;
867
    }
868
869
    /**
870
     * dropOldPartitions by day_ago
871
     * @return array
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
introduced by
Incorrect annotations group.
Loading history...
introduced by
@return annotation of method \ClickHouseDB\Client::dropOldPartitions() does not specify type hint for items of its traversable return value.
Loading history...
872
     * @throws Exception\TransportException
873
     * @throws \Exception
0 ignored issues
show
introduced by
Class \Exception should not be referenced via a fully qualified name, but via a use statement.
Loading history...
874
     * @deprecated
0 ignored issues
show
introduced by
Expected 0 lines after last content, found 1.
Loading history...
875
     *
876
     */
877
    public function dropOldPartitions(string $table_name, int $days_ago, int $count_partitons_per_one = 100)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::dropOldPartitions() does not have return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
878
    {
879
        $days_ago = strtotime(date('Y-m-d 00:00:00', strtotime('-' . $days_ago . ' day')));
880
881
        $drop = [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 11 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
882
        $list_patitions = $this->partitions($table_name, $count_partitons_per_one);
883
884
        foreach ($list_patitions as $partion_id => $partition) {
885
            if (stripos($partition['engine'], 'mergetree') === false) {
886
                continue;
887
            }
888
889
            // $min_date = strtotime($partition['min_date']);
890
            $max_date = strtotime($partition['max_date']);
891
892
            if ($max_date < $days_ago) {
0 ignored issues
show
introduced by
Use early exit to reduce code nesting.
Loading history...
893
                $drop[] = $partition['partition'];
894
            }
895
        }
896
897
        $result = [];
898
        foreach ($drop as $partition_id) {
899
            $result[$partition_id] = $this->dropPartition($table_name, $partition_id);
0 ignored issues
show
Deprecated Code introduced by
The function ClickHouseDB\Client::dropPartition() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

899
            $result[$partition_id] = /** @scrutinizer ignore-deprecated */ $this->dropPartition($table_name, $partition_id);
Loading history...
900
        }
901
902
        return $result;
903
    }
904
}
905