Completed
Push — master ( 17aea5...9a3a1b )
by Igor
18:41 queued 16:39
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...
introduced by
Expected 1 lines between different types of use statement, found 0.
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
0 ignored issues
show
introduced by
Documentation comment contains forbidden comment "Class Client".
Loading history...
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 68
    public function __construct(array $connectParams, array $settings = [])
68
    {
69 68
        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 68
        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 68
        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 68
        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 68
        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...
introduced by
Expected 1 lines before "throw", found 0.
Loading history...
92
            }
93
94
            $this->authMethod = $connectParams['auth_method'];
95
        }
96
97 68
        $this->connectUsername = $connectParams['username'];
98 68
        $this->connectPassword = $connectParams['password'];
99 68
        $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 68
        $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 68
        $this->transport = new Http(
104 68
            $this->connectHost,
105 68
            $this->connectPort,
106 68
            $this->connectUsername,
107 68
            $this->connectPassword,
108 68
            $this->authMethod
109
        );
110
111 68
        $this->transport->addQueryDegeneration(new Bindings());
112
113
        // apply settings to transport class
114 68
        $this->settings()->database('default');
115 68
        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 68
        if (isset($connectParams['readonly'])) {
120
            $this->setReadOnlyUser($connectParams['readonly']);
121
        }
122
123 68
        if (isset($connectParams['https'])) {
124
            $this->https($connectParams['https']);
125
        }
126
127 68
        if (isset($connectParams['sslCA'])) {
128
            $this->transport->setSslCa($connectParams['sslCA']);
129
        }
130
131 68
        $this->enableHttpCompression();
132 68
    }
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 native 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 native 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 native 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 native 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 native 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 native 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 68
    public function transport()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::transport() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Http".
Loading history...
220
    {
221 68
        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 68
        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 native 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 native 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 native 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 native 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
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getAuthMethod() has useless @return annotation.
Loading history...
262
     */
263
    public function getAuthMethod(): int
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getAuthMethod() does not need documentation comment.
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 native 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 68
    public function settings()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::settings() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Settings".
Loading history...
288
    {
289 68
        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...
introduced by
Expected 1 lines after "if", found 0.
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;
0 ignored issues
show
introduced by
Expected 1 lines before "return", found 0.
Loading history...
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 27
    public function write(string $sql, array $bindings = [], bool $exception = true)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::write() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
323
    {
324 27
        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 68
    public function database(string $db)
332
    {
333 68
        $this->settings()->database($db);
334
335 68
        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 68
    public function enableHttpCompression(bool $flag = true)
356
    {
357 68
        $this->settings()->enableHttpCompression($flag);
358
359 68
        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 32
    public function select(
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::select() does not have native 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 32
        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 native 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 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...
417
    {
418 1
        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 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...
introduced by
Expected 1 lines after "if", found 0.
Loading history...
423 1
            $this->settings()->set('send_progress_in_http_headers', 1);
424
        }
425 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...
426 1
            $this->settings()->set('http_headers_progress_interval_ms', 100);
427
        }
428
429 1
        $this->transport()->setProgressFunction($callback);
430 1
    }
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 native 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 native 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 native 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 native 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 native 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
505
    {
506 10
        if (empty($values)) {
507 1
            throw QueryException::cannotInsertEmptyValues();
508
        }
509
510 9
        if (stripos($table, '`') === false && stripos($table, '.') === false) {
0 ignored issues
show
introduced by
Expected 1 lines after "if", found 0.
Loading history...
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) {
0 ignored issues
show
introduced by
Expected 1 lines after "foreach", found 0.
Loading history...
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) {
0 ignored issues
show
introduced by
Expected 1 lines after "if", found 0.
Loading history...
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 string $tableName - name table
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
568
     * @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
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
569
     * @return Statement
570
     */
571
    public function insertAssocBulk(string $tableName, array $values)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::insertAssocBulk() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
572
    {
573
        list($columns, $vals) = $this->prepareInsertAssocBulk($values);
0 ignored issues
show
introduced by
list(...) is forbidden, use [...] instead.
Loading history...
574
575
        return $this->insert($tableName, $vals, $columns);
576
    }
577
578
    /**
579
     * insert TabSeparated files
580
     *
581
     * @param string|string[] $fileNames
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
582
     * @param string[] $columns
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
583
     * @return mixed
584
     */
585 1
    public function insertBatchTSVFiles(string $tableName, $fileNames, array $columns = [])
586
    {
587 1
        return $this->insertBatchFiles($tableName, $fileNames, $columns, 'TabSeparated');
588
    }
589
590
    /**
591
     * insert Batch Files
592
     *
593
     * @param string|string[] $fileNames
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
594
     * @param string[] $columns
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
595
     * @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...
596
     * @return Statement[]
597
     * @throws Exception\TransportException
598
     */
599 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 native return type hint for its return value but it should be possible to add it based on @return annotation "Statement[]".
Loading history...
600
    {
601 8
        if (is_string($fileNames)) {
0 ignored issues
show
introduced by
Expected 1 lines after "if", found 0.
Loading history...
602
            $fileNames = [$fileNames];
603
        }
604 8
        if ($this->getCountPendingQueue() > 0) {
605
            throw new QueryException('Queue must be empty, before insertBatch, need executeAsync');
606
        }
607
608 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...
609
            throw new QueryException('Format not support in insertBatchFiles');
610
        }
611
612 8
        $result = [];
613
614 8
        foreach ($fileNames as $fileName) {
615 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...
616
                throw  new QueryException('Cant read file: ' . $fileName . ' ' . (is_file($fileName) ? '' : ' is not file'));
617
            }
618
619 8
            if (empty($columns)) {
0 ignored issues
show
introduced by
Expected 1 lines after "if", found 0.
Loading history...
620
                $sql = 'INSERT INTO ' . $tableName . ' FORMAT ' . $format;
621
            } else {
622 8
                $sql = 'INSERT INTO ' . $tableName . ' ( ' . implode(',', $columns) . ' ) FORMAT ' . $format;
623
            }
624 8
            $result[$fileName] = $this->transport()->writeAsyncCSV($sql, $fileName);
625
        }
626
627
        // exec
628 8
        $this->executeAsync();
629
630
        // fetch resutl
631 8
        foreach ($fileNames as $fileName) {
632 8
            if (!$result[$fileName]->isError()) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space(s) after NOT operator; 0 found
Loading history...
633 6
                continue;
634
            }
635
636 2
            $result[$fileName]->error();
637
        }
638
639 6
        return $result;
640
    }
641
642
    /**
643
     * insert Batch Stream
644
     *
645
     * @param string[] $columns
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
646
     * @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...
647
     * @return Transport\CurlerRequest
648
     */
649 2
    public function insertBatchStream(string $tableName, array $columns = [], string $format = 'CSV')
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::insertBatchStream() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Transport\CurlerRequest".
Loading history...
650
    {
651 2
        if ($this->getCountPendingQueue() > 0) {
652
            throw new QueryException('Queue must be empty, before insertBatch, need executeAsync');
653
        }
654
655 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...
656
            throw new QueryException('Format not support in insertBatchFiles');
657
        }
658
659 2
        if (empty($columns)) {
660
            $sql = 'INSERT INTO ' . $tableName . ' FORMAT ' . $format;
661
        } else {
662 2
            $sql = 'INSERT INTO ' . $tableName . ' ( ' . implode(',', $columns) . ' ) FORMAT ' . $format;
663
        }
664
665 2
        return $this->transport()->writeStreamData($sql);
666
    }
667
668
    /**
669
     * stream Write
670
     *
671
     * @param string[] $bind
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
672
     * @return Statement
673
     * @throws Exception\TransportException
674
     */
675 1
    public function streamWrite(Stream $stream, string $sql, array $bind = [])
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::streamWrite() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
676
    {
677 1
        if ($this->getCountPendingQueue() > 0) {
678
            throw new QueryException('Queue must be empty, before streamWrite');
679
        }
680
681 1
        return $this->transport()->streamWrite($stream, $sql, $bind);
682
    }
683
684
    /**
685
     * stream Read
686
     *
687
     * @param string[] $bind
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
688
     * @return Statement
689
     */
690 1
    public function streamRead(Stream $streamRead, string $sql, array $bind = [])
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::streamRead() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
691
    {
692 1
        if ($this->getCountPendingQueue() > 0) {
693
            throw new QueryException('Queue must be empty, before streamRead');
694
        }
695
696 1
        return $this->transport()->streamRead($streamRead, $sql, $bind);
697
    }
698
699
    /**
700
     * Size of database
701
     *
702
     * @return mixed|null
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
703
     * @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...
704
     */
705
    public function databaseSize()
706
    {
707
        $b = $this->settings()->getDatabase();
708
709
        return $this->select(
710
            '
711
            SELECT database,formatReadableSize(sum(bytes)) as size
712
            FROM system.parts
713
            WHERE active AND database=:database
714
            GROUP BY database
715
            ',
716
            ['database' => $b]
717
        )->fetchOne();
718
    }
719
720
    /**
721
     * Size of tables
722
     *
723
     * @return mixed
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
724
     * @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...
725
     */
726 1
    public function tableSize(string $tableName)
727
    {
728 1
        $tables = $this->tablesSize();
729
730 1
        if (isset($tables[$tableName])) {
731 1
            return $tables[$tableName];
732
        }
733
734
        return null;
735
    }
736
737
    /**
738
     * Ping server
739
     *
740
     * @return bool
741
     */
742 38
    public function ping()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::ping() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "bool".
Loading history...
743
    {
744 38
        return $this->transport()->ping();
745
    }
746
747
    /**
748
     * Tables sizes
749
     *
750
     * @param bool $flatList
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
751
     * @return mixed[][]
752
     * @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...
753
     */
754 1
    public function tablesSize($flatList = false)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::tablesSize() does not have native 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 native return type hint for its return value but it should be possible to add it based on @return annotation "mixed[][]".
Loading history...
755
    {
756 1
        $result = $this->select('
757
        SELECT name as table,database,
758
            max(sizebytes) as sizebytes,
759
            max(size) as size,
760
            min(min_date) as min_date,
761
            max(max_date) as max_date
762
            FROM system.tables
763
            ANY LEFT JOIN 
764
            (
765
            SELECT table,database,
766
                        formatReadableSize(sum(bytes)) as size,
767
                        sum(bytes) as sizebytes,
768
                        min(min_date) as min_date,
769
                        max(max_date) as max_date
770
                        FROM system.parts 
771
                        WHERE active AND database=:database
772
                        GROUP BY table,database
773
            ) as s USING ( table,database )
774
            WHERE database=:database
775
            GROUP BY table,database
776
        ',
777 1
            ['database' => $this->settings()->getDatabase()]);
778
779 1
        if ($flatList) {
780
            return $result->rows();
781
        }
782
783 1
        return $result->rowsAsTree('table');
784
    }
785
786
    /**
787
     * isExists
788
     *
789
     * @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...
790
     * @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...
791
     */
792
    public function isExists(string $database, string $table)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::isExists() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
793
    {
794
        return $this->select(
795
            '
796
            SELECT *
797
            FROM system.tables 
798
            WHERE name=\'' . $table . '\' AND database=\'' . $database . '\''
799
        )->rowsAsTree('name');
800
    }
801
802
    /**
803
     * List of partitions
804
     *
805
     * @return mixed[][]
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
806
     * @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...
807
     */
808
    public function partitions(string $table, int $limit = null, bool $active = null)
0 ignored issues
show
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...
introduced by
Method \ClickHouseDB\Client::partitions() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "mixed[][]".
Loading history...
809
    {
810
        $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...
811
        $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...
812
        $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...
813
814
        return $this->select(<<<CLICKHOUSE
815
SELECT *
816
FROM system.parts 
817
WHERE like(table,'%$table%') AND database='$database'$whereActiveClause
818
ORDER BY max_date $limitClause
819
CLICKHOUSE
820
        )->rowsAsTree('name');
821
    }
822
823
    /**
824
     * dropPartition
825
     * @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...
826
     * @deprecated
827
     */
828
    public function dropPartition(string $dataBaseTableName, string $partition_id)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::dropPartition() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "Statement".
Loading history...
Coding Style introduced by
The variable $partition_id should be in camel caps format.
Loading history...
829
    {
0 ignored issues
show
Coding Style introduced by
Expected 0 blank lines after opening function brace; 1 found
Loading history...
830
831
        $partition_id = trim($partition_id, '\'');
0 ignored issues
show
Coding Style introduced by
The variable $partition_id should be in camel caps format.
Loading history...
832
        $this->settings()->set('replication_alter_partitions_sync', 2);
833
        $state = $this->write('ALTER TABLE {dataBaseTableName} DROP PARTITION :partion_id',
0 ignored issues
show
introduced by
Useless variable $state.
Loading history...
834
            [
835
                'dataBaseTableName' => $dataBaseTableName,
836
                'partion_id' => $partition_id,
0 ignored issues
show
Coding Style introduced by
The variable $partition_id should be in camel caps format.
Loading history...
837
            ]);
838
839
        return $state;
840
    }
841
842
    /**
843
     * Truncate ( drop all partitions )
844
     * @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...
845
     * @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...
846
     * @deprecated
847
     */
848
    public function truncateTable(string $tableName)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::truncateTable() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
849
    {
850
        $partions = $this->partitions($tableName);
851
        $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...
852
        foreach ($partions as $part_key => $part) {
0 ignored issues
show
Coding Style introduced by
The variable $part_key should be in camel caps format.
Loading history...
853
            $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...
Coding Style introduced by
The variable $part_id should be in camel caps format.
Loading history...
854
            $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

854
            $out[$part_id] = /** @scrutinizer ignore-deprecated */ $this->dropPartition($tableName, $part_id);
Loading history...
Coding Style introduced by
The variable $part_id should be in camel caps format.
Loading history...
855
        }
856
857
        return $out;
858
    }
859
860
    /**
861
     * Returns the server's uptime in seconds.
862
     *
863
     * @return int
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
864
     * @throws Exception\TransportException
865
     * @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...
866
     */
867 1
    public function getServerUptime()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getServerUptime() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "int".
Loading history...
868
    {
869 1
        return $this->select('SELECT uptime() as uptime')->fetchOne('uptime');
870
    }
871
872
    /**
873
     * Returns string with the server version.
874
     */
875 1
    public function getServerVersion(): string
876
    {
877 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...
878
    }
879
880
    /**
881
     * Read system.settings table
882
     *
883
     * @return mixed[][]
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
884
     * @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...
885
     */
886 1
    public function getServerSystemSettings(string $like = '')
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::getServerSystemSettings() does not have native return type hint for its return value but it should be possible to add it based on @return annotation "mixed[][]".
Loading history...
887
    {
888 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...
889 1
        $list = $this->select('SELECT * FROM system.settings' . ($like ? ' WHERE name LIKE :like' : ''),
890 1
            ['like' => '%' . $like . '%'])->rows();
891 1
        foreach ($list as $row) {
892 1
            if (isset($row['name'])) {
0 ignored issues
show
introduced by
Use early exit to reduce code nesting.
Loading history...
893 1
                $n = $row['name'];
894 1
                unset($row['name']);
895 1
                $l[$n] = $row;
896
            }
897
        }
898
899 1
        return $l;
900
    }
0 ignored issues
show
Coding Style introduced by
Expected 0 blank lines after function; 1 found
Loading history...
901
902
}
0 ignored issues
show
introduced by
There must be exactly 0 empty lines before class closing brace.
Loading history...
903