Skip to content

Commit 4117fec

Browse files
authored
Merge pull request #6134 from shyim/add-binary-array-type
Add binary array type
2 parents 36a5136 + 504462e commit 4117fec

7 files changed

+404
-6
lines changed

docs/en/reference/data-retrieval-and-manipulation.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,12 @@ SQL injection possibilities if not handled carefully.
253253
Doctrine DBAL implements a very powerful parsing process that will make this kind of prepared
254254
statement possible natively in the binding type system.
255255
The parsing necessarily comes with a performance overhead, but only if you really use a list of parameters.
256-
There are two special binding types that describe a list of integers or strings:
256+
There are four special binding types that describe a list of integers, regular, ascii or binary strings:
257257

258258
- ``\Doctrine\DBAL\ArrayParameterType::INTEGER``
259259
- ``\Doctrine\DBAL\ArrayParameterType::STRING``
260+
- ``\Doctrine\DBAL\ArrayParameterType::ASCII``
261+
- ``\Doctrine\DBAL\ArrayParameterType::BINARY``
260262

261263
Using one of these constants as a type you can activate the SQLParser inside Doctrine that rewrites
262264
the SQL and flattens the specified values into the set of parameters. Consider our previous example:

src/ArrayParameterType.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@ final class ArrayParameterType
1919
*/
2020
public const ASCII = ParameterType::ASCII + Connection::ARRAY_PARAM_OFFSET;
2121

22+
/**
23+
* Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
24+
*/
25+
public const BINARY = ParameterType::BINARY + Connection::ARRAY_PARAM_OFFSET;
26+
2227
/**
2328
* @internal
2429
*
2530
* @psalm-param self::* $type
2631
*
27-
* @psalm-return ParameterType::INTEGER|ParameterType::STRING|ParameterType::ASCII
32+
* @psalm-return ParameterType::INTEGER|ParameterType::STRING|ParameterType::ASCII|ParameterType::BINARY
2833
*/
2934
public static function toElementParameterType(int $type): int
3035
{

src/Connection.php

+1
Original file line numberDiff line numberDiff line change
@@ -1919,6 +1919,7 @@ private function needsArrayParameterConversion(array $params, array $types): boo
19191919
$type === ArrayParameterType::INTEGER
19201920
|| $type === ArrayParameterType::STRING
19211921
|| $type === ArrayParameterType::ASCII
1922+
|| $type === ArrayParameterType::BINARY
19221923
) {
19231924
return true;
19241925
}

src/ExpandArrayParameters.php

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ private function acceptParameter($key, $value): void
101101
$type !== ArrayParameterType::INTEGER
102102
&& $type !== ArrayParameterType::STRING
103103
&& $type !== ArrayParameterType::ASCII
104+
&& $type !== ArrayParameterType::BINARY
104105
) {
105106
$this->appendTypedParameter([$value], $type);
106107

tests/Connection/ExpandArrayParametersTest.php

+32-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Doctrine\DBAL\Types\Type;
1212
use PHPUnit\Framework\TestCase;
1313

14+
use function hex2bin;
15+
1416
class ExpandArrayParametersTest extends TestCase
1517
{
1618
/** @return mixed[][] */
@@ -94,16 +96,24 @@ public static function dataExpandListParameters(): iterable
9496
[1 => ParameterType::STRING, 2 => ParameterType::STRING],
9597
],
9698
'Positional: explicit keys for array params and array types' => [
97-
'SELECT * FROM Foo WHERE foo IN (?) AND bar IN (?) AND baz = ? AND bax IN (?)',
98-
[1 => ['bar1', 'bar2'], 2 => true, 0 => [1, 2, 3], ['bax1', 'bax2']],
99+
'SELECT * FROM Foo WHERE foo IN (?) AND bar IN (?) AND baz = ? AND bax IN (?) AND bay IN (?)',
100+
[
101+
1 => ['bar1', 'bar2'],
102+
2 => true,
103+
0 => [1, 2, 3],
104+
['bax1', 'bax2'],
105+
4 => [hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
106+
],
99107
[
108+
4 => ArrayParameterType::BINARY,
100109
3 => ArrayParameterType::ASCII,
101110
2 => ParameterType::BOOLEAN,
102111
1 => ArrayParameterType::STRING,
103112
0 => ArrayParameterType::INTEGER,
104113
],
105-
'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND bar IN (?, ?) AND baz = ? AND bax IN (?, ?)',
106-
[1, 2, 3, 'bar1', 'bar2', true, 'bax1', 'bax2'],
114+
'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND bar IN (?, ?) AND baz = ? AND bax IN (?, ?) ' .
115+
'AND bay IN (?, ?)',
116+
[1, 2, 3, 'bar1', 'bar2', true, 'bax1', 'bax2', hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
107117
[
108118
ParameterType::INTEGER,
109119
ParameterType::INTEGER,
@@ -113,6 +123,8 @@ public static function dataExpandListParameters(): iterable
113123
ParameterType::BOOLEAN,
114124
ParameterType::ASCII,
115125
ParameterType::ASCII,
126+
ParameterType::BINARY,
127+
ParameterType::BINARY,
116128
],
117129
],
118130
'Named: Very simple with param int' => [
@@ -310,6 +322,22 @@ public static function dataExpandListParameters(): iterable
310322
['foo', 'bar', 'baz'],
311323
[1 => ParameterType::STRING, ParameterType::STRING],
312324
],
325+
'Named: Binary array with explicit types' => [
326+
'SELECT * FROM Foo WHERE foo IN (:foo) OR bar IN (:bar)',
327+
[
328+
'foo' => [hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
329+
'bar' => [hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
330+
],
331+
['foo' => ArrayParameterType::BINARY, 'bar' => ArrayParameterType::BINARY],
332+
'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar IN (?, ?)',
333+
[hex2bin('DEADBEEF'), hex2bin('C0DEF00D'), hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
334+
[
335+
ParameterType::BINARY,
336+
ParameterType::BINARY,
337+
ParameterType::BINARY,
338+
ParameterType::BINARY,
339+
],
340+
],
313341
];
314342
}
315343

0 commit comments

Comments
 (0)