Skip to content

Commit

Permalink
Merge branch '3.7.x' into 4.0.x
Browse files Browse the repository at this point in the history
* 3.7.x:
  Fix IBM DB2 tests
  Implement binary array parameter type
  • Loading branch information
derrabus committed Aug 28, 2023
2 parents 9128251 + 4117fec commit 5e696a0
Show file tree
Hide file tree
Showing 5 changed files with 402 additions and 5 deletions.
4 changes: 3 additions & 1 deletion docs/en/reference/data-retrieval-and-manipulation.rst
Expand Up @@ -253,10 +253,12 @@ SQL injection possibilities if not handled carefully.
Doctrine DBAL implements a very powerful parsing process that will make this kind of prepared
statement possible natively in the binding type system.
The parsing necessarily comes with a performance overhead, but only if you really use a list of parameters.
There are two special binding types that describe a list of integers or strings:
There are four special binding types that describe a list of integers, regular, ascii or binary strings:

- ``\Doctrine\DBAL\ArrayParameterType::INTEGER``
- ``\Doctrine\DBAL\ArrayParameterType::STRING``
- ``\Doctrine\DBAL\ArrayParameterType::ASCII``
- ``\Doctrine\DBAL\ArrayParameterType::BINARY``

Using one of these constants as a type you can activate the SQLParser inside Doctrine that rewrites
the SQL and flattens the specified values into the set of parameters. Consider our previous example:
Expand Down
6 changes: 6 additions & 0 deletions src/ArrayParameterType.php
Expand Up @@ -21,13 +21,19 @@ enum ArrayParameterType
*/
case ASCII;

/**
* Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
*/
case BINARY;

/** @internal */
public static function toElementParameterType(self $type): ParameterType
{
return match ($type) {
self::INTEGER => ParameterType::INTEGER,
self::STRING => ParameterType::STRING,
self::ASCII => ParameterType::ASCII,
self::BINARY => ParameterType::BINARY,
};
}
}
36 changes: 32 additions & 4 deletions tests/Connection/ExpandArrayParametersTest.php
Expand Up @@ -14,6 +14,8 @@
use Doctrine\DBAL\Types\Type;
use PHPUnit\Framework\TestCase;

use function hex2bin;

/** @psalm-import-type WrapperParameterTypeArray from Connection */
class ExpandArrayParametersTest extends TestCase
{
Expand Down Expand Up @@ -107,16 +109,24 @@ public static function dataExpandListParameters(): iterable
[1 => ParameterType::STRING, 2 => ParameterType::STRING],
],
'Positional: explicit keys for array params and array types' => [
'SELECT * FROM Foo WHERE foo IN (?) AND bar IN (?) AND baz = ? AND bax IN (?)',
[1 => ['bar1', 'bar2'], 2 => true, 0 => [1, 2, 3], ['bax1', 'bax2']],
'SELECT * FROM Foo WHERE foo IN (?) AND bar IN (?) AND baz = ? AND bax IN (?) AND bay IN (?)',
[
1 => ['bar1', 'bar2'],
2 => true,
0 => [1, 2, 3],
['bax1', 'bax2'],
4 => [hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
],
[
4 => ArrayParameterType::BINARY,
3 => ArrayParameterType::ASCII,
2 => ParameterType::BOOLEAN,
1 => ArrayParameterType::STRING,
0 => ArrayParameterType::INTEGER,
],
'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND bar IN (?, ?) AND baz = ? AND bax IN (?, ?)',
[1, 2, 3, 'bar1', 'bar2', true, 'bax1', 'bax2'],
'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND bar IN (?, ?) AND baz = ? AND bax IN (?, ?) ' .
'AND bay IN (?, ?)',
[1, 2, 3, 'bar1', 'bar2', true, 'bax1', 'bax2', hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
[
ParameterType::INTEGER,
ParameterType::INTEGER,
Expand All @@ -126,6 +136,8 @@ public static function dataExpandListParameters(): iterable
ParameterType::BOOLEAN,
ParameterType::ASCII,
ParameterType::ASCII,
ParameterType::BINARY,
ParameterType::BINARY,
],
],
'Named: Very simple with param int' => [
Expand Down Expand Up @@ -323,6 +335,22 @@ public static function dataExpandListParameters(): iterable
['foo', 'bar', 'baz'],
[1 => ParameterType::STRING, ParameterType::STRING],
],
'Named: Binary array with explicit types' => [
'SELECT * FROM Foo WHERE foo IN (:foo) OR bar IN (:bar)',
[
'foo' => [hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
'bar' => [hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
],
['foo' => ArrayParameterType::BINARY, 'bar' => ArrayParameterType::BINARY],
'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar IN (?, ?)',
[hex2bin('DEADBEEF'), hex2bin('C0DEF00D'), hex2bin('DEADBEEF'), hex2bin('C0DEF00D')],
[
ParameterType::BINARY,
ParameterType::BINARY,
ParameterType::BINARY,
ParameterType::BINARY,
],
],
];
}

Expand Down

0 comments on commit 5e696a0

Please sign in to comment.