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 fetch* methods in QueryBuilder for SELECT queries #4461
Comments
Okay, now I see why it was originally brought up in #4280. While the idea of adding methods looks okay, I'm not really a fan of runtime assertions (the need for which in this case is a downside of the Apart from the transition from DBAL 2 to DBAL 3, does the addition of these (eight, I believe) new methods solve any other problem than being able to skip the call to |
Also it will help to know return types for executed queries. |
Adding those methods would avoid the following PHPStan error:
It was already reported (a while ago) in phpstan/phpstan#687. For now I workaround by ignoring those error in PHPStan, but I think the proper fix would be a more predictable API. The new methods would allow that. |
The PHPStan issue above is logged for the |
With <?php
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Query\QueryBuilder;
require 'vendor/autoload.php';
function test(Connection $connection, QueryBuilder $queryBuilder): void
{
// All of those calls are fine, with a clear and predictable API
$connection->fetchAllAssociative('SELECT 1');
$connection->fetchAllAssociativeIndexed('SELECT 1');
$connection->fetchAllKeyValue('SELECT 1');
$connection->fetchAllNumeric('SELECT 1');
$connection->fetchAssociative('SELECT 1');
$connection->fetchFirstColumn('SELECT 1');
$connection->fetchNumeric('SELECT 1');
$connection->fetchOne('SELECT 1');
$connection->executeStatement('UPDATE table SET value = 1');
// All of those calls are ambiguous and raise errors in PHPStan,
// because the API is unpredictable, because `execute()` support
// both queries and statements and so may return two different and incompatible types
$queryBuilder->execute()->fetchAllAssociative();
$queryBuilder->execute()->fetchAllAssociativeIndexed();
$queryBuilder->execute()->fetchAllKeyValue();
$queryBuilder->execute()->fetchAllNumeric();
$queryBuilder->execute()->fetchAssociative();
$queryBuilder->execute()->fetchFirstColumn();
$queryBuilder->execute()->fetchNumeric();
$queryBuilder->execute()->fetchOne();
// A queryBuilder containing an UPDATE would be fine
$queryBuilder->execute();
} We get the following PHPStan errors when running
So I think @andrew-demb suggestion to introduce new, predictable methods make sense. I would go as far as deprecating then removing // Exactly same method names as those in `Connection`, but without argument
$queryBuilder->fetchAllAssociative();
$queryBuilder->fetchAllAssociativeIndexed();
$queryBuilder->fetchAllKeyValue();
$queryBuilder->fetchAllNumeric();
$queryBuilder->fetchAssociative();
$queryBuilder->fetchFirstColumn();
$queryBuilder->fetchNumeric();
$queryBuilder->fetchOne();
$queryBuilder->executeStatement();
// Deprecated and then removed entirely
$queryBuilder->execute(); Also I don't think asserting that the queryBuilder contains a query (vs a statement) is strictly necessary. This assertion is not done in |
Agree.
Agree.
It's not necessary if proven by a test: we can do something like |
@PowerKiKi, #4489 doesn't contain the deprecation you proposed and is ready to be merged. If you want to get the old method deprecated, please file another PR. |
I'll create a new PR to deprecate |
…Statement()` This deprecates `QueryBuilder::execute()`, because its return type is unpredictable and raises issues with static analysis tools such as PHPStan. Instead you should use either `QueryBuilder::executeQuery()` or `QueryBuilder::executeStatement()`, depending if the queryBuilder is a query (SELECT) or a statement (INSERT, UPDATE, DELETE). You might also consider the use of the new shortcut methods, such as: - `fetchAllAssociative()` - `fetchAllAssociativeIndexed()` - `fetchAllKeyValue()` - `fetchAllNumeric()` - `fetchAssociative()` - `fetchFirstColumn()` - `fetchNumeric()` - `fetchOne()` This commit is a direct follow-up to doctrine#4461 where those shortcut methods where introduced.
…Statement()` This deprecates `QueryBuilder::execute()`, because its return type is unpredictable and raises issues with static analysis tools such as PHPStan. Instead you should use either `QueryBuilder::executeQuery()` or `QueryBuilder::executeStatement()`, depending on whether the queryBuilder is a query (SELECT) or a statement (INSERT, UPDATE, DELETE). You might also consider the use of the new shortcut methods, such as: - `fetchAllAssociative()` - `fetchAllAssociativeIndexed()` - `fetchAllKeyValue()` - `fetchAllNumeric()` - `fetchAssociative()` - `fetchFirstColumn()` - `fetchNumeric()` - `fetchOne()` This commit is a direct follow-up to doctrine#4461 where those shortcut methods where introduced.
I just created #4578 as a follow-up to this. |
…Statement()` This deprecates `QueryBuilder::execute()`, because its return type is unpredictable and raises issues with static analysis tools such as PHPStan. Instead you should use either `QueryBuilder::executeQuery()` or `QueryBuilder::executeStatement()`, depending on whether the queryBuilder is a query (SELECT) or a statement (INSERT, UPDATE, DELETE). You might also consider the use of the new shortcut methods, such as: - `fetchAllAssociative()` - `fetchAllAssociativeIndexed()` - `fetchAllKeyValue()` - `fetchAllNumeric()` - `fetchAssociative()` - `fetchFirstColumn()` - `fetchNumeric()` - `fetchOne()` This commit is a direct follow-up to doctrine#4461 where those shortcut methods where introduced.
…Statement()` This deprecates `QueryBuilder::execute()`, because its return type is unpredictable and raises issues with static analysis tools such as PHPStan. Instead you should use either `QueryBuilder::executeQuery()` or `QueryBuilder::executeStatement()`, depending on whether the queryBuilder is a query (SELECT) or a statement (INSERT, UPDATE, DELETE). You might also consider the use of the new shortcut methods, such as: - `fetchAllAssociative()` - `fetchAllAssociativeIndexed()` - `fetchAllKeyValue()` - `fetchAllNumeric()` - `fetchAssociative()` - `fetchFirstColumn()` - `fetchNumeric()` - `fetchOne()` This commit is a direct follow-up to doctrine#4461 where those shortcut methods where introduced.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Feature Request
Summary
Since DBAL deprecates concept of fetch mode in favor usage specific to every fetch mode Connection methods, there are no easy way to avoid deprecated staff with QueryBuilder usage.
As an alternative to deprecated API DBAL may provide new methods in QueryBuilder -
fetchAllAssociative()
and other, related to new fetch modes.Implementation for fetch associative method in QueryBuilder may looks like this:
The text was updated successfully, but these errors were encountered: