From ee5c7db75e7af80be7ee56d5716d6cdf97976492 Mon Sep 17 00:00:00 2001 From: Yancharuk Alexander Date: Mon, 1 Jul 2019 14:15:45 +0300 Subject: [PATCH] fix: Implement ability to bind values for arrays Implement binding for Connection::PARAM_INT_ARRAY and Connection::PARAM_STR_ARRAY types --- README.md | 16 ++++++++++++++++ src/ClickHouseStatement.php | 9 +++++++++ tests/SelectTest.php | 22 ++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/README.md b/README.md index e559ab8..2b1903b 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,22 @@ while ($row = $stmt->fetch()) { } ``` +### Select using placeholders with arrays as values +```php +$stmt = $conn->prepare('SELECT authorId FROM articles WHERE categoryId IN (:categoryIds)'); + +$stmt->bindValue('categoryIds', [123, 124], \Doctrine\DBAL\Connection::PARAM_INT_ARRAY); +$stmt->execute(); +$result = $stmt->fetchAll(); +``` +```php +$stmt = $conn->prepare('SELECT authorId FROM articles WHERE categoryName IN (:categoryNames)'); + +$stmt->bindValue('categoryNames', ['Auto', 'News'], \Doctrine\DBAL\Connection::PARAM_STR_ARRAY); +$stmt->execute(); +$result = $stmt->fetchAll(); +``` + ### Additional types If you want to use [Array(T) type](https://clickhouse.yandex/reference_en.html#Array(T)), register additional DBAL types in your code: diff --git a/src/ClickHouseStatement.php b/src/ClickHouseStatement.php index 9587257..7343d63 100644 --- a/src/ClickHouseStatement.php +++ b/src/ClickHouseStatement.php @@ -15,6 +15,7 @@ namespace FOD\DBALClickHouse; use ClickHouseDB\Client; +use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\FetchMode; use Doctrine\DBAL\ParameterType; @@ -387,6 +388,14 @@ function ($value) : void { return (string) (int) (bool) $this->values[$key]; } + if ($type === Connection::PARAM_INT_ARRAY) { + return implode(',', $this->values[$key]); + } + + if ($type === Connection::PARAM_STR_ARRAY) { + return "'" . implode("','", $this->values[$key]) . "'"; + } + return $this->platform->quoteStringLiteral((string) $this->values[$key]); } } diff --git a/tests/SelectTest.php b/tests/SelectTest.php index 52e1dba..c50649b 100644 --- a/tests/SelectTest.php +++ b/tests/SelectTest.php @@ -284,5 +284,27 @@ public function testTrimChar() $this->assertEquals('t2', $stmt->fetchColumn()); } + + public function testStatementSelectWithBindingIntegersArray(): void + { + $statement = $this->connection->prepare('INSERT INTO test_select_table(id, payload) VALUES (:v0, :v1), (:v2, :v3)'); + $statement->execute(['v0' => 11, 'v1' => 'v?11', 'v2' => 12, 'v3' => 'v12']); + + $statement = $this->connection->prepare('SELECT payload from test_select_table WHERE id IN (:array) ORDER BY id'); + $statement->bindValue('array', [11, 12], Connection::PARAM_INT_ARRAY); + $statement->execute(); + $this->assertEquals([['payload' => 'v?11'], ['payload' => 'v12']], $statement->fetchAll()); + } + + public function testStatementSelectWithBindingStringsArray(): void + { + $statement = $this->connection->prepare('INSERT INTO test_select_table(id, payload) VALUES (:v0, :v1), (:v2, :v3)'); + $statement->execute(['v0' => 13, 'v1' => 'v?13', 'v2' => 14, 'v3' => 'v14']); + + $statement = $this->connection->prepare('SELECT id from test_select_table WHERE payload IN (:array) ORDER BY id'); + $statement->bindValue('array', ['v?13', 'v14'], Connection::PARAM_STR_ARRAY); + $statement->execute(); + $this->assertEquals([['id' => 13], ['id' => 14]], $statement->fetchAll()); + } }