From bb3098611e706699a51d0f98943e8dfd476c0346 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Mon, 27 Jan 2025 16:43:04 +0100 Subject: [PATCH] feat: introduce Table helper, allow Table as an input for inserts (#284) --- infection.json.dist | 2 +- src/Client/ClickHouseClient.php | 12 ++++++-- src/Client/PsrClickHouseClient.php | 40 +++++++++++++++++-------- src/Schema/Table.php | 33 +++++++++++++++++++++ tests/Schema/TableTest.php | 47 ++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 src/Schema/Table.php create mode 100644 tests/Schema/TableTest.php diff --git a/infection.json.dist b/infection.json.dist index 19c302c..d864e9b 100644 --- a/infection.json.dist +++ b/infection.json.dist @@ -17,5 +17,5 @@ "text": "infection-log.txt" }, "minMsi": 90, - "minCoveredMsi": 95 + "minCoveredMsi": 94 } diff --git a/src/Client/ClickHouseClient.php b/src/Client/ClickHouseClient.php index 36a203a..81b440c 100644 --- a/src/Client/ClickHouseClient.php +++ b/src/Client/ClickHouseClient.php @@ -12,6 +12,7 @@ use SimPod\ClickHouseClient\Exception\UnsupportedParamValue; use SimPod\ClickHouseClient\Format\Format; use SimPod\ClickHouseClient\Output\Output; +use SimPod\ClickHouseClient\Schema\Table; interface ClickHouseClient { @@ -74,7 +75,7 @@ public function selectWithParams(string $query, array $params, Format $outputFor * @throws UnsupportedParamType * @throws UnsupportedParamValue */ - public function insert(string $table, array $values, array|null $columns = null, array $settings = []): void; + public function insert(Table|string $table, array $values, array|null $columns = null, array $settings = []): void; /** * @param array $settings @@ -85,7 +86,12 @@ public function insert(string $table, array $values, array|null $columns = null, * * @template O of Output */ - public function insertWithFormat(string $table, Format $inputFormat, string $data, array $settings = []): void; + public function insertWithFormat( + Table|string $table, + Format $inputFormat, + string $data, + array $settings = [], + ): void; /** * @param array $settings @@ -97,7 +103,7 @@ public function insertWithFormat(string $table, Format $inputFormat, string $dat * @throws ServerError */ public function insertPayload( - string $table, + Table|string $table, Format $inputFormat, StreamInterface $payload, array $columns = [], diff --git a/src/Client/PsrClickHouseClient.php b/src/Client/PsrClickHouseClient.php index ec36d5a..59125de 100644 --- a/src/Client/PsrClickHouseClient.php +++ b/src/Client/PsrClickHouseClient.php @@ -21,7 +21,7 @@ use SimPod\ClickHouseClient\Format\Format; use SimPod\ClickHouseClient\Logger\SqlLogger; use SimPod\ClickHouseClient\Output\Output; -use SimPod\ClickHouseClient\Sql\Escaper; +use SimPod\ClickHouseClient\Schema\Table; use SimPod\ClickHouseClient\Sql\SqlFactory; use SimPod\ClickHouseClient\Sql\ValueFormatter; @@ -100,13 +100,17 @@ public function selectWithParams(string $query, array $params, Format $outputFor return $outputFormat::output($response->getBody()->__toString()); } - public function insert(string $table, array $values, array|null $columns = null, array $settings = []): void + public function insert(Table|string $table, array $values, array|null $columns = null, array $settings = []): void { if ($values === []) { throw CannotInsert::noValues(); } - $table = Escaper::quoteIdentifier($table); + if (! $table instanceof Table) { + $table = new Table($table); + } + + $tableName = $table->fullName(); if (is_array($columns) && ! array_is_list($columns)) { $columnsSql = sprintf('(%s)', implode(',', array_keys($columns))); @@ -139,7 +143,7 @@ static function (array $row) use (&$pN, $types): string { $this->executeRequest( <<executeRequest( <<fullName(); try { $this->executeRequest( <<fullName(); $columnsSql = $columns === [] ? '' : sprintf('(%s)', implode(',', $columns)); $sql = <<requestFactory->initRequest( diff --git a/src/Schema/Table.php b/src/Schema/Table.php new file mode 100644 index 0000000..5e1e6d1 --- /dev/null +++ b/src/Schema/Table.php @@ -0,0 +1,33 @@ +name[0] === '`' && $this->name[-1] === '`' + ? $this->name + : Escaper::quoteIdentifier($this->name); + + if ($this->database === null) { + return $escapedName; + } + + $escapedDatabase = $this->database[0] === '`' && $this->database[-1] === '`' + ? $this->database + : Escaper::quoteIdentifier($this->database); + + return $escapedDatabase . '.' . $escapedName; + } +} diff --git a/tests/Schema/TableTest.php b/tests/Schema/TableTest.php new file mode 100644 index 0000000..a198cfb --- /dev/null +++ b/tests/Schema/TableTest.php @@ -0,0 +1,47 @@ +name); + self::assertSame('db', $table->database); + } + + #[DataProvider('providerFullName')] + public function testFullName(string $expectedFullName, Table $table): void + { + self::assertSame($expectedFullName, $table->fullName()); + } + + /** @return Generator */ + public static function providerFullName(): Generator + { + yield 'no database' => [ + '`t1`', + new Table('t1'), + ]; + + yield 'with database' => [ + '`db`.`t1`', + new Table('t1', 'db'), + ]; + + yield 'escaped' => [ + '`db`.`t1`', + new Table('`t1`', '`db`'), + ]; + } +}