Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a ArrayParameterType enum #5838

Merged
merged 1 commit into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Introduce a ArrayParameterType enum
  • Loading branch information
derrabus committed Dec 29, 2022
commit c6bdad1b3dd06c08c60a55a7e208bcb7ca48c2ce
7 changes: 7 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ awareness about deprecated code.
- Use of our low-overhead runtime deprecation API, details:
https://github.com/doctrine/deprecations/

# Upgrade to 3.6

## Deprecated `Connection::PARAM_*_ARRAY` constants

Use the corresponding constants on `ArrayParameterType` instead. Please be aware that
`ArrayParameterType` will be a native enum type in DBAL 4.

# Upgrade to 3.5

## Deprecated extension via Doctrine Event Manager
Expand Down
8 changes: 4 additions & 4 deletions docs/en/reference/data-retrieval-and-manipulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@ 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:

- ``\Doctrine\DBAL\Connection::PARAM_INT_ARRAY``
- ``\Doctrine\DBAL\Connection::PARAM_STR_ARRAY``
- ``\Doctrine\DBAL\ArrayParameterType::INTEGER``
- ``\Doctrine\DBAL\ArrayParameterType::STRING``

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 All @@ -261,7 +261,7 @@ the SQL and flattens the specified values into the set of parameters. Consider o
<?php
$stmt = $conn->executeQuery('SELECT * FROM articles WHERE id IN (?)',
[[1, 2, 3, 4, 5, 6]],
[\Doctrine\DBAL\Connection::PARAM_INT_ARRAY]
[\Doctrine\DBAL\ArrayParameterType::INTEGER]
);

The SQL statement passed to ``Connection#executeQuery`` is not the one actually passed to the
Expand All @@ -271,7 +271,7 @@ be specified as well:
.. code-block:: php

<?php
// Same SQL WITHOUT usage of Doctrine\DBAL\Connection::PARAM_INT_ARRAY
// Same SQL WITHOUT usage of Doctrine\DBAL\ArrayParameterType::INTEGER
$stmt = $conn->executeQuery('SELECT * FROM articles WHERE id IN (?, ?, ?, ?, ?, ?)',
[1, 2, 3, 4, 5, 6],
[
Expand Down
42 changes: 42 additions & 0 deletions src/ArrayParameterType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Doctrine\DBAL;

final class ArrayParameterType
{
/**
* Represents an array of ints to be expanded by Doctrine SQL parsing.
*/
public const INTEGER = ParameterType::INTEGER + self::ARRAY_PARAM_OFFSET;

/**
* Represents an array of strings to be expanded by Doctrine SQL parsing.
*/
public const STRING = ParameterType::STRING + self::ARRAY_PARAM_OFFSET;

/**
* Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
*/
public const ASCII = ParameterType::ASCII + self::ARRAY_PARAM_OFFSET;

/**
* Offset by which PARAM_* constants are detected as arrays of the param type.
*/
private const ARRAY_PARAM_OFFSET = 100;

/**
* @internal
*
* @psalm-param self::INTEGER|self::STRING|self::ASCII $type
*
* @psalm-return ParameterType::INTEGER|ParameterType::STRING|ParameterType::ASCII
*/
public static function toElementParameterType(int $type): int
{
return $type - self::ARRAY_PARAM_OFFSET;
}

private function __construct()
{
}
}
23 changes: 11 additions & 12 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,24 @@ class Connection
{
/**
* Represents an array of ints to be expanded by Doctrine SQL parsing.
*
* @deprecated Use {@see ArrayParameterType::INTEGER} instead.
*/
public const PARAM_INT_ARRAY = ParameterType::INTEGER + self::ARRAY_PARAM_OFFSET;
public const PARAM_INT_ARRAY = ArrayParameterType::INTEGER;

/**
* Represents an array of strings to be expanded by Doctrine SQL parsing.
*
* @deprecated Use {@see ArrayParameterType::STRING} instead.
*/
public const PARAM_STR_ARRAY = ParameterType::STRING + self::ARRAY_PARAM_OFFSET;
public const PARAM_STR_ARRAY = ArrayParameterType::STRING;

/**
* Represents an array of ascii strings to be expanded by Doctrine SQL parsing.
*/
public const PARAM_ASCII_STR_ARRAY = ParameterType::ASCII + self::ARRAY_PARAM_OFFSET;

/**
* Offset by which PARAM_* constants are detected as arrays of the param type.
*
* @internal Should be used only within the wrapper layer.
* @deprecated Use {@see ArrayParameterType::ASCII} instead.
*/
public const ARRAY_PARAM_OFFSET = 100;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this removal because it's internal. How do others see this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Favorably

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ORM seems use it #5837 (comment) and if doctrine/dbal and doctrine/orm is not a match it will fail. So for bc reasons when I think it need to be kept if somebody is only updating doctrine/dbal and not doctrine/orm. Else doctrine/dbal 3.6.0 would require to set a conflict to all doctrine/orm versions lower than a supported version that version to avoid that older none compatible orm versino is used, setting requirement on doctrine/orm side would not work as current orm version already supports ^3.6.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll restore the constant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@derrabus Thank you!

public const PARAM_ASCII_STR_ARRAY = ArrayParameterType::ASCII;

/**
* The wrapped driver connection.
Expand Down Expand Up @@ -1888,9 +1887,9 @@ private function needsArrayParameterConversion(array $params, array $types): boo

foreach ($types as $type) {
if (
$type === self::PARAM_INT_ARRAY
|| $type === self::PARAM_STR_ARRAY
|| $type === self::PARAM_ASCII_STR_ARRAY
$type === ArrayParameterType::INTEGER
|| $type === ArrayParameterType::STRING
|| $type === ArrayParameterType::ASCII
) {
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions src/ExpandArrayParameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ private function acceptParameter($key, $value): void
$type = $this->originalTypes[$key];

if (
$type !== Connection::PARAM_INT_ARRAY
&& $type !== Connection::PARAM_STR_ARRAY
&& $type !== Connection::PARAM_ASCII_STR_ARRAY
$type !== ArrayParameterType::INTEGER
&& $type !== ArrayParameterType::STRING
&& $type !== ArrayParameterType::ASCII
) {
$this->appendTypedParameter([$value], $type);

Expand All @@ -113,7 +113,7 @@ private function acceptParameter($key, $value): void
return;
}

$this->appendTypedParameter($value, $type - Connection::ARRAY_PARAM_OFFSET);
$this->appendTypedParameter($value, ArrayParameterType::toElementParameterType($type));
}

/** @return array<int,Type|int|string|null> */
Expand Down
50 changes: 25 additions & 25 deletions tests/Connection/ExpandArrayParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Doctrine\DBAL\ArrayParameters\Exception\MissingNamedParameter;
use Doctrine\DBAL\ArrayParameters\Exception\MissingPositionalParameter;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\ExpandArrayParameters;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\SQL\Parser;
Expand All @@ -20,31 +20,31 @@ public static function dataExpandListParameters(): iterable
'Positional: Very simple with one needle' => [
'SELECT * FROM Foo WHERE foo IN (?)',
[[1, 2, 3]],
[Connection::PARAM_INT_ARRAY],
[ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (?, ?, ?)',
[1, 2, 3],
[ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER],
],
'Positional: One non-list before d one after list-needle' => [
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?)',
['string', [1, 2, 3]],
[ParameterType::STRING, Connection::PARAM_INT_ARRAY],
[ParameterType::STRING, ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)',
['string', 1, 2, 3],
[ParameterType::STRING, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER],
],
'Positional: One non-list after list-needle' => [
'SELECT * FROM Foo WHERE bar IN (?) AND baz = ?',
[[1, 2, 3], 'foo'],
[Connection::PARAM_INT_ARRAY, ParameterType::STRING],
[ArrayParameterType::INTEGER, ParameterType::STRING],
'SELECT * FROM Foo WHERE bar IN (?, ?, ?) AND baz = ?',
[1, 2, 3, 'foo'],
[ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING],
],
'Positional: One non-list before and one after list-needle' => [
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?) AND baz = ?',
[1, [1, 2, 3], 4],
[ParameterType::INTEGER, Connection::PARAM_INT_ARRAY, ParameterType::INTEGER],
[ParameterType::INTEGER, ArrayParameterType::INTEGER, ParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ?',
[1, 1, 2, 3, 4],
[
Expand All @@ -58,7 +58,7 @@ public static function dataExpandListParameters(): iterable
'Positional: Two lists' => [
'SELECT * FROM Foo WHERE foo IN (?, ?)',
[[1, 2, 3], [4, 5]],
[Connection::PARAM_INT_ARRAY, Connection::PARAM_INT_ARRAY],
[ArrayParameterType::INTEGER, ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)',
[1, 2, 3, 4, 5],
[
Expand All @@ -72,15 +72,15 @@ public static function dataExpandListParameters(): iterable
'Positional: Empty "integer" array (DDC-1978)' => [
'SELECT * FROM Foo WHERE foo IN (?)',
[[]],
[Connection::PARAM_INT_ARRAY],
[ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (NULL)',
[],
[],
],
'Positional: Empty "str" array (DDC-1978)' => [
'SELECT * FROM Foo WHERE foo IN (?)',
[[]],
[Connection::PARAM_STR_ARRAY],
[ArrayParameterType::STRING],
'SELECT * FROM Foo WHERE foo IN (NULL)',
[],
[],
Expand All @@ -97,10 +97,10 @@ public static function dataExpandListParameters(): iterable
'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']],
[
3 => Connection::PARAM_ASCII_STR_ARRAY,
3 => ArrayParameterType::ASCII,
2 => ParameterType::BOOLEAN,
1 => Connection::PARAM_STR_ARRAY,
0 => Connection::PARAM_INT_ARRAY,
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'],
Expand Down Expand Up @@ -134,23 +134,23 @@ public static function dataExpandListParameters(): iterable
'Named: Very simple with one needle' => [
'SELECT * FROM Foo WHERE foo IN (:foo)',
['foo' => [1, 2, 3]],
['foo' => Connection::PARAM_INT_ARRAY],
['foo' => ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (?, ?, ?)',
[1, 2, 3],
[ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER],
],
'Named: One non-list before d one after list-needle' => [
'SELECT * FROM Foo WHERE foo = :foo AND bar IN (:bar)',
['foo' => 'string', 'bar' => [1, 2, 3]],
['foo' => ParameterType::STRING, 'bar' => Connection::PARAM_INT_ARRAY],
['foo' => ParameterType::STRING, 'bar' => ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?)',
['string', 1, 2, 3],
[ParameterType::STRING, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER],
],
'Named: One non-list after list-needle' => [
'SELECT * FROM Foo WHERE bar IN (:bar) AND baz = :baz',
['bar' => [1, 2, 3], 'baz' => 'foo'],
['bar' => Connection::PARAM_INT_ARRAY, 'baz' => ParameterType::STRING],
['bar' => ArrayParameterType::INTEGER, 'baz' => ParameterType::STRING],
'SELECT * FROM Foo WHERE bar IN (?, ?, ?) AND baz = ?',
[1, 2, 3, 'foo'],
[ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::INTEGER, ParameterType::STRING],
Expand All @@ -159,7 +159,7 @@ public static function dataExpandListParameters(): iterable
'SELECT * FROM Foo WHERE foo = :foo AND bar IN (:bar) AND baz = :baz',
['bar' => [1, 2, 3],'foo' => 1, 'baz' => 4],
[
'bar' => Connection::PARAM_INT_ARRAY,
'bar' => ArrayParameterType::INTEGER,
'foo' => ParameterType::INTEGER,
'baz' => ParameterType::INTEGER,
],
Expand All @@ -176,7 +176,7 @@ public static function dataExpandListParameters(): iterable
'Named: Two lists' => [
'SELECT * FROM Foo WHERE foo IN (:a, :b)',
['b' => [4, 5],'a' => [1, 2, 3]],
['a' => Connection::PARAM_INT_ARRAY, 'b' => Connection::PARAM_INT_ARRAY],
['a' => ArrayParameterType::INTEGER, 'b' => ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (?, ?, ?, ?, ?)',
[1, 2, 3, 4, 5],
[
Expand All @@ -198,7 +198,7 @@ public static function dataExpandListParameters(): iterable
'Named: With the same name arg' => [
'SELECT * FROM Foo WHERE foo IN (:arg) AND NOT bar IN (:arg)',
['arg' => [1, 2, 3]],
['arg' => Connection::PARAM_INT_ARRAY],
['arg' => ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND NOT bar IN (?, ?, ?)',
[1, 2, 3, 1, 2, 3],
[
Expand All @@ -221,31 +221,31 @@ public static function dataExpandListParameters(): iterable
'Named: Empty "integer" array (DDC-1978)' => [
'SELECT * FROM Foo WHERE foo IN (:foo)',
['foo' => []],
['foo' => Connection::PARAM_INT_ARRAY],
['foo' => ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (NULL)',
[],
[],
],
'Named: Two empty "str" array (DDC-1978)' => [
'SELECT * FROM Foo WHERE foo IN (:foo) OR bar IN (:bar)',
['foo' => [], 'bar' => []],
['foo' => Connection::PARAM_STR_ARRAY, 'bar' => Connection::PARAM_STR_ARRAY],
['foo' => ArrayParameterType::STRING, 'bar' => ArrayParameterType::STRING],
'SELECT * FROM Foo WHERE foo IN (NULL) OR bar IN (NULL)',
[],
[],
],
[
'SELECT * FROM Foo WHERE foo IN (:foo) OR bar IN (:bar)',
['foo' => [], 'bar' => []],
['foo' => Connection::PARAM_ASCII_STR_ARRAY, 'bar' => Connection::PARAM_ASCII_STR_ARRAY],
['foo' => ArrayParameterType::ASCII, 'bar' => ArrayParameterType::ASCII],
'SELECT * FROM Foo WHERE foo IN (NULL) OR bar IN (NULL)',
[],
[],
],
[
'SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar OR baz = :baz',
['foo' => [1, 2], 'bar' => 'bar', 'baz' => 'baz'],
['foo' => Connection::PARAM_INT_ARRAY, 'baz' => 'string'],
['foo' => ArrayParameterType::INTEGER, 'baz' => 'string'],
'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ? OR baz = ?',
[1, 2, 'bar', 'baz'],
[
Expand All @@ -257,7 +257,7 @@ public static function dataExpandListParameters(): iterable
[
'SELECT * FROM Foo WHERE foo IN (:foo) OR bar = :bar',
['foo' => [1, 2], 'bar' => 'bar'],
['foo' => Connection::PARAM_INT_ARRAY],
['foo' => ArrayParameterType::INTEGER],
'SELECT * FROM Foo WHERE foo IN (?, ?) OR bar = ?',
[1, 2, 'bar'],
[ParameterType::INTEGER, ParameterType::INTEGER],
Expand Down Expand Up @@ -305,7 +305,7 @@ public static function dataExpandListParameters(): iterable
[
'SELECT NULL FROM dummy WHERE ? IN (?)',
['foo', ['bar', 'baz']],
[1 => Connection::PARAM_STR_ARRAY],
[1 => ArrayParameterType::STRING],
'SELECT NULL FROM dummy WHERE ? IN (?, ?)',
['foo', 'bar', 'baz'],
[1 => ParameterType::STRING, ParameterType::STRING],
Expand Down Expand Up @@ -353,12 +353,12 @@ public static function missingNamedParameterProvider(): iterable
[
'SELECT * FROM foo WHERE bar = :param',
[],
['bar' => Connection::PARAM_INT_ARRAY],
['bar' => ArrayParameterType::INTEGER],
],
[
'SELECT * FROM foo WHERE bar = :param',
['bar' => 'value'],
['bar' => Connection::PARAM_INT_ARRAY],
['bar' => ArrayParameterType::INTEGER],
],
];
}
Expand Down
6 changes: 3 additions & 3 deletions tests/Functional/DataAccessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Doctrine\DBAL\Tests\Functional;

use DateTime;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Platforms\TrimMode;
Expand Down Expand Up @@ -306,7 +306,7 @@ public function testNativeArrayListSupport(): void
$result = $this->connection->executeQuery(
'SELECT test_int FROM fetch_table WHERE test_int IN (?)',
[[100, 101, 102, 103, 104]],
[Connection::PARAM_INT_ARRAY],
[ArrayParameterType::INTEGER],
);

$data = $result->fetchAllNumeric();
Expand All @@ -316,7 +316,7 @@ public function testNativeArrayListSupport(): void
$result = $this->connection->executeQuery(
'SELECT test_int FROM fetch_table WHERE test_string IN (?)',
[['foo100', 'foo101', 'foo102', 'foo103', 'foo104']],
[Connection::PARAM_STR_ARRAY],
[ArrayParameterType::STRING],
);

$data = $result->fetchAllNumeric();
Expand Down
Loading