Skip to content

Commit 809b5fc

Browse files
committed
Refactor formatting
1 parent c017ad4 commit 809b5fc

File tree

7 files changed

+121
-89
lines changed

7 files changed

+121
-89
lines changed

src/Exception/UnsupportedParameterType.php renamed to src/Exception/UnsupportedValueType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use function gettype;
99
use function sprintf;
1010

11-
final class UnsupportedParameterType extends InvalidArgumentException implements ClickHouseException
11+
final class UnsupportedValueType extends InvalidArgumentException implements ClickHouseException
1212
{
1313
/**
1414
* @param mixed $parameter

src/Query/Degeneration/Bindings.php

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,11 @@
44

55
namespace ClickHouseDB\Query\Degeneration;
66

7-
use ClickHouseDB\Exception\UnsupportedParameterType;
87
use ClickHouseDB\Query\Degeneration;
9-
use DateTimeInterface;
8+
use ClickHouseDB\Quote\ValueFormatter;
109
use function array_map;
1110
use function implode;
1211
use function is_array;
13-
use function is_bool;
14-
use function is_callable;
15-
use function is_float;
16-
use function is_int;
17-
use function is_object;
18-
use function is_string;
19-
use function sprintf;
2012

2113
class Bindings implements Degeneration
2214
{
@@ -45,17 +37,6 @@ public function bindParam($column, $value)
4537
$this->bindings[$column] = $value;
4638
}
4739

48-
/**
49-
* Escape an string
50-
*
51-
* @param string $value
52-
* @return string
53-
*/
54-
private function escapeString($value)
55-
{
56-
return addslashes($value);
57-
}
58-
5940
/**
6041
* Binds a list of values to the corresponding parameters.
6142
* This is similar to [[bindValue()]] except that it binds multiple values at a time.
@@ -92,15 +73,15 @@ public function process($sql)
9273

9374
$values = array_map(
9475
function ($value) {
95-
return $this->formatParameter($value);
76+
return ValueFormatter::formatValue($value);
9677
},
9778
$value
9879
);
9980

10081
$formattedParameter = implode(',', $values);
10182
} else {
10283
$valueSet = $value;
103-
$formattedParameter = $this->formatParameter($value);
84+
$formattedParameter = ValueFormatter::formatValue($value);
10485
}
10586

10687
if ($formattedParameter !== null) {
@@ -122,37 +103,4 @@ function ($value) {
122103

123104
return $sql;
124105
}
125-
126-
/**
127-
* @param mixed $value
128-
* @return mixed
129-
*/
130-
private function formatParameter($value)
131-
{
132-
if ($value instanceof DateTimeInterface) {
133-
$value = $value->format('Y-m-d H:i:s');
134-
}
135-
136-
if (is_float($value) || is_int($value) || is_bool($value) || $value === null) {
137-
return $value;
138-
}
139-
140-
if (is_object($value) && is_callable([$value, '__toString'])) {
141-
$value = (string) $value;
142-
}
143-
144-
if (is_string($value)) {
145-
return $this->formatStringParameter($this->escapeString($value));
146-
}
147-
148-
throw UnsupportedParameterType::new($value);
149-
}
150-
151-
/**
152-
* @return string
153-
*/
154-
private function formatStringParameter($value)
155-
{
156-
return sprintf("'%s'", $value);
157-
}
158106
}

src/Quote/FormatLine.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class FormatLine
1616
* @param string $format
1717
* @return StrictQuoteLine
1818
*/
19-
private static function strictQuote($format)
19+
public static function strictQuote($format)
2020
{
2121
if (empty(self::$strict[$format]))
2222
{
@@ -28,10 +28,10 @@ private static function strictQuote($format)
2828
/**
2929
* Array in a string for a query Insert
3030
*
31-
* @param array $row
31+
* @param mixed[] $row
3232
* @return string
3333
*/
34-
public static function Insert(Array $row)
34+
public static function Insert(array $row)
3535
{
3636
return self::strictQuote('Insert')->quoteRow($row);
3737
}

src/Quote/StrictQuoteLine.php

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33

44
use ClickHouseDB\Exception\QueryException;
55
use function array_map;
6+
use function is_array;
7+
use function is_float;
8+
use function is_int;
69
use function is_string;
710
use function preg_replace;
811
use function str_replace;
912

1013
class StrictQuoteLine
1114
{
12-
1315
private $preset = [
1416
'CSV'=>[
1517
'EnclosureArray'=>'"',
@@ -44,6 +46,7 @@ public function __construct($format)
4446
{
4547
throw new QueryException("Unsupport format encode line:" . $format);
4648
}
49+
4750
$this->settings = $this->preset[$format];
4851
}
4952
public function quoteRow($row)
@@ -59,51 +62,46 @@ public function quoteValue($row)
5962
$null = $this->settings['Null'];
6063
$tabEncode = $this->settings['TabEncode'];
6164

62-
6365
$quote = function($value) use ($enclosure, $delimiter, $encode, $encodeArray, $null, $tabEncode) {
64-
65-
66-
6766
$delimiter_esc = preg_quote($delimiter, '/');
6867

6968
$enclosure_esc = preg_quote($enclosure, '/');
7069

7170
$encode_esc = preg_quote($encode, '/');
7271

73-
$type = gettype($value);
74-
75-
if ($type == 'integer' || $type == 'double') {
76-
return strval($value);
77-
}
78-
79-
if (is_string($value)) {
80-
if ($tabEncode)
81-
{
82-
return str_replace(["\t", "\n"], ['\\t', '\\n'], $value);
83-
}
84-
85-
$value = strval($value);
86-
$value = $this->encodeString($value, $enclosure_esc, $encode_esc);
87-
return $enclosure . $value . $enclosure;
88-
}
89-
9072
if (is_array($value)) {
9173
// Arrays are formatted as a list of values separated by commas in square brackets.
9274
// Elements of the array - the numbers are formatted as usual, and the dates, dates-with-time, and lines are in
9375
// single quotation marks with the same screening rules as above.
9476
// as in the TabSeparated format, and then the resulting string is output in InsertRow in double quotes.
95-
$value = array_map(
77+
$value = array_map(
9678
function ($v) use ($enclosure_esc, $encode_esc) {
9779
return is_string($v) ? $this->encodeString($v, $enclosure_esc, $encode_esc) : $v;
9880
},
9981
$value
10082
);
101-
$result_array = FormatLine::Insert($value);
83+
$resultArray = FormatLine::Insert($value);
84+
85+
return $encodeArray . '[' . $resultArray . ']' . $encodeArray;
86+
}
87+
88+
$value = ValueFormatter::formatValue($value, false);
89+
90+
if (is_float($value) || is_int($value)) {
91+
return (string) $value;
92+
}
10293

103-
return $encodeArray . '[' . $result_array . ']' . $encodeArray;
94+
if (is_string($value)) {
95+
if ($tabEncode) {
96+
return str_replace(["\t", "\n"], ['\\t', '\\n'], $value);
97+
}
98+
99+
$value = $this->encodeString($value, $enclosure_esc, $encode_esc);
100+
101+
return $enclosure . $value . $enclosure;
104102
}
105103

106-
if (null === $value) {
104+
if ($value === null) {
107105
return $null;
108106
}
109107

src/Quote/ValueFormatter.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace ClickHouseDB\Quote;
6+
7+
use ClickHouseDB\Exception\UnsupportedValueType;
8+
use DateTimeInterface;
9+
use function addslashes;
10+
use function is_bool;
11+
use function is_callable;
12+
use function is_float;
13+
use function is_int;
14+
use function is_object;
15+
use function is_string;
16+
use function sprintf;
17+
18+
class ValueFormatter
19+
{
20+
/**
21+
* @param mixed $value
22+
* @return mixed
23+
*/
24+
public static function formatValue($value, bool $addQuotes = true)
25+
{
26+
if ($value instanceof DateTimeInterface) {
27+
$value = $value->format('Y-m-d H:i:s');
28+
}
29+
30+
if (is_float($value) || is_int($value) || is_bool($value) || $value === null) {
31+
return $value;
32+
}
33+
34+
if (is_object($value) && is_callable([$value, '__toString'])) {
35+
$value = (string) $value;
36+
}
37+
38+
if (is_string($value)) {
39+
if ($addQuotes) {
40+
return self::formatStringParameter(self::escapeString($value));
41+
}
42+
43+
return $value;
44+
}
45+
46+
throw UnsupportedValueType::new($value);
47+
}
48+
49+
/**
50+
* Escape an string
51+
*
52+
* @param string $value
53+
* @return string
54+
*/
55+
private static function escapeString($value)
56+
{
57+
return addslashes($value);
58+
}
59+
60+
/**
61+
* @return string
62+
*/
63+
private static function formatStringParameter($value)
64+
{
65+
return sprintf("'%s'", $value);
66+
}
67+
}

tests/BindingsTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
namespace ClickHouseDB\Tests;
44

5-
use ClickHouseDB\Exception\UnsupportedParameterType;
5+
use ClickHouseDB\Exception\UnsupportedValueType;
66
use ClickHouseDB\Query\Degeneration\Bindings;
77
use DateTimeImmutable;
88
use PHPUnit\Framework\TestCase;
99
use function curl_init;
1010

1111
/**
12-
* Class BindingsTest
13-
* @package ClickHouseDB\Tests
1412
* @group BindingsTest
1513
*/
1614
final class BindingsTest extends TestCase
@@ -187,7 +185,7 @@ public function testEscape($sql, $params, $expectedSql)
187185
*/
188186
public function testEscapeFail()
189187
{
190-
$this->expectException(UnsupportedParameterType::class);
188+
$this->expectException(UnsupportedValueType::class);
191189

192190
$bindings = new Bindings();
193191
$bindings->bindParams(['unsupportedParam' => curl_init()]);

tests/ClientTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,27 @@ public function testSqlDisableConditions()
226226

227227
}
228228

229+
public function testInsertNullable()
230+
{
231+
$this->client->write('DROP TABLE IF EXISTS `test`');
232+
$this->client->write('CREATE TABLE `test` (
233+
event_date Date DEFAULT toDate(event_time),
234+
event_time DateTime,
235+
url_hash Nullable(String)
236+
) ENGINE = TinyLog()');
237+
$this->client->insert(
238+
'test',
239+
[
240+
[strtotime('2010-10-10 00:00:00'), null],
241+
],
242+
['event_time', 'url_hash']
243+
);
229244

245+
$statement = $this->client->select('SELECT url_hash FROM `test`');
246+
self::assertCount(1, $statement->rows());
247+
self::assertNull($statement->fetchOne('url_hash'));
248+
249+
}
230250

231251
public function testInsertDotTable()
232252
{
@@ -263,6 +283,7 @@ public function testInsertDotTable()
263283
$this->assertEquals('Хеш', $st->fetchOne('url_hash'));
264284

265285
}
286+
266287
public function testSearchWithCyrillic()
267288
{
268289
$this->create_table_summing_url_views();

0 commit comments

Comments
 (0)