Passed
Push — master ( a58ab5...d43eeb )
by Igor
02:11
created

Client::maxTimeExecutionAllAsync()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 0
dl 0
loc 2
ccs 0
cts 1
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ClickHouseDB;
6
7
use ClickHouseDB\Exception\QueryException;
8
use ClickHouseDB\Query\Degeneration;
9
use ClickHouseDB\Query\Degeneration\Bindings;
10
use ClickHouseDB\Query\Degeneration\Conditions;
11
use ClickHouseDB\Query\WhereInFile;
12
use ClickHouseDB\Query\WriteToFile;
13
use ClickHouseDB\Quote\FormatLine;
14
use ClickHouseDB\Transport\Http;
15
use ClickHouseDB\Transport\Stream;
16
use function array_flip;
0 ignored issues
show
introduced by
Type array_flip is not used in this file.
Loading history...
17
use function array_keys;
18
use function array_rand;
0 ignored issues
show
introduced by
Type array_rand is not used in this file.
Loading history...
19
use function array_values;
20
use function count;
21
use function date;
22
use function implode;
23
use function in_array;
24
use function is_array;
25
use function is_callable;
26
use function is_file;
27
use function is_readable;
28
use function is_string;
29
use function sprintf;
30
use function stripos;
31
use function strtotime;
32
use function trim;
33
34
class Client
35
{
36
    const SUPPORTED_FORMATS = ['TabSeparated', 'TabSeparatedWithNames', 'CSV', 'CSVWithNames', 'JSONEachRow'];
0 ignored issues
show
introduced by
Constant \ClickHouseDB\Client::SUPPORTED_FORMATS visibility missing.
Loading history...
37
38
    /** @var Http */
39
    private $transport;
40
41
    /** @var string */
42
    private $connectUsername;
43
44
    /** @var string */
45
    private $connectPassword;
46
47
    /** @var string */
48
    private $connectHost;
49
50
    /** @var string */
51
    private $connectPort;
52
53
    /** @var bool */
54
    private $connectUserReadonly = false;
55
56
    /**
57
     * @param mixed[] $connectParams
58
     * @param mixed[] $settings
59
     */
60 63
    public function __construct(array $connectParams, array $settings = [])
61
    {
62 63
        if (! isset($connectParams['username'])) {
63
            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...
64
        }
65
66 63
        if (! isset($connectParams['password'])) {
67
            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...
68
        }
69
70 63
        if (! isset($connectParams['port'])) {
71
            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...
72
        }
73
74 63
        if (! isset($connectParams['host'])) {
75
            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...
76
        }
77
78 63
        $this->connectUsername = $connectParams['username'];
79 63
        $this->connectPassword = $connectParams['password'];
80 63
        $this->connectPort     = $connectParams['port'];
81 63
        $this->connectHost     = $connectParams['host'];
82
83
        // init transport class
84 63
        $this->transport = new Http(
85 63
            $this->connectHost,
86 63
            $this->connectPort,
87 63
            $this->connectUsername,
88 63
            $this->connectPassword
89
        );
90
91 63
        $this->transport->addQueryDegeneration(new Bindings());
92
93
        // apply settings to transport class
94 63
        $this->settings()->database('default');
95 63
        if (! empty($settings)) {
96 1
            $this->settings()->apply($settings);
97
        }
98
99 63
        if (isset($connectParams['readonly'])) {
100
            $this->setReadOnlyUser($connectParams['readonly']);
101
        }
102
103 63
        if (isset($connectParams['https'])) {
104
            $this->https($connectParams['https']);
105
        }
106
107 63
        $this->enableHttpCompression();
108 63
    }
109
110
    /**
111
     * if the user has only read in the config file
112
     */
113
    public function setReadOnlyUser(bool $flag)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::setReadOnlyUser() does not have void return type hint.
Loading history...
114
    {
115
        $this->connectUserReadonly = $flag;
116
        $this->settings()->setReadOnlyUser($this->connectUserReadonly);
117
    }
118
119
    /**
120
     * Clear Degeneration processing request [template ]
121
     *
122
     * @return bool
123
     */
124 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...
125
    {
126 1
        return $this->transport->cleanQueryDegeneration();
127
    }
128
129
    /**
130
     * add Degeneration processing
131
     *
132
     * @return bool
133
     */
134
    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...
135
    {
136
        return $this->transport->addQueryDegeneration($degeneration);
137
    }
138
139
    /**
140
     * add Conditions in query
141
     *
142
     * @return bool
143
     */
144 1
    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...
145
    {
146 1
        return $this->transport->addQueryDegeneration(new Conditions());
147
    }
148
149
    /**
150
     * Set connection host
151
     *
152
     * @param string $host
153
     */
154
    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...
155
    {
156
        $this->connectHost = $host;
157
        $this->transport()->setHost($host);
158
    }
159
160
    /**
161
     * @return Settings
162
     */
163 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...
164
    {
165 2
        return $this->settings()->max_execution_time($timeout);
0 ignored issues
show
Bug introduced by
$timeout of type double is incompatible with the type integer expected by parameter $time of ClickHouseDB\Settings::max_execution_time(). ( Ignorable by Annotation )

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

165
        return $this->settings()->max_execution_time(/** @scrutinizer ignore-type */ $timeout);
Loading history...
166
    }
167
168
    /**
169
     * @return mixed
170
     */
171 1
    public function getTimeout()
172
    {
173 1
        return $this->settings()->getTimeOut();
174
    }
175
176
    /**
177
     * ConnectTimeOut in seconds ( support 1.5 = 1500ms )
178
     */
179 2
    public function setConnectTimeOut(float $connectTimeOut)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::setConnectTimeOut() does not have void return type hint.
Loading history...
180
    {
181 2
        $this->transport()->setConnectTimeOut($connectTimeOut);
0 ignored issues
show
Bug introduced by
$connectTimeOut of type double is incompatible with the type integer expected by parameter $connectTimeOut of ClickHouseDB\Transport\Http::setConnectTimeOut(). ( Ignorable by Annotation )

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

181
        $this->transport()->setConnectTimeOut(/** @scrutinizer ignore-type */ $connectTimeOut);
Loading history...
182 2
    }
183
184
    /**
185
     * @return int
186
     */
187 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...
188
    {
189 1
        return $this->transport()->getConnectTimeOut();
190
    }
191
192
    /**
193
     * @return Http
194
     */
195 63
    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...
196
    {
197 63
        if (! $this->transport) {
198
            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...
199
        }
200
201 63
        return $this->transport;
202
    }
203
204
    /**
205
     * @return string
206
     */
207
    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...
208
    {
209
        return $this->connectHost;
210
    }
211
212
    /**
213
     * @return string
214
     */
215
    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...
216
    {
217
        return $this->connectPassword;
218
    }
219
220
    /**
221
     * @return string
222
     */
223
    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...
224
    {
225
        return $this->connectPort;
226
    }
227
228
    /**
229
     * @return string
230
     */
231
    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...
232
    {
233
        return $this->connectUsername;
234
    }
235
236
    /**
237
     * @return Http
238
     */
239
    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...
240
    {
241
        return $this->transport;
242
    }
243
244
    /**
245
     * @return mixed
246
     */
247
    public function verbose()
248
    {
249
        return $this->transport()->verbose(true);
250
    }
251
252
    /**
253
     * @return Settings
254
     */
255 63
    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...
256
    {
257 63
        return $this->transport()->settings();
258
    }
259
260
    /**
261
     * @return static
262
     */
263 2
    public function useSession(bool $useSessionId = false)
264
    {
265 2
        if (! $this->settings()->getSessionId()) {
266 2
            if (! $useSessionId) {
267 2
                $this->settings()->makeSessionId();
268
            } else {
269
                $this->settings()->session_id($useSessionId);
0 ignored issues
show
Bug introduced by
$useSessionId of type true is incompatible with the type string expected by parameter $session_id of ClickHouseDB\Settings::session_id(). ( Ignorable by Annotation )

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

269
                $this->settings()->session_id(/** @scrutinizer ignore-type */ $useSessionId);
Loading history...
270
            }
271
        }
272
273 2
        return $this;
274
    }
275
276
    /**
277
     * @return mixed
278
     */
279 2
    public function getSession()
280
    {
281 2
        return $this->settings()->getSessionId();
282
    }
283
284
    /**
285
     * Query CREATE/DROP
286
     *
287
     * @param mixed[] $bindings
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
288
     * @return Statement
289
     */
290 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...
291
    {
292 26
        return $this->transport()->write($sql, $bindings, $exception);
293
    }
294
295
    /**
296
     * set db name
297
     * @return static
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
298
     */
299 63
    public function database(string $db)
300
    {
301 63
        $this->settings()->database($db);
302
303 63
        return $this;
304
    }
305
306
    /**
307
     * Write to system.query_log
308
     *
309
     * @return static
310
     */
311
    public function enableLogQueries(bool $flag = true)
312
    {
313
        $this->settings()->set('log_queries', (int) $flag);
314
315
        return $this;
316
    }
317
318
    /**
319
     * Compress the result if the HTTP client said that it understands data compressed with gzip or deflate
320
     *
321
     * @return static
322
     */
323 63
    public function enableHttpCompression(bool $flag = true)
324
    {
325 63
        $this->settings()->enableHttpCompression($flag);
326
327 63
        return $this;
328
    }
329
330
    /**
331
     * Enable / Disable HTTPS
332
     *
333
     * @return static
334
     */
335 1
    public function https(bool $flag = true)
336
    {
337 1
        $this->settings()->https($flag);
338
339 1
        return $this;
340
    }
341
342
    /**
343
     * Read extremes of the result columns. They can be output in JSON-formats.
344
     *
345
     * @return static
346
     */
347 2
    public function enableExtremes(bool $flag = true)
348
    {
349 2
        $this->settings()->set('extremes', (int) $flag);
350
351 2
        return $this;
352
    }
353
354
    /**
355
     * @param mixed[] $bindings
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
356
     * @return Statement
357
     */
358 29
    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...
359
        string $sql,
360
        array $bindings = [],
361
        WhereInFile $whereInFile = null,
0 ignored issues
show
introduced by
Parameter $whereInFile has null default value, but is not marked as nullable.
Loading history...
362
        WriteToFile $writeToFile = null
0 ignored issues
show
introduced by
Parameter $writeToFile has null default value, but is not marked as nullable.
Loading history...
363
    ) {
364 29
        return $this->transport()->select($sql, $bindings, $whereInFile, $writeToFile);
365
    }
366
367
    /**
368
     * @return bool
369
     */
370 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...
371
    {
372 10
        return $this->transport()->executeAsync();
373
    }
374
375
    public function maxTimeExecutionAllAsync()
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::maxTimeExecutionAllAsync() does not have void return type hint.
Loading history...
376
    {
377
378
    }
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...
379
380
    /**
381
     * set progressFunction
382
     */
383 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...
384
    {
385 1
        if (! is_callable($callback)) {
386
            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...
387
        }
388
389 1
        if (! $this->settings()->is('send_progress_in_http_headers')) {
390 1
            $this->settings()->set('send_progress_in_http_headers', 1);
391
        }
392 1
        if (! $this->settings()->is('http_headers_progress_interval_ms')) {
393 1
            $this->settings()->set('http_headers_progress_interval_ms', 100);
394
        }
395
396 1
        $this->transport()->setProgressFunction($callback);
397 1
    }
398
399
    /**
400
     * prepare select
401
     *
402
     * @param mixed[] $bindings
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
403
     * @return Statement
404
     */
405 5
    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...
406
        string $sql,
407
        array $bindings = [],
408
        WhereInFile $whereInFile = null,
0 ignored issues
show
introduced by
Parameter $whereInFile has null default value, but is not marked as nullable.
Loading history...
409
        WriteToFile $writeToFile = null
0 ignored issues
show
introduced by
Parameter $writeToFile has null default value, but is not marked as nullable.
Loading history...
410
    ) {
411 5
        return $this->transport()->selectAsync($sql, $bindings, $whereInFile, $writeToFile);
412
    }
413
414
    /**
415
     * SHOW PROCESSLIST
416
     *
417
     * @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...
418
     */
419
    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...
420
    {
421
        return $this->select('SHOW PROCESSLIST')->rows();
422
    }
423
424
    /**
425
     * show databases
426
     *
427
     * @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...
428
     */
429
    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...
430
    {
431
        return $this->select('show databases')->rows();
432
    }
433
434
    /**
435
     * statement = SHOW CREATE TABLE
436
     *
437
     * @return mixed
438
     */
439
    public function showCreateTable(string $table)
440
    {
441
        return $this->select('SHOW CREATE TABLE ' . $table)->fetchOne('statement');
442
    }
443
444
    /**
445
     * SHOW TABLES
446
     *
447
     * @return mixed[]
448
     */
449 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...
450
    {
451 1
        return $this->select('SHOW TABLES')->rowsAsTree('name');
452
    }
453
454
    /**
455
     * Get the number of simultaneous/Pending requests
456
     *
457
     * @return int
458
     */
459 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...
460
    {
461 12
        return $this->transport()->getCountPendingQueue();
462
    }
463
464
    /**
465
     * @param mixed[][] $values
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
466
     * @param string[]  $columns
467
     * @return Statement
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::insert() has useless @return annotation.
Loading history...
468
     * @throws Exception\TransportException
469
     */
470 9
    public function insert(string $table, array $values, array $columns = []) : Statement
471
    {
472 9
        if (empty($values)) {
473 1
            throw QueryException::cannotInsertEmptyValues();
474
        }
475
476 8
        if (stripos($table, '`') === false && stripos($table, '.') === false) {
477 5
            $table = '`' . $table . '`'; //quote table name for dot names
478
        }
479 8
        $sql = 'INSERT INTO ' . $table;
480
481 8
        if (count($columns) !== 0) {
482 7
            $sql .= ' (`' . implode('`,`', $columns) . '`) ';
483
        }
484
485 8
        $sql .= ' VALUES ';
486
487 8
        foreach ($values as $row) {
488 8
            $sql .= ' (' . FormatLine::Insert($row) . '), ';
489
        }
490 8
        $sql = trim($sql, ', ');
491
492 8
        return $this->transport()->write($sql);
493
    }
494
495
    /**
496
     *       * Prepares the values to insert from the associative array.
497
     *       * There may be one or more lines inserted, but then the keys inside the array list must match (including in the sequence)
498
     *       *
499
     *       * @param mixed[] $values - array column_name => value (if we insert one row) or array list column_name => value if we insert many lines
500
     *       * @return mixed[][] - list of arrays - 0 => fields, 1 => list of value arrays for insertion
501
     *       */
502 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...
503
    {
504 3
        if (isset($values[0]) && is_array($values[0])) { //случай, когда много строк вставляется
505 2
            $preparedFields = array_keys($values[0]);
506 2
            $preparedValues = [];
507 2
            foreach ($values as $idx => $row) {
508 2
                $_fields = array_keys($row);
509 2
                if ($_fields !== $preparedFields) {
510 1
                    throw new QueryException(
511 1
                        sprintf(
512 1
                            'Fields not match: %s and %s on element %s',
513 1
                            implode(',', $_fields),
514 1
                            implode(',', $preparedFields),
515 1
                            $idx
516
                        )
517
                    );
518
                }
519 2
                $preparedValues[] = array_values($row);
520
            }
521
        } else {
522 1
            $preparedFields = array_keys($values);
523 1
            $preparedValues = [array_values($values)];
524
        }
525
526 2
        return [$preparedFields, $preparedValues];
527
    }
528
529
    /**
530
     * Inserts one or more rows from an associative array.
531
     * If there is a discrepancy between the keys of the value arrays (or their order) - throws an exception.
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
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
534
     * @return Statement
535
     */
536
    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...
537
    {
538
        list($columns, $vals) = $this->prepareInsertAssocBulk($values);
0 ignored issues
show
introduced by
list(...) is forbidden, use [...] instead.
Loading history...
539
540
        return $this->insert($tableName, $vals, $columns);
541
    }
542
543
    /**
544
     * insert TabSeparated files
545
     *
546
     * @param string|string[] $fileNames
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
547
     * @param string[]        $columns
548
     * @return mixed
549
     */
550 1
    public function insertBatchTSVFiles(string $tableName, $fileNames, array $columns = [])
551
    {
552 1
        return $this->insertBatchFiles($tableName, $fileNames, $columns, 'TabSeparated');
553
    }
554
555
    /**
556
     * insert Batch Files
557
     *
558
     * @param string|string[] $fileNames
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
559
     * @param string[]        $columns
560
     * @param string          $format ['TabSeparated','TabSeparatedWithNames','CSV','CSVWithNames']
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
561
     * @return Statement[]
562
     * @throws Exception\TransportException
563
     */
564 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...
565
    {
566 8
        if (is_string($fileNames)) {
567
            $fileNames = [$fileNames];
568
        }
569 8
        if ($this->getCountPendingQueue() > 0) {
570
            throw new QueryException('Queue must be empty, before insertBatch, need executeAsync');
571
        }
572
573 8
        if (! in_array($format, self::SUPPORTED_FORMATS, true)) {
574
            throw new QueryException('Format not support in insertBatchFiles');
575
        }
576
577 8
        $result = [];
578
579 8
        foreach ($fileNames as $fileName) {
580 8
            if (! is_file($fileName) || ! is_readable($fileName)) {
581
                throw  new QueryException('Cant read file: ' . $fileName . ' ' . (is_file($fileName) ? '' : ' is not file'));
582
            }
583
584 8
            if (empty($columns)) {
585
                $sql = 'INSERT INTO ' . $tableName . ' FORMAT ' . $format;
586
            } else {
587 8
                $sql = 'INSERT INTO ' . $tableName . ' ( ' . implode(',', $columns) . ' ) FORMAT ' . $format;
588
            }
589 8
            $result[$fileName] = $this->transport()->writeAsyncCSV($sql, $fileName);
590
        }
591
592
        // exec
593 8
        $this->executeAsync();
594
595
        // fetch resutl
596 8
        foreach ($fileNames as $fileName) {
597 8
            if (! $result[$fileName]->isError()) {
598 6
                continue;
599
            }
600
601 2
            $result[$fileName]->error();
602
        }
603
604 6
        return $result;
605
    }
606
607
    /**
608
     * insert Batch Stream
609
     *
610
     * @param string[] $columns
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
611
     * @param string   $format ['TabSeparated','TabSeparatedWithNames','CSV','CSVWithNames']
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
612
     * @return Transport\CurlerRequest
613
     */
614 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...
615
    {
616 2
        if ($this->getCountPendingQueue() > 0) {
617
            throw new QueryException('Queue must be empty, before insertBatch, need executeAsync');
618
        }
619
620 2
        if (! in_array($format, self::SUPPORTED_FORMATS, true)) {
621
            throw new QueryException('Format not support in insertBatchFiles');
622
        }
623
624 2
        if (empty($columns)) {
625
            $sql = 'INSERT INTO ' . $tableName . ' FORMAT ' . $format;
626
        } else {
627 2
            $sql = 'INSERT INTO ' . $tableName . ' ( ' . implode(',', $columns) . ' ) FORMAT ' . $format;
628
        }
629
630 2
        return $this->transport()->writeStreamData($sql);
631
    }
632
633
    /**
634
     * stream Write
635
     *
636
     * @param string[] $bind
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
637
     * @return Statement
638
     * @throws Exception\TransportException
639
     */
640 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...
641
    {
642 1
        if ($this->getCountPendingQueue() > 0) {
643
            throw new QueryException('Queue must be empty, before streamWrite');
644
        }
645
646 1
        return $this->transport()->streamWrite($stream, $sql, $bind);
647
    }
648
649
    /**
650
     * stream Read
651
     *
652
     * @param string[] $bind
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
653
     * @return Statement
654
     */
655 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...
656
    {
657 1
        if ($this->getCountPendingQueue() > 0) {
658
            throw new QueryException('Queue must be empty, before streamWrite');
659
        }
660
661 1
        return $this->transport()->streamRead($streamRead, $sql, $bind);
662
    }
663
664
    /**
665
     * Size of database
666
     *
667
     * @return mixed|null
668
     */
669
    public function databaseSize()
670
    {
671
        $b = $this->settings()->getDatabase();
672
673
        return $this->select(
674
            '
675
            SELECT database,formatReadableSize(sum(bytes)) as size
676
            FROM system.parts
677
            WHERE active AND database=:database
678
            GROUP BY database
679
            ',
680
            ['database' => $b]
681
        )->fetchOne();
682
    }
683
684
    /**
685
     * Size of tables
686
     *
687
     * @return mixed
688
     */
689 1
    public function tableSize(string $tableName)
690
    {
691 1
        $tables = $this->tablesSize();
692
693 1
        if (isset($tables[$tableName])) {
694 1
            return $tables[$tableName];
695
        }
696
697
        return null;
698
    }
699
700
    /**
701
     * Ping server
702
     *
703
     * @return bool
704
     */
705 39
    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...
706
    {
707 39
        return $this->transport()->ping();
708
    }
709
710
    /**
711
     * Tables sizes
712
     *
713
     * @param bool $flatList
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
714
     * @return mixed[][]
715
     */
716 1
    public function tablesSize($flatList = false)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::tablesSize() does not have parameter type hint for its parameter $flatList but it should be possible to add it based on @param annotation "bool".
Loading history...
introduced by
Method \ClickHouseDB\Client::tablesSize() does not have return type hint for its return value but it should be possible to add it based on @return annotation "mixed[][]".
Loading history...
717
    {
718 1
        $result = $this->select('
719
        SELECT name as table,database,
720
            max(sizebytes) as sizebytes,
721
            max(size) as size,
722
            min(min_date) as min_date,
723
            max(max_date) as max_date
724
            FROM system.tables
725
            ANY LEFT JOIN 
726
            (
727
            SELECT table,database,
728
                        formatReadableSize(sum(bytes)) as size,
729
                        sum(bytes) as sizebytes,
730
                        min(min_date) as min_date,
731
                        max(max_date) as max_date
732
                        FROM system.parts 
733
                        WHERE active AND database=:database
734
                        GROUP BY table,database
735
            ) USING ( table,database )
736
            WHERE database=:database
737
            GROUP BY table,database
738
        ',
739 1
            ['database' => $this->settings()->getDatabase()]);
740
741 1
        if ($flatList) {
742
            return $result->rows();
743
        }
744
745 1
        return $result->rowsAsTree('table');
746
    }
747
748
    /**
749
     * isExists
750
     *
751
     * @return array
0 ignored issues
show
introduced by
@return annotation of method \ClickHouseDB\Client::isExists() does not specify type hint for items of its traversable return value.
Loading history...
752
     */
753
    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...
754
    {
755
        return $this->select(
756
            '
757
            SELECT *
758
            FROM system.tables 
759
            WHERE name=\'' . $table . '\' AND database=\'' . $database . '\''
760
        )->rowsAsTree('name');
761
    }
762
763
    /**
764
     * List of partitions
765
     *
766
     * @return mixed[][]
767
     */
768
    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...
769
    {
770
        $database          = $this->settings()->getDatabase();
771
        $whereActiveClause = $active === null ? '' : sprintf(' AND active = %s', (int) $active);
772
        $limitClause       = $limit !== null ? ' LIMIT ' . $limit : '';
773
774
        return $this->select(<<<CLICKHOUSE
775
SELECT *
776
FROM system.parts 
777
WHERE like(table,'%$table%') AND database='$database'$whereActiveClause
778
ORDER BY max_date $limitClause
779
CLICKHOUSE
780
        )->rowsAsTree('name');
781
    }
782
783
    /**
784
     * dropPartition
785
     * @deprecated
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
introduced by
Incorrect annotations group.
Loading history...
786
     * @return Statement
787
     */
788
    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...
789
    {
0 ignored issues
show
Coding Style introduced by
Expected 0 blank lines after opening function brace; 1 found
Loading history...
790
791
        $partition_id = trim($partition_id, '\'');
792
        $this->settings()->set('replication_alter_partitions_sync', 2);
793
        $state = $this->write('ALTER TABLE {dataBaseTableName} DROP PARTITION :partion_id',
0 ignored issues
show
introduced by
Useless variable $state.
Loading history...
794
            [
795
                'dataBaseTableName' => $dataBaseTableName,
796
                'partion_id'        => $partition_id,
797
            ]);
798
799
        return $state;
800
    }
801
802
    /**
803
     * Truncate ( drop all partitions )
804
     * @deprecated
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
introduced by
Incorrect annotations group.
Loading history...
805
     * @return array
0 ignored issues
show
introduced by
@return annotation of method \ClickHouseDB\Client::truncateTable() does not specify type hint for items of its traversable return value.
Loading history...
806
     */
807
    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...
808
    {
809
        $partions = $this->partitions($tableName);
810
        $out      = [];
811
        foreach ($partions as $part_key => $part) {
812
            $part_id       = $part['partition'];
813
            $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

813
            $out[$part_id] = /** @scrutinizer ignore-deprecated */ $this->dropPartition($tableName, $part_id);
Loading history...
814
        }
815
816
        return $out;
817
    }
818
819
    /**
820
     * Returns the server's uptime in seconds.
821
     *
822
     * @return int
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
823
     * @throws Exception\TransportException
824
     */
825 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...
826
    {
827 1
        return $this->select('SELECT uptime() as uptime')->fetchOne('uptime');
828
    }
829
830
    /**
831
     * Returns string with the server version.
832
     */
833 1
    public function getServerVersion() : string
834
    {
835 1
        return (string) $this->select('SELECT version() as version')->fetchOne('version');
836
    }
837
838
    /**
839
     * Read system.settings table
840
     *
841
     * @return mixed[][]
842
     */
843 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...
844
    {
845 1
        $l    = [];
846 1
        $list = $this->select('SELECT * FROM system.settings' . ($like ? ' WHERE name LIKE :like' : ''),
847 1
            ['like' => '%' . $like . '%'])->rows();
848 1
        foreach ($list as $row) {
849 1
            if (isset($row['name'])) {
0 ignored issues
show
introduced by
Use early exit to reduce code nesting.
Loading history...
850 1
                $n = $row['name'];
851 1
                unset($row['name']);
852 1
                $l[$n] = $row;
853
            }
854
        }
855
856 1
        return $l;
857
    }
858
859
    /**
860
     * dropOldPartitions by day_ago
861
     * @deprecated
0 ignored issues
show
introduced by
Expected 1 lines between description and annotations, found 0.
Loading history...
862
     *
863
     * @return array
0 ignored issues
show
introduced by
Incorrect annotations group.
Loading history...
introduced by
@return annotation of method \ClickHouseDB\Client::dropOldPartitions() does not specify type hint for items of its traversable return value.
Loading history...
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
    public function dropOldPartitions(string $table_name, int $days_ago, int $count_partitons_per_one = 100)
0 ignored issues
show
introduced by
Method \ClickHouseDB\Client::dropOldPartitions() does not have return type hint for its return value but it should be possible to add it based on @return annotation "array".
Loading history...
868
    {
869
        $days_ago = strtotime(date('Y-m-d 00:00:00', strtotime('-' . $days_ago . ' day')));
870
871
        $drop           = [];
872
        $list_patitions = $this->partitions($table_name, $count_partitons_per_one);
873
874
        foreach ($list_patitions as $partion_id => $partition) {
875
            if (stripos($partition['engine'], 'mergetree') === false) {
876
                continue;
877
            }
878
879
            // $min_date = strtotime($partition['min_date']);
880
            $max_date = strtotime($partition['max_date']);
881
882
            if ($max_date < $days_ago) {
0 ignored issues
show
introduced by
Use early exit to reduce code nesting.
Loading history...
883
                $drop[] = $partition['partition'];
884
            }
885
        }
886
887
        $result = [];
888
        foreach ($drop as $partition_id) {
889
            $result[$partition_id] = $this->dropPartition($table_name, $partition_id);
0 ignored issues
show
Deprecated Code introduced by
The function ClickHouseDB\Client::dropPartition() has been deprecated. ( Ignorable by Annotation )

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

889
            $result[$partition_id] = /** @scrutinizer ignore-deprecated */ $this->dropPartition($table_name, $partition_id);
Loading history...
890
        }
891
892
        return $result;
893
    }
894
}
895