Skip to content

Commit bb30986

Browse files
authored
feat: introduce Table helper, allow Table as an input for inserts (#284)
1 parent 15c9856 commit bb30986

File tree

5 files changed

+118
-16
lines changed

5 files changed

+118
-16
lines changed

infection.json.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
"text": "infection-log.txt"
1818
},
1919
"minMsi": 90,
20-
"minCoveredMsi": 95
20+
"minCoveredMsi": 94
2121
}

src/Client/ClickHouseClient.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use SimPod\ClickHouseClient\Exception\UnsupportedParamValue;
1313
use SimPod\ClickHouseClient\Format\Format;
1414
use SimPod\ClickHouseClient\Output\Output;
15+
use SimPod\ClickHouseClient\Schema\Table;
1516

1617
interface ClickHouseClient
1718
{
@@ -74,7 +75,7 @@ public function selectWithParams(string $query, array $params, Format $outputFor
7475
* @throws UnsupportedParamType
7576
* @throws UnsupportedParamValue
7677
*/
77-
public function insert(string $table, array $values, array|null $columns = null, array $settings = []): void;
78+
public function insert(Table|string $table, array $values, array|null $columns = null, array $settings = []): void;
7879

7980
/**
8081
* @param array<string, float|int|string> $settings
@@ -85,7 +86,12 @@ public function insert(string $table, array $values, array|null $columns = null,
8586
*
8687
* @template O of Output
8788
*/
88-
public function insertWithFormat(string $table, Format $inputFormat, string $data, array $settings = []): void;
89+
public function insertWithFormat(
90+
Table|string $table,
91+
Format $inputFormat,
92+
string $data,
93+
array $settings = [],
94+
): void;
8995

9096
/**
9197
* @param array<string, float|int|string> $settings
@@ -97,7 +103,7 @@ public function insertWithFormat(string $table, Format $inputFormat, string $dat
97103
* @throws ServerError
98104
*/
99105
public function insertPayload(
100-
string $table,
106+
Table|string $table,
101107
Format $inputFormat,
102108
StreamInterface $payload,
103109
array $columns = [],

src/Client/PsrClickHouseClient.php

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
use SimPod\ClickHouseClient\Format\Format;
2222
use SimPod\ClickHouseClient\Logger\SqlLogger;
2323
use SimPod\ClickHouseClient\Output\Output;
24-
use SimPod\ClickHouseClient\Sql\Escaper;
24+
use SimPod\ClickHouseClient\Schema\Table;
2525
use SimPod\ClickHouseClient\Sql\SqlFactory;
2626
use SimPod\ClickHouseClient\Sql\ValueFormatter;
2727

@@ -100,13 +100,17 @@ public function selectWithParams(string $query, array $params, Format $outputFor
100100
return $outputFormat::output($response->getBody()->__toString());
101101
}
102102

103-
public function insert(string $table, array $values, array|null $columns = null, array $settings = []): void
103+
public function insert(Table|string $table, array $values, array|null $columns = null, array $settings = []): void
104104
{
105105
if ($values === []) {
106106
throw CannotInsert::noValues();
107107
}
108108

109-
$table = Escaper::quoteIdentifier($table);
109+
if (! $table instanceof Table) {
110+
$table = new Table($table);
111+
}
112+
113+
$tableName = $table->fullName();
110114

111115
if (is_array($columns) && ! array_is_list($columns)) {
112116
$columnsSql = sprintf('(%s)', implode(',', array_keys($columns)));
@@ -139,7 +143,7 @@ static function (array $row) use (&$pN, $types): string {
139143

140144
$this->executeRequest(
141145
<<<CLICKHOUSE
142-
INSERT INTO $table
146+
INSERT INTO $tableName
143147
$columnsSql
144148
VALUES $valuesSql
145149
CLICKHOUSE,
@@ -174,7 +178,7 @@ static function (array $row) use (&$pN, $types): string {
174178
try {
175179
$this->executeRequest(
176180
<<<CLICKHOUSE
177-
INSERT INTO $table
181+
INSERT INTO $tableName
178182
$columnsSql
179183
VALUES $valuesSql
180184
CLICKHOUSE,
@@ -186,16 +190,24 @@ static function (array $row) use (&$pN, $types): string {
186190
}
187191
}
188192

189-
public function insertWithFormat(string $table, Format $inputFormat, string $data, array $settings = []): void
190-
{
193+
public function insertWithFormat(
194+
Table|string $table,
195+
Format $inputFormat,
196+
string $data,
197+
array $settings = [],
198+
): void {
191199
$formatSql = $inputFormat::toSql();
192200

193-
$table = Escaper::quoteIdentifier($table);
201+
if (! $table instanceof Table) {
202+
$table = new Table($table);
203+
}
204+
205+
$tableName = $table->fullName();
194206

195207
try {
196208
$this->executeRequest(
197209
<<<CLICKHOUSE
198-
INSERT INTO $table $formatSql $data
210+
INSERT INTO $tableName $formatSql $data
199211
CLICKHOUSE,
200212
params: [],
201213
settings: $settings,
@@ -206,7 +218,7 @@ public function insertWithFormat(string $table, Format $inputFormat, string $dat
206218
}
207219

208220
public function insertPayload(
209-
string $table,
221+
Table|string $table,
210222
Format $inputFormat,
211223
StreamInterface $payload,
212224
array $columns = [],
@@ -218,12 +230,16 @@ public function insertPayload(
218230

219231
$formatSql = $inputFormat::toSql();
220232

221-
$table = Escaper::quoteIdentifier($table);
233+
if (! $table instanceof Table) {
234+
$table = new Table($table);
235+
}
236+
237+
$tableName = $table->fullName();
222238

223239
$columnsSql = $columns === [] ? '' : sprintf('(%s)', implode(',', $columns));
224240

225241
$sql = <<<CLICKHOUSE
226-
INSERT INTO $table $columnsSql $formatSql
242+
INSERT INTO $tableName $columnsSql $formatSql
227243
CLICKHOUSE;
228244

229245
$request = $this->requestFactory->initRequest(

src/Schema/Table.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimPod\ClickHouseClient\Schema;
6+
7+
use SimPod\ClickHouseClient\Sql\Escaper;
8+
9+
final readonly class Table
10+
{
11+
public function __construct(
12+
public string $name,
13+
public string|null $database = null,
14+
) {
15+
}
16+
17+
public function fullName(): string
18+
{
19+
$escapedName = $this->name[0] === '`' && $this->name[-1] === '`'
20+
? $this->name
21+
: Escaper::quoteIdentifier($this->name);
22+
23+
if ($this->database === null) {
24+
return $escapedName;
25+
}
26+
27+
$escapedDatabase = $this->database[0] === '`' && $this->database[-1] === '`'
28+
? $this->database
29+
: Escaper::quoteIdentifier($this->database);
30+
31+
return $escapedDatabase . '.' . $escapedName;
32+
}
33+
}

tests/Schema/TableTest.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimPod\ClickHouseClient\Tests\Schema;
6+
7+
use Generator;
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\Attributes\DataProvider;
10+
use SimPod\ClickHouseClient\Schema\Table;
11+
use SimPod\ClickHouseClient\Tests\TestCaseBase;
12+
13+
#[CoversClass(Table::class)]
14+
final class TableTest extends TestCaseBase
15+
{
16+
public function testConstruct(): void
17+
{
18+
$table = new Table('t1', 'db');
19+
self::assertSame('t1', $table->name);
20+
self::assertSame('db', $table->database);
21+
}
22+
23+
#[DataProvider('providerFullName')]
24+
public function testFullName(string $expectedFullName, Table $table): void
25+
{
26+
self::assertSame($expectedFullName, $table->fullName());
27+
}
28+
29+
/** @return Generator<string, array{string, Table}> */
30+
public static function providerFullName(): Generator
31+
{
32+
yield 'no database' => [
33+
'`t1`',
34+
new Table('t1'),
35+
];
36+
37+
yield 'with database' => [
38+
'`db`.`t1`',
39+
new Table('t1', 'db'),
40+
];
41+
42+
yield 'escaped' => [
43+
'`db`.`t1`',
44+
new Table('`t1`', '`db`'),
45+
];
46+
}
47+
}

0 commit comments

Comments
 (0)