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

[DBAL-3079] Reworked the usage of PDO in PDOConnection from inheritance to composition #3080

Merged
merged 3 commits into from
Apr 13, 2018

Conversation

morozov
Copy link
Member

@morozov morozov commented Apr 2, 2018

Fixes #3079.

  1. PDOConnection no longer extends PDO.
  2. The PDO object can be obtained via PDOStatement::getWrappedConnection(). It's required to be able to call PDO-specific methods like setAttribute().
  3. As long as the signature of PDOStatement::query() doesn't have to be compatible with PDO::query(), it's updated to PDOStatement::query(string $sql) : ResultStatement. This is the primary goal of this pull request.
  4. Other query-related methods of Connection have been updated with typed arguments for consistency: prepare(), executeQuery(), executeUpdate(), exec(),
  5. Driver\Statement::rowCount() was updated with : int since it's invoked from some methods above.
  6. The tests wich invoked PDO methods on PDOStatement have been reworked to use PDOStatement::getWrappedConnection().
  7. DriverConnectionMock has been removed since it required an update but wasn't use anywhere.

*/
public function query();
public function query(string $sql);
Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't add the return type since the wrapper connection will have to declare that it returns a driver connection. This will likely change in the future.

Copy link
Member

Choose a reason for hiding this comment

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

@morozov I didn't understand this comment: if we change this in future, wouldn't it be better to let this become a loud BC break via a change of the signature?

}

/**
* {@inheritdoc}
*/
public function prepare($prepareString, $driverOptions = [])
public function prepare($prepareString)
Copy link
Member Author

Choose a reason for hiding this comment

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

No longer needed to follow the PDO signature. Will add to the changelog later.

*/
public function beginTransaction()
{
return $this->conn->beginTransaction();
Copy link
Member Author

Choose a reason for hiding this comment

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

Not wrapping this into a driver exception. Could be resolved in a different ticket.

@Ocramius Ocramius changed the title [DBAL-3079] Reworked the usage of PDO inPDOConnection from inheritance to composition [DBAL-3079] Reworked the usage of PDO in PDOConnection from inheritance to composition Apr 2, 2018
*/
public function query();
public function query(string $sql);
Copy link
Member

Choose a reason for hiding this comment

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

@morozov I didn't understand this comment: if we change this in future, wouldn't it be better to let this become a loud BC break via a change of the signature?

/**
* @var PDO
*/
private $conn;
Copy link
Member

Choose a reason for hiding this comment

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

Suggest renaming this to connection or even pdoConnection to avoid abbreviation and confusion overall

@morozov
Copy link
Member Author

morozov commented Apr 12, 2018

@Ocramius want to take a look again?

Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

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

Besides nits, this looks really good 👍

* @return \Doctrine\DBAL\Driver\Statement The executed statement.
* @param string $query The SQL query to execute.
* @param mixed[] $params The parameters to bind to the query, if any.
* @param mixed[] $types The types the previous parameters are in.
Copy link
Member

Choose a reason for hiding this comment

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

Types should be (int|string)[]

Copy link
Member Author

Choose a reason for hiding this comment

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

When iterating over (int|string)[], PhpStorm will recognize elements as mixed, but if it's int[]|string[] (not exactly correct), it will recognize them as int|string. This was previously brought up in #3025 (comment).

I'm still in favor of the proper annotation instead of making PhpStorm happy, especially if it's about scalar types (@Majkl578).

Copy link
Contributor

Choose a reason for hiding this comment

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

Please let's not introduce types like (int|string)[]. Although unfortunate, it doesn't work in PhpStorm, our CS and most of other tools either.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm I see you actually did the change... :/
I am strongly against and it should be reverted given the current state of PHP ecosystem.

Copy link
Member Author

Choose a reason for hiding this comment

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

We need to achieve some agreement before reverting it. The state of the PHP ecosystem is PHP 7.1 = ~37%. Yet, we don't support the older versions.

Copy link
Contributor

Choose a reason for hiding this comment

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

The state of PHP ecosystem is: PHPStan supports this, any other software doesn't.

* @param \Doctrine\DBAL\Cache\QueryCacheProfile $qcp The query cache profile.
* @param string $query The SQL query to execute.
* @param mixed[] $params The parameters to bind to the query, if any.
* @param mixed[] $types The types the previous parameters are in.
Copy link
Member

Choose a reason for hiding this comment

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

Types should be (int|string)[]

* raw PDOStatement instances.
* @param DriverStatement $stmt The statement to bind the values to.
* @param mixed[] $params The map/list of named/positional parameters.
* @param mixed[] $types The parameter types.
Copy link
Member

Choose a reason for hiding this comment

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

Types should be (int|string)[]

@@ -22,7 +22,7 @@ class Driver extends AbstractPostgreSQLDriver
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
{
try {
$pdo = new PDOConnection(
$conn = new PDOConnection(
Copy link
Member

Choose a reason for hiding this comment

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

Can we rename $conn here? Let's avoid abbreviations

@@ -36,7 +36,7 @@ public function connect(array $params, $username = null, $password = null, array
}

try {
$pdo = new PDOConnection(
$conn = new PDOConnection(
Copy link
Member

Choose a reason for hiding this comment

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

Same: can we avoid the abbreviation?

@@ -4,9 +4,11 @@

use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\ColumnCase;
use Doctrine\DBAL\Driver\PDOConnection;
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated to this patch, but do we still need the portability connection in 3.x?

Copy link
Member Author

Choose a reason for hiding this comment

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

What's wrong with it? The column case conversion is very helpful when dealing with Oracle and IBM DB2.

Copy link
Member Author

Choose a reason for hiding this comment

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

On the other hand, I agree that PORTABILITY_RTRIM is just a crutch for badly designed code which happens to work on MySQL. And as for PORTABILITY_EMPTY_TO_NULL — no idea what it could be used for.

@Majkl578 Majkl578 self-requested a review April 13, 2018 14:16
*
* @throws \Doctrine\DBAL\Cache\CacheException
* @throws DBALException
Copy link
Member Author

Choose a reason for hiding this comment

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

CacheException is a subclass of DBALException which can happen underneath. Therefore, replaced.

Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

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

:shipit:

@Ocramius Ocramius merged commit fe6bd76 into doctrine:develop Apr 13, 2018
@Ocramius
Copy link
Member

Thanks @morozov!

@stof
Copy link
Member

stof commented Apr 24, 2019

Could we have a way for DBAL's PDOStatement to expose the underlying PDOStatement ? PDO has a getColumnMeta method, which is useful to get info about the type of returned columns (I have a specific use case for that, where I have a controller running SQL queries stored in dedicated files and returning the data in CSV, and so the controller cannot assume the names of column headers as it changes depending on the query).

With DBAL 2.x, I can access this info thanks to the inheritance. But I don't see any way to achieve this in current state of 3.x now that composition is used. The PDOConnection allows accessing the wrapped connection, but the PDOStatement does not have the equivalent API.

@morozov
Copy link
Member Author

morozov commented Apr 24, 2019

@stof please file a separate ticket. For a use case like yours, it'd make sense to expose the underlying statement not only for PDO drivers.

@stof
Copy link
Member

stof commented Apr 29, 2019

@morozov here it is: #3534

@morozov morozov modified the milestones: 4.0.0, 3.0.0 Oct 3, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants