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

853
            $out[$part_id] = /** @scrutinizer ignore-deprecated */ $this->dropPartition($tableName, $part_id);
Loading history...
854
        }
855
856
        return $out;
857
    }
858
859
    /**
860
     * Returns the server's uptime in seconds.
861
     *
862
     * @return int
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
863
     * @throws Exception\TransportException
864
     * @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...
865
     */
866 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...
867
    {
868 1
        return $this->select('SELECT uptime() as uptime')->fetchOne('uptime');
869
    }
870
871
    /**
872
     * Returns string with the server version.
873
     */
874 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...
875
    {
876 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...
877
    }
878
879
    /**
880
     * Read system.settings table
881
     *
882
     * @return mixed[][]
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
883
     * @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...
884
     */
885 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...
886
    {
887 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...
888 1
        $list = $this->select('SELECT * FROM system.settings' . ($like ? ' WHERE name LIKE :like' : ''),
889 1
            ['like' => '%' . $like . '%'])->rows();
890 1
        foreach ($list as $row) {
891 1
            if (isset($row['name'])) {
0 ignored issues
show
introduced by
Use early exit to reduce code nesting.
Loading history...
892 1
                $n = $row['name'];
893 1
                unset($row['name']);
894 1
                $l[$n] = $row;
895
            }
896
        }
897
898 1
        return $l;
899
    }
900
901
}
0 ignored issues
show
introduced by
There must be exactly 0 empty lines before class closing brace.
Loading history...
902