1 | <?php |
||||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||||
2 | |||||
3 | namespace ClickHouseDB\Transport; |
||||
4 | |||||
5 | use ClickHouseDB\Exception\TransportException; |
||||
6 | use ClickHouseDB\Query\Degeneration; |
||||
7 | use ClickHouseDB\Query\Query; |
||||
8 | use ClickHouseDB\Query\WhereInFile; |
||||
9 | use ClickHouseDB\Query\WriteToFile; |
||||
10 | use ClickHouseDB\Settings; |
||||
11 | use ClickHouseDB\Statement; |
||||
12 | use const PHP_EOL; |
||||
0 ignored issues
–
show
|
|||||
13 | |||||
14 | class Http |
||||
15 | { |
||||
16 | const AUTH_METHOD_HEADER = 1; |
||||
0 ignored issues
–
show
|
|||||
17 | const AUTH_METHOD_QUERY_STRING = 2; |
||||
0 ignored issues
–
show
|
|||||
18 | const AUTH_METHOD_BASIC_AUTH = 3; |
||||
0 ignored issues
–
show
|
|||||
19 | |||||
20 | const AUTH_METHODS_LIST = [ |
||||
0 ignored issues
–
show
|
|||||
21 | self::AUTH_METHOD_HEADER, |
||||
22 | self::AUTH_METHOD_QUERY_STRING, |
||||
23 | self::AUTH_METHOD_BASIC_AUTH, |
||||
24 | ]; |
||||
25 | |||||
26 | /** |
||||
0 ignored issues
–
show
|
|||||
27 | * @var string |
||||
28 | */ |
||||
29 | private $_username = null; |
||||
30 | |||||
31 | /** |
||||
0 ignored issues
–
show
|
|||||
32 | * @var string |
||||
33 | */ |
||||
34 | private $_password = null; |
||||
35 | |||||
36 | /** |
||||
37 | * The username and password can be indicated in one of three ways: |
||||
38 | * - Using HTTP Basic Authentication. |
||||
39 | * - In the ‘user’ and ‘password’ URL parameters. |
||||
40 | * - Using ‘X-ClickHouse-User’ and ‘X-ClickHouse-Key’ headers (by default) |
||||
41 | * |
||||
42 | * @see https://clickhouse.tech/docs/en/interfaces/http/ |
||||
0 ignored issues
–
show
|
|||||
43 | * @var int |
||||
44 | */ |
||||
45 | private $_authMethod = self::AUTH_METHOD_HEADER; |
||||
46 | |||||
47 | /** |
||||
0 ignored issues
–
show
|
|||||
48 | * @var string |
||||
49 | */ |
||||
50 | private $_host = ''; |
||||
51 | |||||
52 | /** |
||||
0 ignored issues
–
show
|
|||||
53 | * @var int |
||||
54 | */ |
||||
55 | private $_port = 0; |
||||
56 | |||||
57 | /** |
||||
0 ignored issues
–
show
|
|||||
58 | * @var bool|int |
||||
59 | */ |
||||
60 | private $_verbose = false; |
||||
61 | |||||
62 | /** |
||||
0 ignored issues
–
show
|
|||||
63 | * @var CurlerRolling |
||||
64 | */ |
||||
65 | private $_curler = null; |
||||
66 | |||||
67 | /** |
||||
0 ignored issues
–
show
|
|||||
68 | * @var Settings |
||||
69 | */ |
||||
70 | private $_settings = null; |
||||
71 | |||||
72 | /** |
||||
0 ignored issues
–
show
|
|||||
73 | * @var array |
||||
0 ignored issues
–
show
|
|||||
74 | */ |
||||
75 | private $_query_degenerations = []; |
||||
0 ignored issues
–
show
|
|||||
76 | |||||
77 | /** |
||||
78 | * Count seconds (int) |
||||
79 | * |
||||
80 | * @var int |
||||
81 | */ |
||||
82 | private $_connectTimeOut = 5; |
||||
83 | |||||
84 | /** |
||||
0 ignored issues
–
show
|
|||||
85 | * @var callable |
||||
86 | */ |
||||
87 | private $xClickHouseProgress = null; |
||||
88 | |||||
89 | /** |
||||
0 ignored issues
–
show
|
|||||
90 | * @var null|string |
||||
0 ignored issues
–
show
|
|||||
91 | */ |
||||
92 | private $sslCA = null; |
||||
93 | |||||
94 | /** |
||||
95 | * Http constructor. |
||||
0 ignored issues
–
show
|
|||||
96 | * @param string $host |
||||
0 ignored issues
–
show
|
|||||
97 | * @param int $port |
||||
0 ignored issues
–
show
|
|||||
98 | * @param string $username |
||||
99 | * @param string $password |
||||
100 | * @param int $authMethod |
||||
0 ignored issues
–
show
|
|||||
101 | */ |
||||
102 | 66 | public function __construct($host, $port, $username, $password, $authMethod = null) |
|||
0 ignored issues
–
show
|
|||||
103 | { |
||||
104 | 66 | $this->setHost($host, $port); |
|||
105 | |||||
106 | 66 | $this->_username = $username; |
|||
107 | 66 | $this->_password = $password; |
|||
108 | 66 | if ($authMethod) { |
|||
0 ignored issues
–
show
The expression
$authMethod of type integer|null is loosely compared to true ; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
Loading history...
|
|||||
109 | $this->_authMethod = $authMethod; |
||||
110 | } |
||||
111 | |||||
112 | 66 | $this->_settings = new Settings($this); |
|||
113 | |||||
114 | 66 | $this->setCurler(); |
|||
115 | 66 | } |
|||
0 ignored issues
–
show
|
|||||
116 | |||||
117 | |||||
118 | 66 | public function setCurler() |
|||
0 ignored issues
–
show
|
|||||
119 | { |
||||
120 | 66 | $this->_curler = new CurlerRolling(); |
|||
121 | 66 | } |
|||
122 | |||||
123 | /** |
||||
124 | * @param CurlerRolling $curler |
||||
0 ignored issues
–
show
|
|||||
125 | */ |
||||
126 | public function setDirtyCurler(CurlerRolling $curler) |
||||
0 ignored issues
–
show
|
|||||
127 | { |
||||
128 | if ($curler instanceof CurlerRolling) { |
||||
0 ignored issues
–
show
|
|||||
129 | $this->_curler = $curler; |
||||
130 | } |
||||
131 | } |
||||
132 | |||||
133 | /** |
||||
134 | * @return CurlerRolling |
||||
135 | */ |
||||
136 | public function getCurler() |
||||
0 ignored issues
–
show
|
|||||
137 | { |
||||
138 | return $this->_curler; |
||||
139 | } |
||||
140 | |||||
141 | /** |
||||
142 | * @param string $host |
||||
143 | * @param int $port |
||||
0 ignored issues
–
show
|
|||||
144 | */ |
||||
145 | 66 | public function setHost($host, $port = -1) |
|||
0 ignored issues
–
show
|
|||||
146 | { |
||||
147 | 66 | if ($port > 0) { |
|||
148 | 66 | $this->_port = $port; |
|||
149 | } |
||||
150 | |||||
151 | 66 | $this->_host = $host; |
|||
152 | 66 | } |
|||
153 | |||||
154 | /** |
||||
155 | * Sets client SSL certificate for Yandex Cloud |
||||
156 | * |
||||
157 | * @param string $caPath |
||||
158 | */ |
||||
159 | public function setSslCa($caPath) |
||||
0 ignored issues
–
show
|
|||||
160 | { |
||||
161 | $this->sslCA = $caPath; |
||||
162 | } |
||||
163 | |||||
164 | /** |
||||
165 | * @return string |
||||
166 | */ |
||||
167 | 53 | public function getUri() |
|||
0 ignored issues
–
show
|
|||||
168 | { |
||||
169 | 53 | $proto = 'http'; |
|||
170 | 53 | if ($this->settings()->isHttps()) { |
|||
0 ignored issues
–
show
|
|||||
171 | 1 | $proto = 'https'; |
|||
172 | } |
||||
173 | 53 | $uri = $proto . '://' . $this->_host; |
|||
174 | 53 | if (stripos($this->_host, '/') !== false || stripos($this->_host, ':') !== false) { |
|||
0 ignored issues
–
show
|
|||||
175 | 1 | return $uri; |
|||
176 | } |
||||
177 | 53 | if (intval($this->_port) > 0) { |
|||
0 ignored issues
–
show
|
|||||
178 | 53 | return $uri . ':' . $this->_port; |
|||
179 | } |
||||
180 | 1 | return $uri; |
|||
0 ignored issues
–
show
|
|||||
181 | } |
||||
182 | |||||
183 | /** |
||||
184 | * @return Settings |
||||
185 | */ |
||||
186 | 66 | public function settings() |
|||
0 ignored issues
–
show
|
|||||
187 | { |
||||
188 | 66 | return $this->_settings; |
|||
189 | } |
||||
190 | |||||
191 | /** |
||||
192 | * @param bool|int $flag |
||||
0 ignored issues
–
show
|
|||||
193 | * @return mixed |
||||
194 | */ |
||||
195 | public function verbose($flag) |
||||
196 | { |
||||
197 | $this->_verbose = $flag; |
||||
198 | return $flag; |
||||
0 ignored issues
–
show
|
|||||
199 | } |
||||
200 | |||||
201 | /** |
||||
202 | * @param array $params |
||||
0 ignored issues
–
show
|
|||||
203 | * @return string |
||||
204 | */ |
||||
205 | 43 | private function getUrl($params = []) |
|||
0 ignored issues
–
show
|
|||||
206 | { |
||||
207 | 43 | $settings = $this->settings()->getSettings(); |
|||
208 | |||||
209 | 43 | if (is_array($params) && sizeof($params)) { |
|||
0 ignored issues
–
show
|
|||||
210 | 43 | $settings = array_merge($settings, $params); |
|||
0 ignored issues
–
show
|
|||||
211 | } |
||||
212 | |||||
0 ignored issues
–
show
|
|||||
213 | |||||
214 | 43 | if ($this->settings()->isReadOnlyUser()) { |
|||
215 | unset($settings['extremes']); |
||||
216 | unset($settings['readonly']); |
||||
217 | unset($settings['enable_http_compression']); |
||||
218 | unset($settings['max_execution_time']); |
||||
219 | |||||
0 ignored issues
–
show
|
|||||
220 | } |
||||
221 | |||||
222 | 43 | unset($settings['https']); |
|||
223 | |||||
0 ignored issues
–
show
|
|||||
224 | |||||
225 | 43 | return $this->getUri() . '?' . http_build_query($settings); |
|||
0 ignored issues
–
show
|
|||||
226 | } |
||||
227 | |||||
228 | /** |
||||
229 | * @param array $extendinfo |
||||
0 ignored issues
–
show
|
|||||
230 | * @return CurlerRequest |
||||
231 | */ |
||||
232 | 43 | private function newRequest($extendinfo) |
|||
0 ignored issues
–
show
|
|||||
233 | { |
||||
234 | 43 | $new = new CurlerRequest(); |
|||
235 | |||||
236 | 43 | switch ($this->_authMethod) { |
|||
237 | 43 | case self::AUTH_METHOD_QUERY_STRING: |
|||
238 | /* @todo: Move this implementation to CurlerRequest class. Possible options: the authentication method |
||||
239 | * should be applied in method `CurlerRequest:prepareRequest()`. |
||||
240 | */ |
||||
241 | $this->settings()->set('user', $this->_username); |
||||
242 | $this->settings()->set('password', $this->_password); |
||||
243 | break; |
||||
244 | 43 | case self::AUTH_METHOD_BASIC_AUTH: |
|||
245 | $new->authByBasicAuth($this->_username, $this->_password); |
||||
246 | break; |
||||
247 | default: |
||||
248 | // Auth with headers by default |
||||
249 | 43 | $new->authByHeaders($this->_username, $this->_password); |
|||
250 | 43 | break; |
|||
251 | } |
||||
252 | |||||
253 | 43 | $new->POST()->setRequestExtendedInfo($extendinfo); |
|||
254 | |||||
255 | 43 | if ($this->settings()->isEnableHttpCompression()) { |
|||
0 ignored issues
–
show
|
|||||
256 | 43 | $new->httpCompression(true); |
|||
257 | } |
||||
258 | 43 | if ($this->settings()->getSessionId()) { |
|||
0 ignored issues
–
show
|
|||||
259 | 1 | $new->persistent(); |
|||
260 | } |
||||
261 | 43 | if ($this->sslCA) { |
|||
262 | $new->setSslCa($this->sslCA); |
||||
263 | } |
||||
264 | |||||
265 | 43 | $new->timeOut($this->settings()->getTimeOut()); |
|||
266 | 43 | $new->connectTimeOut($this->_connectTimeOut);//->keepAlive(); // one sec |
|||
267 | 43 | $new->verbose(boolval($this->_verbose)); |
|||
0 ignored issues
–
show
|
|||||
268 | |||||
269 | 43 | return $new; |
|||
270 | } |
||||
271 | |||||
272 | /** |
||||
273 | * @param Query $query |
||||
0 ignored issues
–
show
|
|||||
274 | * @param array $urlParams |
||||
0 ignored issues
–
show
|
|||||
275 | * @param bool $query_as_string |
||||
0 ignored issues
–
show
|
|||||
276 | * @return CurlerRequest |
||||
277 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
278 | */ |
||||
279 | 43 | private function makeRequest(Query $query, $urlParams = [], $query_as_string = false) |
|||
0 ignored issues
–
show
|
|||||
280 | { |
||||
281 | 43 | $sql = $query->toSql(); |
|||
282 | |||||
283 | 43 | if ($query_as_string) { |
|||
0 ignored issues
–
show
|
|||||
284 | 1 | $urlParams['query'] = $sql; |
|||
285 | } |
||||
286 | |||||
287 | $extendinfo = [ |
||||
288 | 43 | 'sql' => $sql, |
|||
289 | 43 | 'query' => $query, |
|||
290 | 43 | 'format' => $query->getFormat() |
|||
0 ignored issues
–
show
|
|||||
291 | ]; |
||||
292 | |||||
293 | 43 | $new = $this->newRequest($extendinfo); |
|||
294 | |||||
295 | /* |
||||
296 | * Build URL after request making, since URL may contain auth data. This will not matter after the |
||||
297 | * implantation of the todo in the `HTTP:newRequest()` method. |
||||
298 | */ |
||||
299 | 43 | $url = $this->getUrl($urlParams); |
|||
300 | 43 | $new->url($url); |
|||
301 | |||||
0 ignored issues
–
show
|
|||||
302 | |||||
303 | 43 | if (!$query_as_string) { |
|||
0 ignored issues
–
show
|
|||||
304 | 43 | $new->parameters_json($sql); |
|||
305 | } |
||||
306 | 43 | if ($this->settings()->isEnableHttpCompression()) { |
|||
307 | 43 | $new->httpCompression(true); |
|||
308 | } |
||||
309 | |||||
310 | 43 | return $new; |
|||
311 | } |
||||
312 | |||||
313 | /** |
||||
314 | * @param string|Query $sql |
||||
0 ignored issues
–
show
|
|||||
315 | * @return CurlerRequest |
||||
316 | */ |
||||
317 | 3 | public function writeStreamData($sql) |
|||
0 ignored issues
–
show
|
|||||
318 | { |
||||
0 ignored issues
–
show
|
|||||
319 | |||||
320 | 3 | if ($sql instanceof Query) { |
|||
321 | 1 | $query = $sql; |
|||
322 | } else { |
||||
323 | 2 | $query = new Query($sql); |
|||
324 | } |
||||
325 | |||||
326 | $extendinfo = [ |
||||
327 | 3 | 'sql' => $sql, |
|||
328 | 3 | 'query' => $query, |
|||
329 | 3 | 'format' => $query->getFormat() |
|||
0 ignored issues
–
show
|
|||||
330 | ]; |
||||
331 | |||||
332 | 3 | $request = $this->newRequest($extendinfo); |
|||
333 | |||||
334 | /* |
||||
335 | * Build URL after request making, since URL may contain auth data. This will not matter after the |
||||
336 | * implantation of the todo in the `HTTP:newRequest()` method. |
||||
337 | */ |
||||
338 | 3 | $url = $this->getUrl([ |
|||
339 | 3 | 'readonly' => 0, |
|||
340 | 3 | 'query' => $query->toSql() |
|||
0 ignored issues
–
show
|
|||||
341 | ]); |
||||
342 | |||||
343 | 3 | $request->url($url); |
|||
344 | 3 | return $request; |
|||
0 ignored issues
–
show
|
|||||
345 | } |
||||
0 ignored issues
–
show
|
|||||
346 | |||||
347 | |||||
348 | /** |
||||
349 | * @param string $sql |
||||
0 ignored issues
–
show
|
|||||
350 | * @param string $file_name |
||||
351 | * @return Statement |
||||
352 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
353 | */ |
||||
354 | 8 | public function writeAsyncCSV($sql, $file_name) |
|||
0 ignored issues
–
show
|
|||||
355 | { |
||||
356 | 8 | $query = new Query($sql); |
|||
357 | |||||
358 | $extendinfo = [ |
||||
359 | 8 | 'sql' => $sql, |
|||
360 | 8 | 'query' => $query, |
|||
361 | 8 | 'format' => $query->getFormat() |
|||
0 ignored issues
–
show
|
|||||
362 | ]; |
||||
363 | |||||
364 | 8 | $request = $this->newRequest($extendinfo); |
|||
365 | |||||
366 | /* |
||||
367 | * Build URL after request making, since URL may contain auth data. This will not matter after the |
||||
368 | * implantation of the todo in the `HTTP:newRequest()` method. |
||||
369 | */ |
||||
370 | 8 | $url = $this->getUrl([ |
|||
371 | 8 | 'readonly' => 0, |
|||
372 | 8 | 'query' => $query->toSql() |
|||
0 ignored issues
–
show
|
|||||
373 | ]); |
||||
374 | |||||
375 | 8 | $request->url($url); |
|||
376 | |||||
377 | $request->setCallbackFunction(function (CurlerRequest $request) { |
||||
0 ignored issues
–
show
|
|||||
378 | 8 | $handle = $request->getInfileHandle(); |
|||
379 | 8 | if (is_resource($handle)) { |
|||
0 ignored issues
–
show
|
|||||
380 | 8 | fclose($handle); |
|||
0 ignored issues
–
show
|
|||||
381 | } |
||||
382 | 8 | }); |
|||
383 | |||||
384 | 8 | $request->setInfile($file_name); |
|||
0 ignored issues
–
show
|
|||||
385 | 8 | $this->_curler->addQueLoop($request); |
|||
386 | |||||
387 | 8 | return new Statement($request); |
|||
388 | } |
||||
389 | |||||
390 | /** |
||||
391 | * get Count Pending Query in Queue |
||||
392 | * |
||||
393 | * @return int |
||||
394 | */ |
||||
395 | 12 | public function getCountPendingQueue() |
|||
0 ignored issues
–
show
|
|||||
396 | { |
||||
397 | 12 | return $this->_curler->countPending(); |
|||
398 | } |
||||
399 | |||||
400 | /** |
||||
401 | * set Connect TimeOut in seconds [CURLOPT_CONNECTTIMEOUT] ( int ) |
||||
402 | * |
||||
403 | * @param int $connectTimeOut |
||||
404 | */ |
||||
405 | 2 | public function setConnectTimeOut($connectTimeOut) |
|||
0 ignored issues
–
show
|
|||||
406 | { |
||||
407 | 2 | $this->_connectTimeOut = $connectTimeOut; |
|||
408 | 2 | } |
|||
409 | |||||
410 | /** |
||||
411 | * get ConnectTimeOut in seconds |
||||
412 | * |
||||
413 | * @return int |
||||
414 | */ |
||||
415 | 37 | public function getConnectTimeOut() |
|||
0 ignored issues
–
show
|
|||||
416 | { |
||||
417 | 37 | return $this->_connectTimeOut; |
|||
418 | } |
||||
0 ignored issues
–
show
|
|||||
419 | |||||
420 | |||||
421 | public function __findXClickHouseProgress($handle) |
||||
0 ignored issues
–
show
|
|||||
422 | { |
||||
423 | $code = curl_getinfo($handle, CURLINFO_HTTP_CODE); |
||||
0 ignored issues
–
show
|
|||||
424 | |||||
425 | // Search X-ClickHouse-Progress |
||||
426 | if ($code == 200) { |
||||
0 ignored issues
–
show
|
|||||
427 | $response = curl_multi_getcontent($handle); |
||||
0 ignored issues
–
show
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...
|
|||||
428 | $header_size = curl_getinfo($handle, CURLINFO_HEADER_SIZE); |
||||
0 ignored issues
–
show
|
|||||
429 | if (!$header_size) { |
||||
0 ignored issues
–
show
|
|||||
430 | return false; |
||||
431 | } |
||||
432 | |||||
433 | $header = substr($response, 0, $header_size); |
||||
0 ignored issues
–
show
|
|||||
434 | if (!$header_size) { |
||||
0 ignored issues
–
show
|
|||||
435 | return false; |
||||
436 | } |
||||
437 | |||||
438 | $pos = strrpos($header, 'X-ClickHouse-Summary:'); |
||||
0 ignored issues
–
show
|
|||||
439 | if (!$pos) { |
||||
0 ignored issues
–
show
|
|||||
440 | return false; |
||||
441 | } |
||||
442 | |||||
443 | $last = substr($header, $pos); |
||||
0 ignored issues
–
show
|
|||||
444 | $data = @json_decode(str_ireplace('X-ClickHouse-Summary:', '', $last), true); |
||||
0 ignored issues
–
show
It seems like
str_ireplace('X-ClickHouse-Summary:', '', $last) can also be of type array ; however, parameter $json of json_decode() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
445 | |||||
446 | if ($data && is_callable($this->xClickHouseProgress)) { |
||||
0 ignored issues
–
show
|
|||||
447 | |||||
448 | if (is_array($this->xClickHouseProgress)) { |
||||
0 ignored issues
–
show
|
|||||
449 | call_user_func_array($this->xClickHouseProgress, [$data]); |
||||
0 ignored issues
–
show
|
|||||
450 | } else { |
||||
451 | call_user_func($this->xClickHouseProgress, $data); |
||||
0 ignored issues
–
show
|
|||||
452 | } |
||||
453 | |||||
0 ignored issues
–
show
|
|||||
454 | |||||
0 ignored issues
–
show
|
|||||
455 | } |
||||
456 | |||||
0 ignored issues
–
show
|
|||||
457 | } |
||||
458 | |||||
459 | } |
||||
0 ignored issues
–
show
|
|||||
460 | |||||
461 | /** |
||||
462 | * @param Query $query |
||||
0 ignored issues
–
show
|
|||||
463 | * @param null|WhereInFile $whereInFile |
||||
0 ignored issues
–
show
|
|||||
464 | * @param null|WriteToFile $writeToFile |
||||
0 ignored issues
–
show
|
|||||
465 | * @return CurlerRequest |
||||
466 | * @throws \Exception |
||||
0 ignored issues
–
show
|
|||||
467 | */ |
||||
468 | 38 | public function getRequestRead(Query $query, $whereInFile = null, $writeToFile = null) |
|||
0 ignored issues
–
show
|
|||||
469 | { |
||||
470 | 38 | $urlParams = ['readonly' => 2]; |
|||
0 ignored issues
–
show
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...
|
|||||
471 | 38 | $query_as_string = false; |
|||
0 ignored issues
–
show
|
|||||
472 | // --------------------------------------------------------------------------------- |
||||
473 | 38 | if ($whereInFile instanceof WhereInFile && $whereInFile->size()) { |
|||
0 ignored issues
–
show
|
|||||
474 | // $request = $this->prepareSelectWhereIn($request, $whereInFile); |
||||
475 | 1 | $structure = $whereInFile->fetchUrlParams(); |
|||
476 | // $structure = []; |
||||
477 | 1 | $urlParams = array_merge($urlParams, $structure); |
|||
0 ignored issues
–
show
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...
|
|||||
478 | 1 | $query_as_string = true; |
|||
0 ignored issues
–
show
|
|||||
479 | } |
||||
480 | // --------------------------------------------------------------------------------- |
||||
481 | // if result to file |
||||
482 | 38 | if ($writeToFile instanceof WriteToFile && $writeToFile->fetchFormat()) { |
|||
0 ignored issues
–
show
|
|||||
483 | 1 | $query->setFormat($writeToFile->fetchFormat()); |
|||
484 | 1 | unset($urlParams['extremes']); |
|||
485 | } |
||||
486 | // --------------------------------------------------------------------------------- |
||||
487 | // makeRequest read |
||||
488 | 38 | $request = $this->makeRequest($query, $urlParams, $query_as_string); |
|||
0 ignored issues
–
show
|
|||||
489 | // --------------------------------------------------------------------------------- |
||||
490 | // attach files |
||||
491 | 38 | if ($whereInFile instanceof WhereInFile && $whereInFile->size()) { |
|||
0 ignored issues
–
show
|
|||||
492 | 1 | $request->attachFiles($whereInFile->fetchFiles()); |
|||
493 | } |
||||
494 | // --------------------------------------------------------------------------------- |
||||
495 | // result to file |
||||
496 | 38 | if ($writeToFile instanceof WriteToFile && $writeToFile->fetchFormat()) { |
|||
0 ignored issues
–
show
|
|||||
497 | |||||
498 | 1 | $fout = fopen($writeToFile->fetchFile(), 'w'); |
|||
0 ignored issues
–
show
|
|||||
499 | 1 | if (is_resource($fout)) { |
|||
0 ignored issues
–
show
|
|||||
500 | |||||
501 | 1 | $isGz = $writeToFile->getGzip(); |
|||
502 | |||||
503 | 1 | if ($isGz) { |
|||
0 ignored issues
–
show
|
|||||
504 | // write gzip header |
||||
505 | // "\x1f\x8b\x08\x00\x00\x00\x00\x00" |
||||
506 | // fwrite($fout, "\x1F\x8B\x08\x08".pack("V", time())."\0\xFF", 10); |
||||
507 | // write the original file name |
||||
508 | // $oname = str_replace("\0", "", basename($writeToFile->fetchFile())); |
||||
509 | // fwrite($fout, $oname."\0", 1+strlen($oname)); |
||||
510 | |||||
511 | fwrite($fout, "\x1f\x8b\x08\x00\x00\x00\x00\x00"); |
||||
0 ignored issues
–
show
|
|||||
512 | |||||
0 ignored issues
–
show
|
|||||
513 | } |
||||
514 | |||||
0 ignored issues
–
show
|
|||||
515 | |||||
516 | $request->setResultFileHandle($fout, $isGz)->setCallbackFunction(function (CurlerRequest $request) { |
||||
0 ignored issues
–
show
|
|||||
517 | fclose($request->getResultFileHandle()); |
||||
0 ignored issues
–
show
|
|||||
518 | 1 | }); |
|||
519 | } |
||||
520 | } |
||||
521 | 38 | if ($this->xClickHouseProgress) { |
|||
0 ignored issues
–
show
|
|||||
522 | $request->setFunctionProgress([$this, '__findXClickHouseProgress']); |
||||
523 | } |
||||
524 | // --------------------------------------------------------------------------------- |
||||
525 | 38 | return $request; |
|||
0 ignored issues
–
show
|
|||||
526 | |||||
527 | } |
||||
0 ignored issues
–
show
|
|||||
528 | |||||
529 | 1 | public function cleanQueryDegeneration() |
|||
0 ignored issues
–
show
|
|||||
530 | { |
||||
531 | 1 | $this->_query_degenerations = []; |
|||
0 ignored issues
–
show
|
|||||
532 | 1 | return true; |
|||
0 ignored issues
–
show
|
|||||
533 | } |
||||
534 | |||||
535 | 66 | public function addQueryDegeneration(Degeneration $degeneration) |
|||
0 ignored issues
–
show
|
|||||
536 | { |
||||
537 | 66 | $this->_query_degenerations[] = $degeneration; |
|||
0 ignored issues
–
show
|
|||||
538 | 66 | return true; |
|||
0 ignored issues
–
show
|
|||||
539 | } |
||||
540 | |||||
541 | /** |
||||
542 | * @param Query $query |
||||
0 ignored issues
–
show
|
|||||
543 | * @return CurlerRequest |
||||
544 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
545 | */ |
||||
546 | 26 | public function getRequestWrite(Query $query) |
|||
0 ignored issues
–
show
|
|||||
547 | { |
||||
548 | 26 | $urlParams = ['readonly' => 0]; |
|||
549 | 26 | return $this->makeRequest($query, $urlParams); |
|||
0 ignored issues
–
show
|
|||||
550 | } |
||||
551 | |||||
552 | /** |
||||
553 | * @throws TransportException |
||||
554 | */ |
||||
555 | 37 | public function ping(): bool |
|||
556 | { |
||||
557 | 37 | $request = new CurlerRequest(); |
|||
558 | 37 | $request->url($this->getUri())->verbose(false)->GET()->connectTimeOut($this->getConnectTimeOut()); |
|||
559 | 37 | $this->_curler->execOne($request); |
|||
560 | |||||
561 | 37 | return $request->response()->body() === 'Ok.' . PHP_EOL; |
|||
562 | } |
||||
563 | |||||
564 | /** |
||||
565 | * @param string $sql |
||||
0 ignored issues
–
show
|
|||||
566 | * @param mixed[] $bindings |
||||
567 | * @return Query |
||||
568 | */ |
||||
569 | 44 | private function prepareQuery($sql, $bindings) |
|||
0 ignored issues
–
show
|
|||||
570 | { |
||||
0 ignored issues
–
show
|
|||||
571 | |||||
572 | // add Degeneration query |
||||
573 | 44 | foreach ($this->_query_degenerations as $degeneration) { |
|||
0 ignored issues
–
show
|
|||||
574 | 44 | $degeneration->bindParams($bindings); |
|||
575 | } |
||||
576 | |||||
577 | 44 | return new Query($sql, $this->_query_degenerations); |
|||
0 ignored issues
–
show
|
|||||
578 | } |
||||
0 ignored issues
–
show
|
|||||
579 | |||||
580 | |||||
581 | /** |
||||
582 | * @param Query|string $sql |
||||
0 ignored issues
–
show
|
|||||
583 | * @param mixed[] $bindings |
||||
0 ignored issues
–
show
|
|||||
584 | * @param null|WhereInFile $whereInFile |
||||
0 ignored issues
–
show
|
|||||
585 | * @param null|WriteToFile $writeToFile |
||||
0 ignored issues
–
show
|
|||||
586 | * @return CurlerRequest |
||||
587 | * @throws \Exception |
||||
0 ignored issues
–
show
|
|||||
588 | */ |
||||
589 | 37 | private function prepareSelect($sql, $bindings, $whereInFile, $writeToFile = null) |
|||
0 ignored issues
–
show
|
|||||
590 | { |
||||
591 | 37 | if ($sql instanceof Query) { |
|||
0 ignored issues
–
show
|
|||||
592 | return $this->getRequestWrite($sql); |
||||
593 | } |
||||
594 | 37 | $query = $this->prepareQuery($sql, $bindings); |
|||
595 | 37 | $query->setFormat('JSON'); |
|||
596 | 37 | return $this->getRequestRead($query, $whereInFile, $writeToFile); |
|||
0 ignored issues
–
show
|
|||||
597 | } |
||||
0 ignored issues
–
show
|
|||||
598 | |||||
599 | |||||
600 | /** |
||||
601 | * @param Query|string $sql |
||||
0 ignored issues
–
show
|
|||||
602 | * @param mixed[] $bindings |
||||
0 ignored issues
–
show
|
|||||
603 | * @return CurlerRequest |
||||
604 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
605 | */ |
||||
606 | 27 | private function prepareWrite($sql, $bindings = []) |
|||
0 ignored issues
–
show
|
|||||
607 | { |
||||
608 | 27 | if ($sql instanceof Query) { |
|||
609 | return $this->getRequestWrite($sql); |
||||
610 | } |
||||
611 | |||||
612 | 27 | $query = $this->prepareQuery($sql, $bindings); |
|||
613 | 26 | return $this->getRequestWrite($query); |
|||
0 ignored issues
–
show
|
|||||
614 | } |
||||
615 | |||||
616 | /** |
||||
617 | * @return bool |
||||
0 ignored issues
–
show
|
|||||
618 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
619 | */ |
||||
620 | 10 | public function executeAsync() |
|||
0 ignored issues
–
show
|
|||||
621 | { |
||||
622 | 10 | return $this->_curler->execLoopWait(); |
|||
623 | } |
||||
624 | |||||
625 | /** |
||||
626 | * @param Query|string $sql |
||||
0 ignored issues
–
show
|
|||||
627 | * @param mixed[] $bindings |
||||
0 ignored issues
–
show
|
|||||
628 | * @param null|WhereInFile $whereInFile |
||||
0 ignored issues
–
show
|
|||||
629 | * @param null|WriteToFile $writeToFile |
||||
0 ignored issues
–
show
|
|||||
630 | * @return Statement |
||||
631 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
632 | * @throws \Exception |
||||
0 ignored issues
–
show
|
|||||
633 | */ |
||||
634 | 30 | public function select($sql, array $bindings = [], $whereInFile = null, $writeToFile = null) |
|||
0 ignored issues
–
show
|
|||||
635 | { |
||||
636 | 30 | $request = $this->prepareSelect($sql, $bindings, $whereInFile, $writeToFile); |
|||
637 | 30 | $this->_curler->execOne($request); |
|||
638 | 30 | return new Statement($request); |
|||
0 ignored issues
–
show
|
|||||
639 | } |
||||
640 | |||||
641 | /** |
||||
642 | * @param Query|string $sql |
||||
0 ignored issues
–
show
|
|||||
643 | * @param mixed[] $bindings |
||||
0 ignored issues
–
show
|
|||||
644 | * @param null|WhereInFile $whereInFile |
||||
0 ignored issues
–
show
|
|||||
645 | * @param null|WriteToFile $writeToFile |
||||
0 ignored issues
–
show
|
|||||
646 | * @return Statement |
||||
647 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
648 | * @throws \Exception |
||||
0 ignored issues
–
show
|
|||||
649 | */ |
||||
650 | 7 | public function selectAsync($sql, array $bindings = [], $whereInFile = null, $writeToFile = null) |
|||
0 ignored issues
–
show
|
|||||
651 | { |
||||
652 | 7 | $request = $this->prepareSelect($sql, $bindings, $whereInFile, $writeToFile); |
|||
653 | 7 | $this->_curler->addQueLoop($request); |
|||
654 | 7 | return new Statement($request); |
|||
0 ignored issues
–
show
|
|||||
655 | } |
||||
656 | |||||
657 | /** |
||||
658 | * @param callable $callback |
||||
0 ignored issues
–
show
|
|||||
659 | */ |
||||
660 | public function setProgressFunction(callable $callback) : void |
||||
0 ignored issues
–
show
|
|||||
661 | { |
||||
662 | $this->xClickHouseProgress = $callback; |
||||
663 | } |
||||
664 | |||||
665 | /** |
||||
666 | * @param string $sql |
||||
0 ignored issues
–
show
|
|||||
667 | * @param mixed[] $bindings |
||||
668 | * @param bool $exception |
||||
0 ignored issues
–
show
|
|||||
669 | * @return Statement |
||||
670 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
671 | */ |
||||
672 | 27 | public function write($sql, array $bindings = [], $exception = true) |
|||
0 ignored issues
–
show
|
|||||
673 | { |
||||
674 | 27 | $request = $this->prepareWrite($sql, $bindings); |
|||
675 | 26 | $this->_curler->execOne($request); |
|||
676 | 26 | $response = new Statement($request); |
|||
677 | 26 | if ($exception) { |
|||
0 ignored issues
–
show
|
|||||
678 | 26 | if ($response->isError()) { |
|||
679 | 3 | $response->error(); |
|||
680 | } |
||||
681 | } |
||||
682 | 24 | return $response; |
|||
0 ignored issues
–
show
|
|||||
683 | } |
||||
684 | |||||
685 | /** |
||||
686 | * @param Stream $streamRW |
||||
0 ignored issues
–
show
|
|||||
687 | * @param CurlerRequest $request |
||||
0 ignored issues
–
show
|
|||||
688 | * @return Statement |
||||
689 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
690 | */ |
||||
691 | 2 | private function streaming(Stream $streamRW, CurlerRequest $request) |
|||
0 ignored issues
–
show
|
|||||
692 | { |
||||
693 | 2 | $callable = $streamRW->getClosure(); |
|||
694 | 2 | $stream = $streamRW->getStream(); |
|||
0 ignored issues
–
show
Equals sign not aligned with surrounding assignments; expected 3 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...
|
|||||
695 | |||||
0 ignored issues
–
show
|
|||||
696 | |||||
697 | try { |
||||
0 ignored issues
–
show
|
|||||
698 | |||||
0 ignored issues
–
show
|
|||||
699 | |||||
700 | 2 | if (!is_callable($callable)) { |
|||
0 ignored issues
–
show
|
|||||
701 | if ($streamRW->isWrite()) { |
||||
0 ignored issues
–
show
|
|||||
702 | |||||
703 | $callable = function ($ch, $fd, $length) use ($stream) { |
||||
0 ignored issues
–
show
|
|||||
704 | return ($line = fread($stream, $length)) ? $line : ''; |
||||
0 ignored issues
–
show
|
|||||
705 | }; |
||||
706 | } else { |
||||
707 | $callable = function ($ch, $fd) use ($stream) { |
||||
0 ignored issues
–
show
|
|||||
708 | return fwrite($stream, $fd); |
||||
0 ignored issues
–
show
|
|||||
709 | }; |
||||
710 | } |
||||
711 | } |
||||
712 | |||||
713 | 2 | if ($streamRW->isGzipHeader()) { |
|||
0 ignored issues
–
show
|
|||||
714 | |||||
715 | 1 | if ($streamRW->isWrite()) { |
|||
0 ignored issues
–
show
|
|||||
716 | 1 | $request->header('Content-Encoding', 'gzip'); |
|||
717 | 1 | $request->header('Content-Type', 'application/x-www-form-urlencoded'); |
|||
718 | } else { |
||||
719 | $request->header('Accept-Encoding', 'gzip'); |
||||
720 | } |
||||
721 | |||||
0 ignored issues
–
show
|
|||||
722 | } |
||||
723 | |||||
0 ignored issues
–
show
|
|||||
724 | |||||
725 | 2 | $request->header('Transfer-Encoding', 'chunked'); |
|||
726 | |||||
0 ignored issues
–
show
|
|||||
727 | |||||
728 | 2 | if ($streamRW->isWrite()) { |
|||
0 ignored issues
–
show
|
|||||
729 | 1 | $request->setReadFunction($callable); |
|||
730 | } else { |
||||
731 | 1 | $request->setWriteFunction($callable); |
|||
732 | |||||
0 ignored issues
–
show
|
|||||
733 | |||||
734 | // $request->setHeaderFunction($callableHead); |
||||
735 | } |
||||
736 | |||||
0 ignored issues
–
show
|
|||||
737 | |||||
738 | 2 | $this->_curler->execOne($request, true); |
|||
739 | 2 | $response = new Statement($request); |
|||
740 | 2 | if ($response->isError()) { |
|||
0 ignored issues
–
show
|
|||||
741 | $response->error(); |
||||
742 | } |
||||
743 | 2 | return $response; |
|||
0 ignored issues
–
show
|
|||||
744 | } finally { |
||||
745 | 2 | if ($streamRW->isWrite()) |
|||
0 ignored issues
–
show
|
|||||
746 | 2 | fclose($stream); |
|||
0 ignored issues
–
show
|
|||||
747 | } |
||||
748 | |||||
0 ignored issues
–
show
|
|||||
749 | |||||
750 | } |
||||
0 ignored issues
–
show
|
|||||
751 | |||||
752 | |||||
753 | /** |
||||
754 | * @param Stream $streamRead |
||||
0 ignored issues
–
show
|
|||||
755 | * @param string $sql |
||||
0 ignored issues
–
show
|
|||||
756 | * @param mixed[] $bindings |
||||
757 | * @return Statement |
||||
758 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
759 | */ |
||||
760 | 1 | public function streamRead(Stream $streamRead, $sql, $bindings = []) |
|||
0 ignored issues
–
show
|
|||||
761 | { |
||||
762 | 1 | $sql = $this->prepareQuery($sql, $bindings); |
|||
0 ignored issues
–
show
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...
|
|||||
763 | 1 | $request = $this->getRequestRead($sql); |
|||
764 | 1 | return $this->streaming($streamRead, $request); |
|||
0 ignored issues
–
show
|
|||||
765 | |||||
766 | } |
||||
0 ignored issues
–
show
|
|||||
767 | |||||
768 | /** |
||||
769 | * @param Stream $streamWrite |
||||
0 ignored issues
–
show
|
|||||
770 | * @param string $sql |
||||
0 ignored issues
–
show
|
|||||
771 | * @param mixed[] $bindings |
||||
772 | * @return Statement |
||||
773 | * @throws \ClickHouseDB\Exception\TransportException |
||||
0 ignored issues
–
show
|
|||||
774 | */ |
||||
775 | 1 | public function streamWrite(Stream $streamWrite, $sql, $bindings = []) |
|||
0 ignored issues
–
show
|
|||||
776 | { |
||||
777 | 1 | $sql = $this->prepareQuery($sql, $bindings); |
|||
0 ignored issues
–
show
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...
|
|||||
778 | 1 | $request = $this->writeStreamData($sql); |
|||
779 | 1 | return $this->streaming($streamWrite, $request); |
|||
0 ignored issues
–
show
|
|||||
780 | } |
||||
781 | } |
||||
782 |